Zum Inhalt springen
IntoSQL-Startseite

Eine Datenbank in eine andere Datenbank umwandeln

Zieh einen Dump aus mysqldump, mariadb-dump, pg_dump, SSMS, SQL Developer oder SQLcl oder eine SQLite-.db-Datei hierher und lade ein Skript für PostgreSQL, MySQL, MariaDB, SQLite, SQL Server oder Oracle herunter, mit denselben Tabellen, Schlüsseln, Indizes und Daten. Jede Änderung steht in einem Bericht, und der Dump verlässt nie deinen Computer.

Deine Datei
sqlshop_2024.sqlBeispieldatei, 5,1 kB
Deine Datenbank

18 Zeilen konvertiert, 8 Korrekturen, keine abgelehnt

Anzeigen

Tabellen in shop_2024.sqlMySQL-8.0.46-Dump · erstellt mit mysqldump · utf8mb4

  • customers8 Zeilen3
    7 Spalten
    idbigint not null
    namevarchar(100) not null
    emailvarchar(150) not null
    countryvarchar(2) not null
    is_activeboolean not null
    signed_update
    created_attimestamptz(0) not null
  • orders10 Zeilen5
    9 Spalten
    idbigint not null
    customer_idbigint not null
    statustext not null
    totalnumeric(10,2) not null
    itemsinteger not null
    ordered_attimestamp(0) not null
    shipped_attimestamp(0)
    notevarchar(255)
    updated_attimestamptz(0) not null
-- Written by IntoSQL from a MySQL dump. Load it with: psql -v ON_ERROR_STOP=1 -f <file>
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET synchronous_commit = off;
SET maintenance_work_mem = '512MB';

CREATE TABLE customers (
    id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
    name varchar(100) NOT NULL,
    email varchar(150) NOT NULL,
    country varchar(2) DEFAULT 'US' NOT NULL,
    is_active boolean DEFAULT true NOT NULL,
    signed_up date,
    created_at timestamptz(0) DEFAULT CURRENT_TIMESTAMP NOT NULL,
    CONSTRAINT customers_id_check CHECK (id >= 0)
);

CREATE TABLE orders (
    id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
    customer_id bigint NOT NULL,
    status text DEFAULT 'pending' NOT NULL,
    total numeric(10,2) NOT NULL,
    items integer DEFAULT 1 NOT NULL,
    ordered_at timestamp(0) NOT NULL,
    shipped_at timestamp(0),
    note varchar(255),
    updated_at timestamptz(0) DEFAULT CURRENT_TIMESTAMP NOT NULL,
    CONSTRAINT orders_id_check CHECK (id >= 0),
    CONSTRAINT orders_customer_id_check CHECK (customer_id >= 0),
    CONSTRAINT orders_status_check CHECK (status IN ('pending', 'paid', 'shipped', 'cancelled', '')),
    CONSTRAINT orders_items_check CHECK (items >= 0)
);

COPY customers (id, name, email, country, is_active, signed_up, created_at) FROM stdin;
1	Ana Martínez	ana@example.com	MX	t	2023-01-15	2023-01-15 10:24:00+00:00
2	Zoë Müller	zoe@example.de	DE	t	2023-02-03	2023-02-03 08:11:42+00:00
3	José Peña	jose@example.es	ES	f	2023-03-21	2023-03-21 19:05:17+00:00
4	李雷	lilei@example.cn	CN	t	2023-05-09	2023-05-09 02:40:00+00:00
5	Noah O'Brien	noah@example.ie	IE	t	\N	2023-06-30 14:00:00+00:00
6	Amélie Laurent	amelie@example.fr	FR	t	2024-01-02	2024-01-02 09:30:00+00:00
7	Ravi Patel	ravi@example.in	IN	f	2024-02-29	2024-02-29 23:59:59+00:00
8	Sofia Rossi 🌻	sofia@example.it	IT	t	2024-04-12	2024-04-12 12:12:12+00:00
\.

COPY orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, updated_at) FROM stdin;
1	1	shipped	129.90	3	2024-03-01 10:00:00	2024-03-02 16:30:00	\N	2024-03-02 16:30:00+00:00
2	2	paid	54.00	1	2024-03-02 11:15:00	\N	Gift wrap 🎁	2024-03-02 11:20:00+00:00
3	1	cancelled	12.50	1	2024-03-03 09:45:00	\N	Customer changed their mind	2024-03-03 10:00:00+00:00
4	4	shipped	980.00	12	2024-03-05 02:10:00	2024-03-07 08:00:00	请小心轻放	2024-03-07 08:00:00+00:00
5	5	pending	45.75	2	2024-03-08 17:20:00	\N	Leave at the door; ring twice	2024-03-08 17:20:00+00:00
6	6	shipped	310.40	5	2024-03-10 13:00:00	2024-03-11 09:00:00	Fragile: "glass"	2024-03-11 09:00:00+00:00
7	8	paid	76.20	2	2024-03-11 18:45:00	\N	\N	2024-03-11 18:46:00+00:00
8	2		19.99	1	2024-03-12 08:00:00	\N	Status lost in an old import	2024-03-12 08:00:00+00:00
9	3	shipped	64.00	2	2024-03-14 15:30:00	\N	Shipping date never recorded	2024-03-15 10:00:00+00:00
10	7	paid	1499.00	1	2024-03-15 21:05:00	\N	C:\\Users\\ravi\\invoice.pdf	2024-03-15 21:05:00+00:00
\.


-- Keys, indexes and constraints, after the rows so each builds once.
CREATE UNIQUE INDEX customers_pkey ON customers (id);
CREATE UNIQUE INDEX customers_uq_email ON customers (email);
CREATE UNIQUE INDEX orders_pkey ON orders (id);
CREATE INDEX orders_idx_customer ON orders (customer_id);
CREATE INDEX orders_idx_status_date ON orders (status, ordered_at);
ALTER TABLE customers ADD CONSTRAINT customers_pkey PRIMARY KEY USING INDEX customers_pkey;
ALTER TABLE customers ADD CONSTRAINT customers_uq_email UNIQUE USING INDEX customers_uq_email;
ALTER TABLE orders ADD CONSTRAINT orders_pkey PRIMARY KEY USING INDEX orders_pkey;
ALTER TABLE orders ADD CONSTRAINT fk_orders_customer FOREIGN KEY (customer_id) REFERENCES customers (id) NOT VALID;
DO $f$ BEGIN
    ALTER TABLE orders VALIDATE CONSTRAINT fk_orders_customer;
EXCEPTION WHEN foreign_key_violation THEN
    RAISE WARNING 'foreign key % has rows without a parent: it stays NOT VALID, and new rows are checked', 'fk_orders_customer';
END $f$;
SELECT setval(pg_get_serial_sequence('customers', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM customers)::numeric, 0) + 1, 1001), 9223372036854775807)::bigint, false);
COMMENT ON TABLE customers IS 'People who bought at least once';
SELECT setval(pg_get_serial_sequence('orders', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM orders)::numeric, 0) + 1, 5001), 9223372036854775807)::bigint, false);
CREATE FUNCTION orders_updated_at_on_update() RETURNS trigger LANGUAGE plpgsql AS $f$
BEGIN
    IF NEW IS DISTINCT FROM OLD AND NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at THEN
        NEW.updated_at := CURRENT_TIMESTAMP;
    END IF;
    RETURN NEW;
END
$f$;
CREATE TRIGGER orders_updated_at_on_update BEFORE UPDATE ON orders FOR EACH ROW EXECUTE FUNCTION orders_updated_at_on_update();

Korrekturen

  1. "id" von customers ist vorzeichenlos und wurde deshalb bigint mit einer CHECK-Bedingung gegen negative Werte.
  2. "signed_up" von customers erlaubt jetzt NULL: Einige Werte ließen sich nicht speichern und sind NULL.
  3. Der Standardwert von "signed_up" in customers, 0000‑00‑00, ist kein Datum, das PostgreSQL akzeptiert, daher hat die Spalte keinen Standardwert.
  4. "customer_id" von orders ist vorzeichenlos und wurde deshalb bigint mit einer CHECK-Bedingung gegen negative Werte.
  5. "id" von orders ist vorzeichenlos und wurde deshalb bigint mit einer CHECK-Bedingung gegen negative Werte.
  6. "items" von orders ist vorzeichenlos und wurde deshalb integer mit einer CHECK-Bedingung gegen negative Werte.
  7. 1 Zeile von "status" in orders enthält den leeren Wert, den MySQL für ungültige Einträge speichert; die CHECK-Bedingung der Spalte erlaubt ihn.
  8. "updated_at" von orders wird bei jeder Änderung auf die aktuelle Zeit gesetzt; in PostgreSQL übernimmt das ein Trigger.

Zu prüfen

  • 1 Wert in "signed_up" von customers ist ein Null- oder unmögliches Datum wie 0000‑00‑00, was PostgreSQL nicht speichern kann, daher ist er NULL. Wenn diese Datumsangaben etwas bedeuten, ersetze sie vor dem Dump in der Quelle durch echte.
  • 1 Wert in "shipped_at" von orders ist ein Null- oder unmögliches Datum wie 0000‑00‑00 00:00:00, was PostgreSQL nicht speichern kann, daher ist er NULL. Wenn diese Datumsangaben etwas bedeuten, ersetze sie vor dem Dump in der Quelle durch echte.

Deine Datei wird auf diesem Computer umgewandelt und nie hochgeladen.

Weitere Beispiele:

Alle Datenbankpaare

Die Zeilen sind die Datenbank, aus der der Dump stammt, die Spalten die Datenbank, für die das Skript ist. Jedes Paar hat eine eigene Seite mit dem dafür eingerichteten Konverter, den Regeln, die er anwendet, und wie das Skript geladen wird.

Datentypen für jedes Paar

Was erhalten bleibt und was gemeldet wird

Der Konverter liest den Dump selbst, ohne Datenbankserver, und schreibt das Skript aus dem, was er enthält. Die Seite jedes Paares listet die Regeln, die es anwendet, zwischen 25 und 67 pro Paar, mit der Berichtszeile, die jede schreibt.

Im Skript erhalten

  • Tabellen und Spalten, jeweils mit dem nächstliegenden Typ des Ziels samt Länge und Genauigkeit.
  • Primär-, Unique- und Fremdschlüssel, Indizes und Standardwerte.
  • AUTO_INCREMENT-, Identity- und Serial-Spalten, mit der ID jeder Zeile und dem Zähler, der dort weiterläuft, wo der Dump ihn gelassen hat.
  • Jede Zeile, mit Datumswerten, Dezimalzahlen, Text und Binärwerten so, wie der Dump sie enthält.

Im Bericht aufgeführt

  • Werte, die das Ziel so nicht speichern kann, etwa ein Datum 0000-00-00 in PostgreSQL, mit der Spalte und der Anzahl.invalid_date_null
  • Typen, die das Ziel nicht hat, etwa ENUM oder INET6, mit dem Typ, der jeweils daraus wurde.type_replaced
  • Views, Trigger, Prozeduren, Funktionen und Events, mit Namen: Sie sind in der eigenen Sprache jeder Datenbank geschrieben und werden daher nicht konvertiert.not_converted_objects
  • Text, der in seinem Zeichensatz ungültig ist, und Dumps, die ihre 4-Byte-Zeichen schon verloren haben.invalid_utf8_replaced

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.
Die Seite MySQL zu PostgreSQL

Die vorhandene Datenbank exportieren

Der Konverter liest eine Datei, keinen laufenden Server. Jede Datenbank schreibt eine mit ihren eigenen Werkzeugen:

Fragen zur Datenbankmigration

Keine Antwort gefunden? Schreib uns über die Kontaktseite, und ein Mensch antwortet. Kontaktseite

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.

Aus welchen Versionen kann der Dump stammen?

MySQL 5.5 bis 9, MariaDB 10.3 bis 12, PostgreSQL ab 10, SQL Server ab 2017, SQLite ab 3.0 und Oracle ab 11g. Die Seite jedes Paares nennt die Versionen, auf denen sein Skript lädt.

Brauche ich einen laufenden Datenbankserver?

Nein. Der Konverter liest die Dump-Datei selbst, die Quelldatenbank muss also nirgends laufen. Das Skript lädt mit dem eigenen Client des Ziels, etwa psql, mysql oder sqlcmd.

Was wird nicht konvertiert?

Views, Trigger, Stored Procedures, Funktionen und Events sind in der eigenen Sprache jeder Datenbank geschrieben und stehen daher mit Namen im Bericht. Tabellen, Schlüssel, Indizes und Zeilen sind alle im Skript.

Kann es das Skript direkt in meine Datenbank laden?

Die Desktop-App und der Befehl intosql load schreiben kostenlos direkt in SQLite und mit IntoSQL Pro in PostgreSQL, MySQL und MariaDB. Für SQL Server und Oracle führst du das Skript mit sqlcmd oder sqlplus aus.