---
title: "MySQL in PostgreSQL umwandeln"
description: "Wandle einen MySQL- oder MariaDB-Dump in ein PostgreSQL-Skript um, das beim ersten Versuch lädt, mit Bericht über jede Änderung. Im Browser, ohne Upload."
canonical: https://intosql.com/de/mysql-in-postgresql
last_updated: 2026-10-15
---

# MySQL in PostgreSQL umwandeln

Leg einen Dump aus mysqldump, mariadb-dump, mysqlpump, phpMyAdmin oder Adminer ab, als .sql oder .sql.gz, und lade ein PostgreSQL-Skript mit denselben Tabellen, Schlüsseln, Indizes und Daten herunter. Jeder Wert, den PostgreSQL nicht unverändert aufnehmen kann, und jedes Objekt, das es nicht übernimmt, steht im Bericht.

## Was sich von MySQL zu PostgreSQL ändert

Jede Zeile ist eine Regel, die der Konverter anwendet, mit der Berichtszeile, die er schreibt, wenn die Regel etwas an deinen Daten ändert.

| In MySQL | In PostgreSQL | Berichtszeile |
| --- | --- | --- |
| TINYINT(1), BOOL | boolean, wenn jeder Wert 0 oder 1 ist, sonst smallint | `bool_kept_numeric` |
| UNSIGNED integers | der nächstgrößere Ganzzahltyp mit einem CHECK gegen negative Werte; BIGINT UNSIGNED wird bigint, wenn jeder Wert passt, sonst numeric(20,0) | `unsigned_widened` |
| ZEROFILL and display widths | entfernt | `zerofill_dropped` |
| FLOAT(M,D) | real oder double precision, ohne die Nachkommastellen | `float_scale_dropped` |
| BIT(1), BIT(n) | boolean, bit(n) |  |
| zero, partial or impossible dates (0000-00-00, 2024-02-30) | NULL | `invalid_date_null` |
| NOT NULL columns with values that become NULL | NOT NULL entfernt | `not_null_relaxed` |
| DEFAULT '0000-00-00' | kein Standardwert | `zero_date_default` |
| TIME | time, wenn jeder Wert innerhalb eines Tages liegt, sonst interval | `time_as_interval` |
| YEAR | smallint mit einem CHECK für den Wertebereich |  |
| CHAR(n) | varchar(n) |  |
| DATETIME | timestamp |  |
| TIMESTAMP | timestamptz in der Zeitzone, die der Dump angibt, UTC, wenn er keine angibt | `timestamp_zone_assumed` |
| ENUM | text mit einem CHECK der erlaubten Werte |  |
| ENUM holding '' (MySQL's error value) | der leere Wert, von der CHECK-Bedingung erlaubt | `enum_invalid_value` |
| ENUM or SET holding values outside its list | kein CHECK | `enum_check_skipped` |
| SET | text[] mit einem CHECK, dass jedes Element in der Liste steht |  |
| JSON | jsonb; json, wenn ein Wert \u0000 enthält | `json_not_jsonb` |
| NUL bytes in text | entfernt | `nul_removed` |
| text that isn't valid in its character set | die fehlerhaften Bytes als Ersatzzeichen | `invalid_utf8_replaced` |
| text decoded twice (Ã±) | unverändert kopiert | `mojibake_suspected` |
| AUTO_INCREMENT | GENERATED BY DEFAULT AS IDENTITY, mit dem Zähler hinter den kopierten IDs |  |
| MyISAM AUTO_INCREMENT on the second column of a key | ein Zähler für die Tabelle | `myisam_group_autoincrement` |
| ON UPDATE CURRENT_TIMESTAMP | ein Trigger mit BEFORE UPDATE | `on_update_trigger` |
| generated columns | STORED | `virtual_as_stored` |
| generated columns with functions PostgreSQL lacks | eine normale Spalte | `generated_not_translated` |
| INVISIBLE columns | normale Spalten | `invisible_column` |
| CHECK constraints | übersetzt, inline in CREATE TABLE |  |
| CHECK constraints with functions PostgreSQL lacks | nicht angelegt | `check_skipped` |
| CHECK ... NOT ENFORCED | nicht angelegt | `check_not_enforced` |
| defaults with functions PostgreSQL lacks | kein Standardwert | `default_not_translated` |
| keys and indexes on a prefix, c(20) | ein Index auf left(c, 20) | `prefix_unique` |
| FULLTEXT indexes | GIN auf to_tsvector('simple', ...) | `fulltext_as_gin` |
| indexes on values over 2,000 bytes | hash | `index_on_wide_values` |
| SPATIAL indexes | ohne PostGIS nicht angelegt | `spatial_index_skipped` |
| functional indexes PostgreSQL can't write | nicht angelegt | `index_skipped` |
| foreign keys | nach den Daten, NOT VALID, dann validiert, mit einer Warnung bei verwaisten Zeilen |  |
| foreign keys to columns without a unique key | nicht angelegt | `foreign_key_skipped` |
| table and column names | kleingeschrieben, wenn das eindeutig bleibt | `identifier_renamed` |
| names over 63 bytes | mit einem Hash gekürzt | `name_shortened` |
| GEOMETRY, POINT, POLYGON... | WKB in bytea | `geometry_as_wkb` |
| INET4, INET6, UUID (MariaDB) | inet, uuid |  |
| BINARY, VARBINARY, BLOB | bytea |  |
| PARTITION BY | eine Tabelle | `partitions_dropped` |
| WITH SYSTEM VERSIONING (MariaDB) | eine Tabelle mit den aktuellen Zeilen | `system_versioning_dropped` |
| MyISAM, MEMORY and other engines | eine normale Tabelle | `engine_dropped` |
| views, triggers, procedures, functions and events | im Bericht aufgeführt | `not_converted_objects` |
| dumps without CREATE TABLE | Typen aus den Werten gelesen | `no_schema` |
| geometries in a dump without CREATE TABLE | WKB in bytea | `geometry_inferred` |
| _ci collations | exakter Vergleich | `case_insensitive_collation` |
| SET NAMES utf8 from utf8mb4 tables | konvertiert, mit einer Warnung | `dump_lost_four_byte_chars` |
| dumps without SET NAMES whose text isn't UTF-8 | als Latin-1 (Windows-1252) gelesen | `charset_guessed` |
| sjis, cp932, gbk, big5 dumps | als UTF-8 gelesen, mit einer Warnung | `unsupported_charset` |
| UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows | ausgewertet |  |
| other expressions in rows | NULL | `expression_value` |
| DEFAULT in VALUES | der Standardwert der Spalte | `default_keyword_filled` |
| DEFAULT in VALUES without a literal default | NULL | `default_keyword_null` |
| REPLACE and INSERT IGNORE | normale Zeilen | `replace_as_insert` |
| types IntoSQL doesn't know | text | `unknown_type` |
| values that don't fit their column | NULL | `invalid_value_null` |
| unreadable geometries | NULL | `bad_geometry` |
| CREATE SEQUENCE (MariaDB) | CREATE SEQUENCE mit ihrem aktuellen Wert |  |

## Das Skript in PostgreSQL laden

Das Skript legt die Tabellen an, kopiert die Zeilen und fügt dann Schlüssel, Indizes und Fremdschlüssel hinzu, so lädt es schnell und hält beim ersten Fehler an.

```shell
psql -v ON_ERROR_STOP=1 -d mydb -f mysql.postgresql.sql
```

Fremdschlüssel werden als NOT VALID hinzugefügt und dann validiert. Verweist eine Zeile auf eine Zeile, die es nicht gibt, nennt dir das Skript den betroffenen Fremdschlüssel, statt auf halbem Weg abzubrechen.

Lege bei einem großen Dump zuerst die Datenbank an und führe das Skript mit psql auf dem Rechner aus, auf dem der Server läuft.

## Den MySQL-Dump für das beste Ergebnis erstellen

Der Konverter liest, was der Dump enthält. Mit diesen Optionen bleibt mehr von deinen Daten darin:

- --default-character-set=utf8mb4 bewahrt Emoji und andere 4-Byte-Zeichen, die ein utf8-Dump verliert, bevor der Konverter ihn sieht.
- --hex-blob schreibt Binärspalten hexadezimal, was das Kopieren zwischen Systemen übersteht.
- --routines --triggers --events fügen diese Objekte dem Dump hinzu, damit der Bericht sie auflisten kann.

## Was nicht konvertiert wird

Sichten, Trigger, gespeicherte Prozeduren, Funktionen und Ereignisse sind in der eigenen Sprache jeder Datenbank geschrieben. Sie stehen mit Namen im Bericht und werden nie stillschweigend weggelassen, damit du sie für PostgreSQL neu schreiben kannst.

## Im Vergleich mit pgloader gemessen

Dieselben Dumps, konvertiert und geladen von IntoSQL und von pgloader 3.6.7 auf einem Rechner (ein i9-10900K mit 10 Kernen und einer SATA SSD), im Oktober 2026.

- Eine TINYINT(1)-Spalte mit 2, -1 und -5: pgloader lädt für jeden Wert true, ohne Warnung. IntoSQL behält die Zahlen, und der Bericht sagt warum.
- Ein Dump mit dem Standardwert 'it's', einer Tabelle mit einem Backtick im Namen, einem ENUM mit dem leeren Wert und einer TIME über 24 Stunden: pgloader bricht ab. IntoSQL konvertiert und lädt ihn.
- Was pgloader lädt, hat seine Primärschlüssel, eindeutigen Schlüssel, Fremdschlüssel und Identity-Spalten verloren. IntoSQL behält sie alle.
- Ein Dump von 5.3 GB mit 30 Millionen Zeilen: pgloader braucht ihn zuerst in einem laufenden MySQL wiederhergestellt, was 18 Minuten dauert, und dann geht ihm mit den Standardeinstellungen der Speicher aus. IntoSQL konvertiert den Dump in 10 Sekunden, und psql lädt das Skript in etwa 3 Minuten.
- Über 476 Dumps aus MySQL 5.5 bis 9 und MariaDB 10.3 bis 12, geladen in PostgreSQL 13 und 18: keine Ladefehler und kein geänderter Wert ohne eine Zeile im Bericht.

## Fragen zu MySQL zu PostgreSQL

### Wird mein Dump hochgeladen?

Nein. Der Konverter läuft in deinem Browser und liest den Dump stückweise von deiner Festplatte, daher verlässt er nie deinen Computer. Die Desktop-App und die Kommandozeile konvertieren ebenfalls auf deinem Computer.

### Wie groß darf der Dump sein?

Der Konverter hält nie den ganzen Dump im Speicher: Er liest die Datei zweimal, in Abschnitten, und schreibt das Skript fortlaufend. Dumps von mehreren Gigabyte werden im Browser, in der Desktop-App und mit der Kommandozeile konvertiert.

### Liest es MariaDB-Dumps?

Ja. Dumps aus mariadb-dump und aus MariaDB 10.3 bis 12 werden genauso konvertiert, einschließlich der INET6-, INET4- und UUID-Spalten von MariaDB.

### Was passiert mit dem Datum 0000-00-00?

PostgreSQL kennt kein Null-Datum, daher werden diese Werte NULL, und die Spalte akzeptiert NULL. Der Bericht nennt, wie viele es in jeder Spalte waren.

### Bleiben AUTO_INCREMENT-Werte erhalten?

Ja. Jede AUTO_INCREMENT-Spalte wird eine Identity-Spalte, jede Zeile behält ihre ID, und die nächste ID macht nach der höchsten weiter oder nach dem AUTO_INCREMENT der Tabelle, wenn das höher ist.

### Wird TINYINT(1) zu boolean?

Nur wenn jeder Wert der Spalte 0 oder 1 ist. Enthält sie andere Zahlen wie 2 oder -1, bleibt sie eine Zahl, und der Bericht sagt warum, damit kein Wert versehentlich zu true wird.

### Was ist mit gespeicherten Prozeduren und Triggern?

Sie stehen mit Namen im Bericht und werden nicht konvertiert, weil jede Datenbank sie in ihrer eigenen Sprache schreibt. ON UPDATE CURRENT_TIMESTAMP ist die Ausnahme: Es wird ein PostgreSQL-Trigger.

### Auf welchen PostgreSQL-Versionen lädt das Skript?

PostgreSQL 13 bis 18. Dasselbe Skript lädt auf jeder davon und hält beim ersten Fehler an, falls etwas schiefgeht.

## Weitere Konvertierungen in PostgreSQL

- [Excel in PostgreSQL umwandeln](https://intosql.com/de/excel-in-postgresql)
- [CSV in PostgreSQL umwandeln](https://intosql.com/de/csv-in-postgresql)
- [JSON in PostgreSQL umwandeln](https://intosql.com/de/json-in-postgresql)
