Converti MySQL in SQLite
Trascina un dump di mysqldump, mariadb-dump, mysqlpump, phpMyAdmin o Adminer, in .sql o .sql.gz, e scarica uno script SQLite con le stesse tabelle, chiavi, indici e dati. Ogni valore che SQLite non può contenere così com'è, e ogni oggetto che non supporta, è elencato nel report.
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 INTEGER not null name VARCHAR(100) not null email VARCHAR(150) not null country VARCHAR(2) not null is_active INTEGER not null signed_up DATE created_at TIMESTAMP not null orders10 righe5
9 colonne id INTEGER not null customer_id INTEGER not null status TEXT not null total DECIMAL(10,2) not null items INTEGER not null ordered_at DATETIME not null shipped_at DATETIME note VARCHAR(255) updated_at TIMESTAMP not null
-- Written by IntoSQL from a MySQL dump. Load it with: sqlite3 -bail <database> < <file>
PRAGMA foreign_keys = OFF;
PRAGMA synchronous = OFF;
BEGIN;
CREATE TABLE customers ( -- People who bought at least once
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(100) NOT NULL,
email VARCHAR(150) NOT NULL,
country VARCHAR(2) DEFAULT 'US' NOT NULL,
is_active INTEGER DEFAULT 1 NOT NULL,
signed_up DATE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
CONSTRAINT customers_id_check CHECK (id >= 0)
);
CREATE TABLE orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer_id INTEGER NOT NULL,
status TEXT DEFAULT 'pending' NOT NULL,
total DECIMAL(10,2) NOT NULL,
items INTEGER DEFAULT 1 NOT NULL,
ordered_at DATETIME NOT NULL,
shipped_at DATETIME,
note VARCHAR(255),
updated_at TIMESTAMP 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),
CONSTRAINT fk_orders_customer FOREIGN KEY (customer_id) REFERENCES customers (id)
);
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(1,'Ana Martínez','ana@example.com','MX',1,'2023-01-15','2023-01-15 10:24:00'),
(2,'Zoë Müller','zoe@example.de','DE',1,'2023-02-03','2023-02-03 08:11:42'),
(3,'José Peña','jose@example.es','ES',0,'2023-03-21','2023-03-21 19:05:17'),
(4,'李雷','lilei@example.cn','CN',1,'2023-05-09','2023-05-09 02:40:00'),
(5,'Noah O''Brien','noah@example.ie','IE',1,NULL,'2023-06-30 14:00:00'),
(6,'Amélie Laurent','amelie@example.fr','FR',1,'2024-01-02','2024-01-02 09:30:00'),
(7,'Ravi Patel','ravi@example.in','IN',0,'2024-02-29','2024-02-29 23:59:59'),
(8,'Sofia Rossi 🌻','sofia@example.it','IT',1,'2024-04-12','2024-04-12 12:12:12');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, updated_at) VALUES
(1,1,'shipped',129.90,3,'2024-03-01 10:00:00','2024-03-02 16:30:00',NULL,'2024-03-02 16:30:00'),
(2,2,'paid',54.00,1,'2024-03-02 11:15:00',NULL,'Gift wrap 🎁','2024-03-02 11:20:00'),
(3,1,'cancelled',12.50,1,'2024-03-03 09:45:00',NULL,'Customer changed their mind','2024-03-03 10: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'),
(5,5,'pending',45.75,2,'2024-03-08 17:20:00',NULL,'Leave at the door; ring twice','2024-03-08 17:20: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'),
(7,8,'paid',76.20,2,'2024-03-11 18:45:00',NULL,NULL,'2024-03-11 18:46:00'),
(8,2,'',19.99,1,'2024-03-12 08:00:00',NULL,'Status lost in an old import','2024-03-12 08:00:00'),
(9,3,'shipped',64.00,2,'2024-03-14 15:30:00',NULL,'Shipping date never recorded','2024-03-15 10:00:00'),
(10,7,'paid',1499.00,1,'2024-03-15 21:05:00',NULL,'C:\Users\ravi\invoice.pdf','2024-03-15 21:05:00');
-- Indexes, triggers and counters, after the rows so each index builds once.
CREATE UNIQUE INDEX customers_uq_email ON customers (email);
CREATE INDEX orders_idx_customer ON orders (customer_id);
CREATE INDEX orders_idx_status_date ON orders (status, ordered_at);
UPDATE sqlite_sequence SET seq = max(seq, 1000) WHERE name = 'customers';
INSERT INTO sqlite_sequence (name, seq) SELECT 'customers', 1000 WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = 'customers');
UPDATE sqlite_sequence SET seq = max(seq, 5000) WHERE name = 'orders';
INSERT INTO sqlite_sequence (name, seq) SELECT 'orders', 5000 WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = 'orders');
CREATE TRIGGER orders_updated_at_on_update AFTER UPDATE ON orders FOR EACH ROW WHEN NEW.updated_at IS OLD.updated_at AND (NEW.id IS NOT OLD.id OR NEW.customer_id IS NOT OLD.customer_id OR NEW.status IS NOT OLD.status OR NEW.total IS NOT OLD.total OR NEW.items IS NOT OLD.items OR NEW.ordered_at IS NOT OLD.ordered_at OR NEW.shipped_at IS NOT OLD.shipped_at OR NEW.note IS NOT OLD.note)
BEGIN
UPDATE orders SET updated_at = CURRENT_TIMESTAMP WHERE rowid = NEW.rowid;
END;
COMMIT;
-- Rows whose foreign key finds no parent, if any: the load doesn't stop for them.
PRAGMA foreign_key_check;
Correzioni
- "id" di customers è senza segno, quindi è diventata INTEGER 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 SQLite accetta, quindi la colonna non ha un valore predefinito.
- "customer_id" di orders è senza segno, quindi è diventata INTEGER con un vincolo CHECK che non sia negativa.
- "id" di orders è senza segno, quindi è diventata INTEGER 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 SQLite lo fa un trigger.
Da controllare
- 1 valore in "signed_up" di customers è una data zero o impossibile come 0000‑00‑00, che SQLite 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 SQLite 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:
Cosa cambia da MySQL a SQLite
Ogni riga è una regola che il convertitore applica, con la riga del report che scrive quando la regola cambia qualcosa nei tuoi dati.
TINYINT(1), BOOL
INTEGER con i valori così come sono
SQLite non ha un tipo booleano; vero e falso sono gli interi 1 e 0, quindi ogni valore mantiene il suo significato.
UNSIGNED integers
INTEGER con un CHECK che non sia negativo; BIGINT UNSIGNED con valori oltre 2^63-1 è TEXT
Gli interi di SQLite sono a 64 bit con segno. Il CHECK tiene fuori i valori negativi come faceva MySQL; i valori oltre l'intervallo con segno restano come testo, così non si perde nessuna cifra.
Riga del report: unsigned_widened
ZEROFILL and display widths
rimosso
Il riempimento con zeri è un modo di mostrare un numero, non ne fa parte. I numeri restano; formattali quando li leggi se il riempimento conta.
Riga del report: zerofill_dropped
FLOAT(M,D)
REAL, senza la scala
I float di SQLite non hanno una scala fissa. I valori salvati vengono copiati così come sono.
Riga del report: float_scale_dropped
DECIMAL(p,s)
DECIMAL(p,s) fino a 15 cifre; TEXT oltre
SQLite tiene circa 15 cifre significative in un numero. I decimali più ampi restano come testo, così ogni cifra resta esatta.
Riga del report: decimal_as_text
BIT(1), BIT(n)
INTEGER con il valore dei bit; BIT(64) come cifre TEXT
Un campo di bit viene salvato come il numero formato dai suoi bit. Il bit più alto di un BIT(64) non sta in un intero con segno, quindi il suo numero resta come testo.
zero, partial or impossible dates (0000-00-00, 2024-02-30)
NULL
Le funzioni di data di SQLite leggono solo date reali del calendario. Diventano NULL e il report le conta, come per ogni altro database.
Riga del report: invalid_date_null
NOT NULL columns with values that become NULL
NOT NULL rimosso
Una colonna i cui valori sono dovuti diventare NULL non può mantenere NOT NULL, altrimenti il caricamento si fermerebbe.
Riga del report: not_null_relaxed
DEFAULT '0000-00-00'
nessun valore predefinito
Un valore predefinito che non è una data reale viene omesso invece di essere sostituito con uno inventato.
Riga del report: zero_date_default
TIME
testo TIME come lo scrive MySQL, durate incluse
SQLite tiene gli orari come testo, quindi le durate oltre un giorno o sotto zero restano esatte.
YEAR
INTEGER con un CHECK del suo intervallo
SQLite non ha un tipo anno; il vincolo CHECK mantiene gli stessi valori che MySQL consente.
CHAR(n), VARCHAR(n)
VARCHAR(n), non applicato
SQLite tiene il tipo dichiarato per gli strumenti ma non limita la lunghezza; i valori sono quelli che restituisce MySQL.
DATETIME
DATETIME come testo ISO 8601
SQLite salva le date come testo che le sue funzioni di data leggono.
TIMESTAMP
TIMESTAMP come testo ISO 8601 in UTC; il fuso indicato dal dump, UTC se non ne indica uno
Un TIMESTAMP è un istante, scritto in UTC. I dump indicano il fuso in cui lo hanno scritto (mysqldump scrive UTC); senza questa indicazione, i valori vengono letti come UTC e il report lo dice.
Riga del report: timestamp_zone_assumed
ENUM
TEXT con un CHECK dei suoi valori
Il testo con un vincolo CHECK mantiene gli stessi valori.
ENUM holding '' (MySQL's error value)
il valore vuoto ammesso dal vincolo CHECK
MySQL salva una stringa vuota quando un valore non valido entra in un ENUM con una modalità SQL permissiva. Quelle righe restano e il vincolo CHECK le ammette.
Riga del report: enum_invalid_value
ENUM holding values outside its list
nessun CHECK
I valori che la lista non nomina violerebbero il vincolo CHECK, quindi il vincolo non viene creato.
Riga del report: enum_check_skipped
SET
TEXT come lo scrive MySQL ('a,b')
SQLite non ha array; il testo è quello che restituisce MySQL.
JSON
TEXT
Le funzioni JSON di SQLite leggono il JSON dal testo. Una colonna dichiarata JSON trasformerebbe "123" in un numero, quindi è TEXT.
NUL bytes in text
mantenuto
Il testo di SQLite può contenere un byte NUL, quindi il valore viene copiato così com'è.
text that isn't valid in its character set
i byte errati come carattere di sostituzione
Il testo di SQLite è UTF-8; le sue funzioni leggono male i byte che non lo sono.
Riga del report: invalid_utf8_replaced
text decoded twice (ñ)
copiato così com'è
Il dump contiene esattamente questi caratteri, quindi vengono copiati; il report li segnala.
Riga del report: mojibake_suspected
AUTO_INCREMENT
INTEGER PRIMARY KEY AUTOINCREMENT, con il contatore impostato oltre gli id copiati
SQLite conta una chiave primaria intera di tipo intero. AUTOINCREMENT evita che gli id vengano riusati, come fa MySQL, e il contatore riparte dopo l'id più alto o dopo l'AUTO_INCREMENT del dump, se è maggiore.
AUTO_INCREMENT on part of a key or outside one
INTEGER senza contatore
SQLite conta solo una colonna che è l'intera chiave primaria, quindi la colonna mantiene i suoi valori e le nuove righe devono avere i loro.
Riga del report: identity_without_counter
ON UPDATE CURRENT_TIMESTAMP
un trigger AFTER UPDATE
Il trigger imposta la colonna all'ora corrente quando una riga cambia e l'aggiornamento non l'ha impostata, come fa MySQL.
Riga del report: on_update_trigger
generated columns
GENERATED ALWAYS AS, VIRTUAL o STORED come nella sorgente
SQLite dalla 3.31 calcola le colonne generate negli stessi due modi.
generated columns with functions SQLite lacks
una colonna semplice
Una formula che non si può scrivere per SQLite lascia una colonna semplice e una riga nel report.
Riga del report: generated_not_translated
INVISIBLE columns
colonne normali
SQLite non ha colonne invisibili.
Riga del report: invisible_column
CHECK constraints
tradotti, dentro CREATE TABLE
SQLite accetta i vincoli CHECK solo in CREATE TABLE.
CHECK constraints with functions SQLite lacks
non creato
Un vincolo CHECK che non si può scrivere per SQLite viene omesso e segnalato.
Riga del report: check_skipped
CHECK ... NOT ENFORCED
non creati
MySQL conserva questi vincoli senza applicarli, quindi le righe possono violarli.
Riga del report: check_not_enforced
defaults with functions SQLite lacks
nessun valore predefinito
Un valore predefinito che non si può scrivere per SQLite viene omesso e segnalato.
Riga del report: default_not_translated
keys and indexes on a prefix, c(20)
un indice su substr(c, 1, 20)
SQLite indicizza le espressioni, quindi viene indicizzato lo stesso prefisso e un prefisso univoco resta univoco.
Riga del report: prefix_unique
FULLTEXT indexes
non creato
SQLite cerca nel testo con tabelle FTS5 separate, che richiedono query proprie.
Riga del report: fulltext_not_created
SPATIAL indexes
non creato
SQLite non ha indici spaziali su una colonna.
Riga del report: spatial_index_not_created
functional indexes SQLite can't write
non creato
Un indice su un'espressione che non si può scrivere per SQLite viene omesso e segnalato.
Riga del report: index_skipped
foreign keys
in CREATE TABLE, caricate senza controllo, poi elencate da PRAGMA foreign_key_check
SQLite accetta le chiavi esterne solo in CREATE TABLE e le controlla solo con PRAGMA foreign_keys attivo. Le righe si caricano senza controllo, come da MySQL, e lo script finisce elencando ogni riga senza genitore.
foreign keys to columns without a unique key
non creata
SQLite richiede una chiave univoca sulle colonne referenziate; InnoDB no.
Riga del report: foreign_key_skipped
table, index and column names
come scritti; rinominati quando differiscono solo per maiuscole o un nome di indice si ripete
In SQLite i nomi ignorano le maiuscole, e i nomi degli indici condividono un unico namespace per database.
Riga del report: identifier_renamed
GEOMETRY, POINT, POLYGON...
WKB in un BLOB
Il formato binario standard WKB conserva ogni geometria in modo esatto.
Riga del report: geometry_as_blob
INET4, INET6, UUID (MariaDB)
TEXT
SQLite non ha questi tipi; il testo è quello che restituisce MariaDB.
BINARY, VARBINARY, BLOB
BLOB
I byte restano byte.
PARTITION BY
una sola tabella
Le righe sono le stesse.
Riga del report: partitions_dropped
WITH SYSTEM VERSIONING (MariaDB)
una tabella con le righe attuali
Un dump contiene solo le righe attuali.
Riga del report: system_versioning_dropped
MyISAM, MEMORY and other engines
una tabella normale
SQLite ha un solo motore di tabelle.
Riga del report: engine_dropped
dumps of several databases
un unico file, ogni tabella con il nome del suo database davanti
Un file SQLite è un solo database, quindi il nome del database tiene distinte le tabelle con lo stesso nome.
Riga del report: databases_merged
views, triggers, procedures, functions and events
elencati nel report
Il loro codice è scritto nel linguaggio di MySQL, quindi vengono elencati perché tu li ricrei.
Riga del report: not_converted_objects
dumps without CREATE TABLE
tipi ricavati dai valori
Un dump fatto con --no-create-info contiene solo righe, quindi i tipi vengono dai valori.
Riga del report: no_schema
geometries in a dump without CREATE TABLE
WKB in un BLOB
Il formato delle geometrie di MySQL viene riconosciuto dai valori e salvato come WKB standard.
Riga del report: geometry_as_blob
_ci collations
confronto esatto
SQLite confronta il testo in modo esatto salvo indicazione diversa, e il suo NOCASE ignora le maiuscole solo per le lettere ASCII.
Riga del report: case_insensitive_collation
SET NAMES utf8 from utf8mb4 tables
convertito, con un avviso
mysqldump di MySQL 5.x scrive utf8 a 3 byte per impostazione predefinita e sostituisce ogni emoji con un punto interrogativo prima che un convertitore veda il file.
Riga del report: dump_lost_four_byte_chars
dumps without SET NAMES whose text isn't UTF-8
letto come Latin-1 (Windows-1252)
Il latin1 di MySQL è Windows-1252, la codifica abituale di questi dump.
Riga del report: charset_guessed
sjis, cp932, gbk, big5 dumps
letto come UTF-8, con un avviso
Queste codifiche non vengono ancora decodificate.
Riga del report: unsupported_charset
UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows
valutate
Alcuni strumenti di dump scrivono i valori come queste chiamate; vengono letti come i valori che producono, e il WKT geografico viene convertito mettendo prima la longitudine.
other expressions in rows
NULL
Un convertitore che non esegue un database non può valutarle.
Riga del report: expression_value
DEFAULT in VALUES
il valore predefinito della colonna
Un valore predefinito letterale viene copiato nella riga.
Riga del report: default_keyword_filled
DEFAULT in VALUES without a literal default
NULL
Non c'è nessun valore da copiare.
Riga del report: default_keyword_null
REPLACE and INSERT IGNORE
righe semplici
Un dump ha una riga per chiave, quindi le righe sono le stesse.
Riga del report: replace_as_insert
types IntoSQL doesn't know
TEXT
Il testo contiene qualsiasi valore; cambia il tipo dopo il caricamento.
Riga del report: unknown_type
values that don't fit their column
NULL
Un dump danneggiato o scritto a mano può contenere valori che la colonna non ammette; diventano NULL così il resto si carica.
Riga del report: invalid_value_null
unreadable geometries
NULL
I byte che non sono una geometria non si possono salvare come tale.
Riga del report: bad_geometry
CREATE SEQUENCE (MariaDB)
non creato
SQLite non ha sequenze.
Riga del report: sequence_not_converted
VECTOR(n) (MariaDB 11.7+)
TEXT con i float come array JSON
SQLite non ha un tipo vector; un array JSON mantiene ogni float.
Riga del report: type_replaced
| In MySQL | In SQLite | Riga del report |
|---|---|---|
| TINYINT(1), BOOL | INTEGER con i valori così come sonoSQLite non ha un tipo booleano; vero e falso sono gli interi 1 e 0, quindi ogni valore mantiene il suo significato. | |
| UNSIGNED integers | INTEGER con un CHECK che non sia negativo; BIGINT UNSIGNED con valori oltre 2^63-1 è TEXTGli interi di SQLite sono a 64 bit con segno. Il CHECK tiene fuori i valori negativi come faceva MySQL; i valori oltre l'intervallo con segno restano come testo, così non si perde nessuna cifra. | unsigned_widened |
| ZEROFILL and display widths | rimossoIl riempimento con zeri è un modo di mostrare un numero, non ne fa parte. I numeri restano; formattali quando li leggi se il riempimento conta. | zerofill_dropped |
| FLOAT(M,D) | REAL, senza la scalaI float di SQLite non hanno una scala fissa. I valori salvati vengono copiati così come sono. | float_scale_dropped |
| DECIMAL(p,s) | DECIMAL(p,s) fino a 15 cifre; TEXT oltreSQLite tiene circa 15 cifre significative in un numero. I decimali più ampi restano come testo, così ogni cifra resta esatta. | decimal_as_text |
| BIT(1), BIT(n) | INTEGER con il valore dei bit; BIT(64) come cifre TEXTUn campo di bit viene salvato come il numero formato dai suoi bit. Il bit più alto di un BIT(64) non sta in un intero con segno, quindi il suo numero resta come testo. | |
| zero, partial or impossible dates (0000-00-00, 2024-02-30) | NULLLe funzioni di data di SQLite leggono solo date reali del calendario. Diventano NULL e il report le conta, come per ogni altro database. | invalid_date_null |
| NOT NULL columns with values that become NULL | NOT NULL rimossoUna colonna i cui valori sono dovuti diventare NULL non può mantenere NOT NULL, altrimenti il caricamento si fermerebbe. | not_null_relaxed |
| DEFAULT '0000-00-00' | nessun valore predefinitoUn valore predefinito che non è una data reale viene omesso invece di essere sostituito con uno inventato. | zero_date_default |
| TIME | testo TIME come lo scrive MySQL, durate incluseSQLite tiene gli orari come testo, quindi le durate oltre un giorno o sotto zero restano esatte. | |
| YEAR | INTEGER con un CHECK del suo intervalloSQLite non ha un tipo anno; il vincolo CHECK mantiene gli stessi valori che MySQL consente. | |
| CHAR(n), VARCHAR(n) | VARCHAR(n), non applicatoSQLite tiene il tipo dichiarato per gli strumenti ma non limita la lunghezza; i valori sono quelli che restituisce MySQL. | |
| DATETIME | DATETIME come testo ISO 8601SQLite salva le date come testo che le sue funzioni di data leggono. | |
| TIMESTAMP | TIMESTAMP come testo ISO 8601 in UTC; il fuso indicato dal dump, UTC se non ne indica unoUn TIMESTAMP è un istante, scritto in UTC. I dump indicano il fuso in cui lo hanno scritto (mysqldump scrive UTC); senza questa indicazione, i valori vengono letti come UTC e il report lo dice. | timestamp_zone_assumed |
| ENUM | TEXT con un CHECK dei suoi valoriIl testo con un vincolo CHECK mantiene gli stessi valori. | |
| ENUM holding '' (MySQL's error value) | il valore vuoto ammesso dal vincolo CHECKMySQL salva una stringa vuota quando un valore non valido entra in un ENUM con una modalità SQL permissiva. Quelle righe restano e il vincolo CHECK le ammette. | enum_invalid_value |
| ENUM holding values outside its list | nessun CHECKI valori che la lista non nomina violerebbero il vincolo CHECK, quindi il vincolo non viene creato. | enum_check_skipped |
| SET | TEXT come lo scrive MySQL ('a,b')SQLite non ha array; il testo è quello che restituisce MySQL. | |
| JSON | TEXTLe funzioni JSON di SQLite leggono il JSON dal testo. Una colonna dichiarata JSON trasformerebbe "123" in un numero, quindi è TEXT. | |
| NUL bytes in text | mantenutoIl testo di SQLite può contenere un byte NUL, quindi il valore viene copiato così com'è. | |
| text that isn't valid in its character set | i byte errati come carattere di sostituzioneIl testo di SQLite è UTF-8; le sue funzioni leggono male i byte che non lo sono. | invalid_utf8_replaced |
| text decoded twice (ñ) | copiato così com'èIl dump contiene esattamente questi caratteri, quindi vengono copiati; il report li segnala. | mojibake_suspected |
| AUTO_INCREMENT | INTEGER PRIMARY KEY AUTOINCREMENT, con il contatore impostato oltre gli id copiatiSQLite conta una chiave primaria intera di tipo intero. AUTOINCREMENT evita che gli id vengano riusati, come fa MySQL, e il contatore riparte dopo l'id più alto o dopo l'AUTO_INCREMENT del dump, se è maggiore. | |
| AUTO_INCREMENT on part of a key or outside one | INTEGER senza contatoreSQLite conta solo una colonna che è l'intera chiave primaria, quindi la colonna mantiene i suoi valori e le nuove righe devono avere i loro. | identity_without_counter |
| ON UPDATE CURRENT_TIMESTAMP | un trigger AFTER UPDATEIl trigger imposta la colonna all'ora corrente quando una riga cambia e l'aggiornamento non l'ha impostata, come fa MySQL. | on_update_trigger |
| generated columns | GENERATED ALWAYS AS, VIRTUAL o STORED come nella sorgenteSQLite dalla 3.31 calcola le colonne generate negli stessi due modi. | |
| generated columns with functions SQLite lacks | una colonna sempliceUna formula che non si può scrivere per SQLite lascia una colonna semplice e una riga nel report. | generated_not_translated |
| INVISIBLE columns | colonne normaliSQLite non ha colonne invisibili. | invisible_column |
| CHECK constraints | tradotti, dentro CREATE TABLESQLite accetta i vincoli CHECK solo in CREATE TABLE. | |
| CHECK constraints with functions SQLite lacks | non creatoUn vincolo CHECK che non si può scrivere per SQLite viene omesso e segnalato. | check_skipped |
| CHECK ... NOT ENFORCED | non creatiMySQL conserva questi vincoli senza applicarli, quindi le righe possono violarli. | check_not_enforced |
| defaults with functions SQLite lacks | nessun valore predefinitoUn valore predefinito che non si può scrivere per SQLite viene omesso e segnalato. | default_not_translated |
| keys and indexes on a prefix, c(20) | un indice su substr(c, 1, 20)SQLite indicizza le espressioni, quindi viene indicizzato lo stesso prefisso e un prefisso univoco resta univoco. | prefix_unique |
| FULLTEXT indexes | non creatoSQLite cerca nel testo con tabelle FTS5 separate, che richiedono query proprie. | fulltext_not_created |
| SPATIAL indexes | non creatoSQLite non ha indici spaziali su una colonna. | spatial_index_not_created |
| functional indexes SQLite can't write | non creatoUn indice su un'espressione che non si può scrivere per SQLite viene omesso e segnalato. | index_skipped |
| foreign keys | in CREATE TABLE, caricate senza controllo, poi elencate da PRAGMA foreign_key_checkSQLite accetta le chiavi esterne solo in CREATE TABLE e le controlla solo con PRAGMA foreign_keys attivo. Le righe si caricano senza controllo, come da MySQL, e lo script finisce elencando ogni riga senza genitore. | |
| foreign keys to columns without a unique key | non creataSQLite richiede una chiave univoca sulle colonne referenziate; InnoDB no. | foreign_key_skipped |
| table, index and column names | come scritti; rinominati quando differiscono solo per maiuscole o un nome di indice si ripeteIn SQLite i nomi ignorano le maiuscole, e i nomi degli indici condividono un unico namespace per database. | identifier_renamed |
| GEOMETRY, POINT, POLYGON... | WKB in un BLOBIl formato binario standard WKB conserva ogni geometria in modo esatto. | geometry_as_blob |
| INET4, INET6, UUID (MariaDB) | TEXTSQLite non ha questi tipi; il testo è quello che restituisce MariaDB. | |
| BINARY, VARBINARY, BLOB | BLOBI byte restano byte. | |
| PARTITION BY | una sola tabellaLe righe sono le stesse. | partitions_dropped |
| WITH SYSTEM VERSIONING (MariaDB) | una tabella con le righe attualiUn dump contiene solo le righe attuali. | system_versioning_dropped |
| MyISAM, MEMORY and other engines | una tabella normaleSQLite ha un solo motore di tabelle. | engine_dropped |
| dumps of several databases | un unico file, ogni tabella con il nome del suo database davantiUn file SQLite è un solo database, quindi il nome del database tiene distinte le tabelle con lo stesso nome. | databases_merged |
| views, triggers, procedures, functions and events | elencati nel reportIl loro codice è scritto nel linguaggio di MySQL, quindi vengono elencati perché tu li ricrei. | not_converted_objects |
| dumps without CREATE TABLE | tipi ricavati dai valoriUn dump fatto con --no-create-info contiene solo righe, quindi i tipi vengono dai valori. | no_schema |
| geometries in a dump without CREATE TABLE | WKB in un BLOBIl formato delle geometrie di MySQL viene riconosciuto dai valori e salvato come WKB standard. | geometry_as_blob |
| _ci collations | confronto esattoSQLite confronta il testo in modo esatto salvo indicazione diversa, e il suo NOCASE ignora le maiuscole solo per le lettere ASCII. | case_insensitive_collation |
| SET NAMES utf8 from utf8mb4 tables | convertito, con un avvisomysqldump di MySQL 5.x scrive utf8 a 3 byte per impostazione predefinita e sostituisce ogni emoji con un punto interrogativo prima che un convertitore veda il file. | dump_lost_four_byte_chars |
| dumps without SET NAMES whose text isn't UTF-8 | letto come Latin-1 (Windows-1252)Il latin1 di MySQL è Windows-1252, la codifica abituale di questi dump. | charset_guessed |
| sjis, cp932, gbk, big5 dumps | letto come UTF-8, con un avvisoQueste codifiche non vengono ancora decodificate. | unsupported_charset |
| UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows | valutateAlcuni strumenti di dump scrivono i valori come queste chiamate; vengono letti come i valori che producono, e il WKT geografico viene convertito mettendo prima la longitudine. | |
| other expressions in rows | NULLUn convertitore che non esegue un database non può valutarle. | expression_value |
| DEFAULT in VALUES | il valore predefinito della colonnaUn valore predefinito letterale viene copiato nella riga. | default_keyword_filled |
| DEFAULT in VALUES without a literal default | NULLNon c'è nessun valore da copiare. | default_keyword_null |
| REPLACE and INSERT IGNORE | righe sempliciUn dump ha una riga per chiave, quindi le righe sono le stesse. | replace_as_insert |
| types IntoSQL doesn't know | TEXTIl testo contiene qualsiasi valore; cambia il tipo dopo il caricamento. | unknown_type |
| values that don't fit their column | NULLUn dump danneggiato o scritto a mano può contenere valori che la colonna non ammette; diventano NULL così il resto si carica. | invalid_value_null |
| unreadable geometries | NULLI byte che non sono una geometria non si possono salvare come tale. | bad_geometry |
| CREATE SEQUENCE (MariaDB) | non creatoSQLite non ha sequenze. | sequence_not_converted |
| VECTOR(n) (MariaDB 11.7+) | TEXT con i float come array JSONSQLite non ha un tipo vector; un array JSON mantiene ogni float. | type_replaced |
Carica lo script in SQLite
Lo script crea le tabelle, copia le righe, poi aggiunge chiavi, indici e chiavi esterne, così si carica in fretta e si ferma al primo errore.
sqlite3 -bail mydb.sqlite < mysql.sqlite.sqlLe chiavi esterne sono dichiarate in ogni tabella e le righe si caricano con i controlli delle chiavi esterne disattivati. Lo script poi elenca ogni riga che punta a una riga che non esiste, invece di fallire a metà.
Per un dump grande, carica in un file nuovo su un disco locale. Lo script carica tutto in un'unica transazione con la sincronizzazione disattivata, così va alla velocità del disco, e un caricamento che si ferma a metà non lascia tabelle parziali.
La riga di comando carica il file direttamente in un database SQLite, senza scrivere uno script. È gratis.
Fai il dump di MySQL per il miglior risultato
Il convertitore legge ciò che il dump contiene. Con queste opzioni il dump conserva più dei tuoi dati:
- --default-character-set=utf8mb4 conserva emoji e altri caratteri a 4 byte, che un dump utf8 perde prima che il convertitore lo veda.
- --hex-blob scrive le colonne binarie in esadecimale, che resiste alla copia tra sistemi diversi.
- --routines --triggers --events aggiungono quegli oggetti al dump, così il report può elencarli.
Cosa non viene convertito
Viste, trigger, stored procedure, funzioni ed eventi sono scritti nel linguaggio proprio di ogni database. Sono elencati per nome nel report, mai rimossi in silenzio, così puoi riscriverli per SQLite.
Domande sulla conversione da MySQL a SQLite
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.
Legge i dump di MariaDB?
Sì. I dump di mariadb-dump e di MariaDB dalla 10.3 alla 12 si convertono allo stesso modo, comprese le colonne INET6, INET4 e UUID di MariaDB.
Cosa succede alle date 0000-00-00?
Diventano NULL: SQLite salverebbe il testo, ma niente legge 0000-00-00 come una data. Il report dice quante erano in ogni colonna.
I valori AUTO_INCREMENT vengono mantenuti?
Sì. Una colonna AUTO_INCREMENT che è l'intera chiave primaria della tabella diventa INTEGER PRIMARY KEY AUTOINCREMENT, ogni riga mantiene il suo id e l'id successivo riparte dopo il più alto. Ogni altra colonna AUTO_INCREMENT mantiene i suoi valori senza contatore, e il report lo dice.
TINYINT(1) diventa boolean?
No. SQLite non ha un tipo booleano, quindi TINYINT(1) è un INTEGER e ogni valore resta com'è.
E le stored procedure e i trigger?
Sono elencati per nome nel report e non vengono convertiti, perché ogni database li scrive nel proprio linguaggio. ON UPDATE CURRENT_TIMESTAMP è l'eccezione: diventa un trigger di SQLite.
Su quali versioni di SQLite si carica lo script?
SQLite 3.31 e successive. Ogni dump di test si carica su 3.31 e 3.54, fermandosi al primo errore se qualcosa va storto.