Een database omzetten naar een andere database
Sleep een dump van mysqldump, mariadb-dump, pg_dump, SSMS, SQL Developer of SQLcl, of een SQLite .db-bestand hierheen en download één script voor PostgreSQL, MySQL, MariaDB, SQLite, SQL Server of Oracle met dezelfde tabellen, sleutels, indexen en data. Elke wijziging staat in een rapport, en de dump verlaat je computer nooit.
18 rijen geconverteerd, 8 correcties, geen afgewezen
Tabellen in shop_2024.sqlMySQL 8.0.46-dump · geschreven door mysqldump · utf8mb4
customers8 rijen3
7 kolommen id bigint not null name varchar(100) not null email varchar(150) not null country varchar(2) not null is_active boolean not null signed_up date created_at timestamptz(0) not null orders10 rijen5
9 kolommen id bigint not null customer_id bigint not null status text not null total numeric(10,2) not null items integer not null ordered_at timestamp(0) not null shipped_at timestamp(0) note varchar(255) updated_at timestamptz(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();
Correcties
- "id" van customers is unsigned, dus het is bigint geworden met een check dat het niet negatief is.
- "signed_up" van customers staat nu NULL toe: sommige waarden konden niet worden opgeslagen en zijn NULL.
- De standaardwaarde van "signed_up" in customers, 0000‑00‑00, is geen datum die PostgreSQL accepteert, dus de kolom heeft geen standaardwaarde.
- "customer_id" van orders is unsigned, dus het is bigint geworden met een check dat het niet negatief is.
- "id" van orders is unsigned, dus het is bigint geworden met een check dat het niet negatief is.
- "items" van orders is unsigned, dus het is integer geworden met een check dat het niet negatief is.
- 1 rij van "status" in orders bevat de lege waarde die MySQL opslaat voor ongeldige invoer; de check op de waarden staat die toe.
- "updated_at" van orders verandert bij elke update in de huidige tijd; in PostgreSQL doet een trigger dat.
Na te kijken
- 1 waarde in "signed_up" van customers is een nul- of onmogelijke datum zoals 0000‑00‑00, die PostgreSQL niet kan opslaan, dus die is NULL. Als die datums iets betekenen, vervang ze dan in de bron door echte datums voordat je de dump maakt.
- 1 waarde in "shipped_at" van orders is een nul- of onmogelijke datum zoals 0000‑00‑00 00:00:00, die PostgreSQL niet kan opslaan, dus die is NULL. Als die datums iets betekenen, vervang ze dan in de bron door echte datums voordat je de dump maakt.
Je bestand wordt op deze computer omgezet en nooit geüpload.
Andere voorbeelden:
Elke databasecombinatie
Rijen zijn de database waar de dump vandaan komt, kolommen de database waarvoor het script is. Elke combinatie heeft een eigen pagina met de converter daarvoor ingesteld, de regels die hij toepast en hoe je het script laadt.
- MySQL
- MariaDB
- PostgreSQL
- SQL Server
- SQLite
- Oracle
| van ↓ naar → | PostgreSQL | MySQL | MariaDB | SQLite | SQL Server | Oracle |
|---|---|---|---|---|---|---|
| MySQL | MySQL naar PostgreSQL | MySQL naar MySQL | MySQL naar MariaDB | MySQL naar SQLite | MySQL naar SQL Server | MySQL naar Oracle |
| MariaDB | MariaDB naar PostgreSQL | MariaDB naar MySQL | MariaDB naar MariaDB | MariaDB naar SQLite | MariaDB naar SQL Server | MariaDB naar Oracle |
| PostgreSQL | PostgreSQL naar PostgreSQL | PostgreSQL naar MySQL | PostgreSQL naar MariaDB | PostgreSQL naar SQLite | PostgreSQL naar SQL Server | PostgreSQL naar Oracle |
| SQL Server | SQL Server naar PostgreSQL | SQL Server naar MySQL | SQL Server naar MariaDB | SQL Server naar SQLite | SQL Server naar SQL Server | SQL Server naar Oracle |
| SQLite | SQLite naar PostgreSQL | SQLite naar MySQL | SQLite naar MariaDB | SQLite naar SQLite | SQLite naar SQL Server | SQLite naar Oracle |
| Oracle | Oracle naar PostgreSQL | Oracle naar MySQL | Oracle naar MariaDB | Oracle naar SQLite | Oracle naar SQL Server | Oracle naar Oracle |
Wat behouden blijft en wat gemeld wordt
De converter leest de dump zelf, zonder databaseserver, en schrijft het script op basis van wat erin staat. De pagina van elke combinatie somt de regels op die hij toepast, tussen 25 en 67 per combinatie, met de rapportregel die elke regel schrijft.
Behouden in het script
- Tabellen en kolommen, elk met het dichtstbijzijnde type dat het doel heeft en de lengte en precisie ervan.
- Primaire, unieke en refererende sleutels, indexen en standaardwaarden.
- AUTO_INCREMENT-, identity- en serial-kolommen, met het id van elke rij en de teller die verdergaat waar de dump hem liet.
- Elke rij, met datums, decimalen, tekst en binaire waarden zoals de dump ze bevat.
Vermeld in het rapport
- Waarden die het doel niet ongewijzigd kan bevatten, zoals een datum 0000-00-00 in PostgreSQL, met de kolom en hoeveel.
invalid_date_null - Typen die het doel niet heeft, zoals ENUM of INET6, met het type dat elk werd.
type_replaced - Weergaven, triggers, procedures, functies en events, op naam: ze zijn geschreven in de eigen taal van elke database, dus ze worden niet geconverteerd.
not_converted_objects - Tekst die niet geldig is in zijn tekenset, en dumps die hun 4-bytestekens al kwijt zijn.
invalid_utf8_replaced
Gemeten tegen pgloader
Dezelfde dumps, geconverteerd en geladen door IntoSQL en door pgloader 3.6.7 op één machine (een i9-10900K met 10 cores en een SATA SSD), in oktober 2026.
- Een TINYINT(1)-kolom met 2, -1 en -5: pgloader laadt voor elk ervan true, zonder waarschuwing. IntoSQL behoudt de getallen en het rapport legt uit waarom.
- Een dump met een standaardwaarde 'it's', een tabel met een backtick in de naam, een ENUM met de lege waarde en een TIME van meer dan 24 uur: pgloader stopt. IntoSQL converteert en laadt hem.
- Wat pgloader laadt, is zijn primaire, unieke en refererende sleutels en zijn identities kwijt. IntoSQL behoudt ze allemaal.
- Een dump van 5.3 GB met 30 miljoen rijen: pgloader moet hem eerst terugzetten in een draaiende MySQL, wat 18 minuten duurt, en heeft daarna met de standaardinstellingen te weinig geheugen. IntoSQL converteert de dump in 10 seconden, en psql laadt het script in ongeveer 3 minuten.
- Over 476 dumps van MySQL 5.5 tot en met 9 en MariaDB 10.3 tot en met 12, geladen in PostgreSQL 13 en 18: geen laadfouten, en geen waarde veranderd zonder een regel in het rapport.
De database exporteren die je hebt
De converter leest een bestand, geen draaiende server. Elke database schrijft er een met zijn eigen tools:
MySQL
Een dump van mysqldump, mysqlpump, phpMyAdmin of Adminer, als .sql of .sql.gz. Met --default-character-set=utf8mb4 --hex-blob --routines --triggers --events blijft het meeste behouden.
Migratiehandleiding MySQL naar PostgreSQLMariaDB
Een dump van mariadb-dump, mysqldump, phpMyAdmin of Adminer, als .sql of .sql.gz, met dezelfde opties als MySQL.
Migratiehandleiding MariaDB naar PostgreSQLPostgreSQL
Een gewone dump van pg_dump of pg_dumpall. Een custom-archief (-Fc) wordt er een met pg_restore -f dump.sql, zonder server.
Migratiehandleiding PostgreSQL naar MySQLSQL Server
Het script dat Generate Scripts van SSMS schrijft, met Types of data to script op Schema and data. dbatools en mssql-scripter schrijven hetzelfde.
Migratiehandleiding SQL Server naar PostgreSQLSQLite
Het databasebestand zelf (.db, .sqlite, .sqlite3), of de SQL die sqlite3 app.db .dump schrijft.
Migratiehandleiding SQLite naar PostgreSQLOracle
Het .sql-bestand dat Database Export van SQL Developer of SQLcl schrijft, met DDL en Insert-statements. Een .dmp-bestand van exp of expdp moet eerst opnieuw worden geïmporteerd en geëxporteerd.
Migratiehandleiding Oracle naar PostgreSQL
Vragen over databasemigratie
Staat je vraag er niet bij? Schrijf ons via de contactpagina en een mens antwoordt. Contactpagina
Wordt mijn dump geüpload?
Nee. De converter draait in je browser en leest de dump in delen van je schijf, dus hij verlaat je computer nooit. De desktopapp en de opdrachtregel converteren ook op je computer.
Hoe groot mag de dump zijn?
De converter houdt nooit de hele dump in het geheugen: hij leest het bestand twee keer, in bereiken, en schrijft het script gaandeweg. Dumps van meerdere gigabytes worden geconverteerd in de browser, in de desktopapp en met de opdrachtregel.
Van welke versies kan de dump komen?
MySQL 5.5 tot en met 9, MariaDB 10.3 tot en met 12, PostgreSQL 10 en later, SQL Server 2017 en later, SQLite 3.0 en later, en Oracle 11g en later. De pagina van elke combinatie zegt op welke versies het script laadt.
Heb ik een draaiende databaseserver nodig?
Nee. De converter leest het dumpbestand zelf, dus de brondatabase hoeft nergens te draaien. Het script laadt met de eigen client van het doel, zoals psql, mysql of sqlcmd.
Wat wordt niet geconverteerd?
Weergaven, triggers, opgeslagen procedures, functies en events zijn geschreven in de eigen taal van elke database, dus ze staan in plaats daarvan op naam in het rapport. De tabellen, sleutels, indexen en rijen staan allemaal in het script.
Kan het het script rechtstreeks in mijn database laden?
De desktopapp en het commando intosql load schrijven gratis rechtstreeks in SQLite, en met IntoSQL Pro in PostgreSQL, MySQL en MariaDB. Voer het script voor SQL Server en Oracle uit met sqlcmd of sqlplus.