Converti un database in un altro database
Trascina un dump di mysqldump, mariadb-dump, pg_dump, SSMS, SQL Developer o SQLcl, o un file .db di SQLite, e scarica uno script per PostgreSQL, MySQL, MariaDB, SQLite, SQL Server o Oracle con le stesse tabelle, chiavi, indici e dati. Ogni modifica è elencata in un report, e il dump non lascia mai il tuo computer.
18 righe convertite, 8 correzioni, nessuna rifiutata
Tabelle in shop_2024.sqlDump MySQL 8.0.46 · scritto da mysqldump · utf8mb4
customers8 righe3
7 colonne 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 righe5
9 colonne 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();
Correzioni
- "id" di customers è senza segno, quindi è diventata bigint con un vincolo CHECK che non sia negativa.
- "signed_up" di customers ora ammette NULL: alcuni dei suoi valori non si potevano salvare e sono NULL.
- Il valore predefinito di "signed_up" in customers, 0000‑00‑00, non è una data che PostgreSQL accetta, quindi la colonna non ha un valore predefinito.
- "customer_id" di orders è senza segno, quindi è diventata bigint con un vincolo CHECK che non sia negativa.
- "id" di orders è senza segno, quindi è diventata bigint con un vincolo CHECK che non sia negativa.
- "items" di orders è senza segno, quindi è diventata integer con un vincolo CHECK che non sia negativa.
- 1 riga di "status" in orders contiene il valore vuoto che MySQL salva per le voci non valide; il vincolo CHECK sui suoi valori lo ammette.
- "updated_at" di orders passa all'ora corrente a ogni aggiornamento; in PostgreSQL lo fa un trigger.
Da controllare
- 1 valore in "signed_up" di customers è una data zero o impossibile come 0000‑00‑00, che PostgreSQL non può salvare, quindi è NULL. Se quelle date hanno un significato, sostituiscile nell'origine con date reali prima del dump.
- 1 valore in "shipped_at" di orders è una data zero o impossibile come 0000‑00‑00 00:00:00, che PostgreSQL non può salvare, quindi è NULL. Se quelle date hanno un significato, sostituiscile nell'origine con date reali prima del dump.
Il tuo file viene convertito su questo computer e non viene mai caricato.
Altri esempi:
Tutte le coppie di database
Le righe sono il database da cui viene il dump, le colonne il database per cui è lo script. Ogni coppia ha la sua pagina con il convertitore impostato per essa, le regole che applica e come caricare lo script.
- MySQL
- MariaDB
- PostgreSQL
- SQL Server
- SQLite
- Oracle
| da ↓ a → | PostgreSQL | MySQL | MariaDB | SQLite | SQL Server | Oracle |
|---|---|---|---|---|---|---|
| MySQL | MySQL in PostgreSQL | MySQL in MySQL | MySQL in MariaDB | MySQL in SQLite | MySQL in SQL Server | MySQL in Oracle |
| MariaDB | MariaDB in PostgreSQL | MariaDB in MySQL | MariaDB in MariaDB | MariaDB in SQLite | MariaDB in SQL Server | MariaDB in Oracle |
| PostgreSQL | PostgreSQL in PostgreSQL | PostgreSQL in MySQL | PostgreSQL in MariaDB | PostgreSQL in SQLite | PostgreSQL in SQL Server | PostgreSQL in Oracle |
| SQL Server | SQL Server in PostgreSQL | SQL Server in MySQL | SQL Server in MariaDB | SQL Server in SQLite | SQL Server in SQL Server | SQL Server in Oracle |
| SQLite | SQLite in PostgreSQL | SQLite in MySQL | SQLite in MariaDB | SQLite in SQLite | SQLite in SQL Server | SQLite in Oracle |
| Oracle | Oracle in PostgreSQL | Oracle in MySQL | Oracle in MariaDB | Oracle in SQLite | Oracle in SQL Server | Oracle in Oracle |
Cosa viene conservato e cosa viene segnalato
Il convertitore legge direttamente il dump, senza un server di database, e scrive lo script da ciò che contiene. La pagina di ogni coppia elenca le regole che applica, tra 25 e 67 per coppia, con la riga di report che scrive ognuna.
Conservato nello script
- Tabelle e colonne, ognuna con il tipo più vicino che ha la destinazione, con lunghezza e precisione.
- Chiavi primarie, uniche ed esterne, indici e valori predefiniti.
- Colonne AUTO_INCREMENT, identity e serial, con l'id di ogni riga e il contatore che riparte da dove lo ha lasciato il dump.
- Ogni riga, con date, decimali, testo e valori binari come li contiene il dump.
Elencato nel report
- Valori che la destinazione non può contenere così come sono, come una data 0000-00-00 in PostgreSQL, con la colonna e quanti sono.
invalid_date_null - Tipi che la destinazione non ha, come ENUM o INET6, con il tipo in cui è diventato ognuno.
type_replaced - Viste, trigger, procedure, funzioni ed eventi, per nome: sono scritti nel linguaggio di ciascun database, quindi non vengono convertiti.
not_converted_objects - Testo non valido nel suo set di caratteri, e dump che hanno già perso i caratteri a 4 byte.
invalid_utf8_replaced
Confronto misurato con pgloader
Gli stessi dump, convertiti e caricati da IntoSQL e da pgloader 3.6.7 sulla stessa macchina (un i9-10900K a 10 core con un SATA SSD), a ottobre 2026.
- Una colonna TINYINT(1) che contiene 2, -1 e -5: pgloader carica true per ciascuno, senza un avviso. IntoSQL mantiene i numeri e il report spiega perché.
- Un dump con un valore predefinito 'it's', una tabella con un backtick nel nome, un ENUM che contiene il valore vuoto e un TIME oltre le 24 ore: pgloader si ferma. IntoSQL lo converte e lo carica.
- Ciò che pgloader carica ha perso le chiavi primarie, univoche ed esterne e le identity. IntoSQL le mantiene tutte.
- Un dump di 5.3 GB con 30 milioni di righe: pgloader richiede prima di ripristinarlo in un MySQL in esecuzione, il che richiede 18 minuti, poi esaurisce la memoria con le impostazioni predefinite. IntoSQL converte il dump in 10 secondi, e psql carica lo script in circa 3 minuti.
- Su 476 dump da MySQL 5.5 a 9 e da MariaDB 10.3 a 12, caricati in PostgreSQL 13 e 18: nessun errore di caricamento, e nessun valore modificato senza una riga nel report.
Esporta il database che hai
Il convertitore legge un file, non un server in esecuzione. Ogni database ne scrive uno con i propri strumenti:
MySQL
Un dump di mysqldump, mysqlpump, phpMyAdmin o Adminer, come .sql o .sql.gz. --default-character-set=utf8mb4 --hex-blob --routines --triggers --events conservano il più possibile.
Guida alla migrazione da MySQL a PostgreSQLMariaDB
Un dump di mariadb-dump, mysqldump, phpMyAdmin o Adminer, come .sql o .sql.gz, con le stesse opzioni di MySQL.
Guida alla migrazione da MariaDB a PostgreSQLPostgreSQL
Un dump in testo semplice di pg_dump o pg_dumpall. Un archivio custom (-Fc) diventa uno con pg_restore -f dump.sql, senza server.
Guida alla migrazione da PostgreSQL a MySQLSQL Server
Lo script che scrive Generate Scripts di SSMS, con Types of data to script impostato su Schema and data. dbatools e mssql-scripter scrivono lo stesso.
Guida alla migrazione da SQL Server a PostgreSQLSQLite
Il file del database stesso (.db, .sqlite, .sqlite3), o l'SQL che scrive sqlite3 app.db .dump.
Guida alla migrazione da SQLite a PostgreSQLOracle
Il file .sql che scrive Database Export di SQL Developer o SQLcl, con DDL e istruzioni Insert. Un file .dmp di exp o expdp va prima importato ed esportato di nuovo.
Guida alla migrazione da Oracle a PostgreSQL
Domande sulla migrazione di database
Non trovi la risposta? Scrivici dalla pagina dei contatti e ti risponde una persona. Pagina dei contatti
Il mio dump viene caricato?
No. Il convertitore funziona nel tuo browser e legge il dump dal tuo disco a pezzi, quindi non lascia mai il tuo computer. Anche l'app desktop e la riga di comando convertono sul tuo computer.
Quanto può essere grande il dump?
Il convertitore non tiene mai l'intero dump in memoria: legge il file due volte, per intervalli, e scrive lo script man mano. I dump di più gigabyte si convertono nel browser, nell'app desktop e con la riga di comando.
Da quali versioni può venire il dump?
MySQL da 5.5 a 9, MariaDB da 10.3 a 12, PostgreSQL 10 e successivi, SQL Server 2017 e successivi, SQLite 3.0 e successivi, e Oracle 11g e successivi. La pagina di ogni coppia indica su quali versioni si carica il suo script.
Serve un server di database in esecuzione?
No. Il convertitore legge direttamente il file di dump, quindi il database di origine non deve girare da nessuna parte. Lo script si carica con il client della destinazione, come psql, mysql o sqlcmd.
Cosa non viene convertito?
Viste, trigger, stored procedure, funzioni ed eventi sono scritti nel linguaggio di ciascun database, quindi sono elencati per nome nel report. Tabelle, chiavi, indici e righe sono tutti nello script.
Può caricare lo script direttamente nel mio database?
L'app desktop e il comando intosql load scrivono direttamente in SQLite gratis, e in PostgreSQL, MySQL e MariaDB con IntoSQL Pro. Per SQL Server e Oracle, esegui lo script con sqlcmd o sqlplus.