Konwertuj SQLite do MariaDB
Upuść plik bazy danych SQLite (.db, .sqlite, .sqlite3) albo SQL zapisany przez .dump z sqlite3 i pobierz skrypt MariaDB z tymi samymi tabelami, kluczami, indeksami i danymi. Każda kolumna dostaje typ, w którym mieszczą się jej wartości, a każda wartość, której MariaDB nie może przechować bez zmian, jest wymieniona w raporcie.
18 wierszy przekonwertowanych, bez poprawek, brak odrzuconych
Tabele w pliku shop_2024_sqlite.sqlZrzut SQLite · zapisany przez sqlite3 · utf-8
customers8 wierszy
7 kolumn id bigint not null name text not null email varchar(768) not null country text not null is_active tinyint(1) not null signed_up date created_at datetime not null orders10 wierszy
9 kolumn id bigint not null customer_id bigint not null status varchar(768) not null total decimal(10,2) not null items int not null ordered_at datetime not null shipped_at datetime note text receipt blob
Nieprzekonwertowane
- Widok order_totals
- Wyzwalacz orders_shipped
Każda baza danych zapisuje je we własnym języku. Przepisz je dla MariaDB.
-- Written by IntoSQL from a SQLite dump. Load it with: mariadb --default-character-set=utf8mb4 <database> < <file>
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
SET UNIQUE_CHECKS = 0;
SET SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO,ALLOW_INVALID_DATES';
CREATE TABLE `customers` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
`email` varchar(768) NOT NULL,
`country` text NOT NULL DEFAULT 'US',
`is_active` tinyint(1) NOT NULL DEFAULT 1,
`signed_up` date,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
CONSTRAINT `check1` CHECK (char_length(`country`) = 2)
) AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE `orders` (
`id` bigint NOT NULL AUTO_INCREMENT,
`customer_id` bigint NOT NULL,
`status` varchar(768) NOT NULL DEFAULT 'pending',
`total` decimal(10,2) NOT NULL,
`items` int NOT NULL DEFAULT 1,
`ordered_at` datetime NOT NULL,
`shipped_at` datetime,
`note` text,
`receipt` blob,
PRIMARY KEY (`id`),
KEY `idx_orders_customer` (`customer_id`),
KEY `idx_orders_status_date` (`status`,`ordered_at`),
CONSTRAINT `check1` CHECK (`status` IN ('pending', 'paid', 'shipped', 'cancelled')),
FOREIGN KEY (`customer_id`) REFERENCES `customers` (`id`) ON DELETE CASCADE
) AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
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');
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (2,'Zoë Müller','zoe@example.de','DE',1,'2023-02-03','2023-02-03 08:11:42');
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (3,'José Peña','jose@example.es','ES',0,'2023-03-21','2023-03-21 19:05:17');
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (4,'李雷','lilei@example.cn','CN',1,'2023-05-09','2023-05-09 02:40:00');
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (5,'Noah O\'Brien','noah@example.ie','IE',1,NULL,'2023-06-30 14:00:00');
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (6,'Amélie Laurent','amelie@example.fr','FR',1,'2024-01-02','2024-01-02 09:30:00');
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (7,'Ravi Patel','ravi@example.in','IN',0,'2024-02-29','2024-02-29 23:59:59');
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (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`,`receipt`) VALUES (1,1,'shipped',129.9,3,'2024-03-01 10:00:00','2024-03-02 16:30:00',NULL,NULL);
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`receipt`) VALUES (2,2,'paid',54,1,'2024-03-02 11:15:00',NULL,'Gift wrap 🎁',NULL);
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`receipt`) VALUES (3,1,'cancelled',12.5,1,'2024-03-03 09:45:00',NULL,'Customer changed their mind',NULL);
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`receipt`) VALUES (4,4,'shipped',980,12,'2024-03-05 02:10:00','2024-03-07 08:00:00','请小心轻放',X'25504446');
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`receipt`) VALUES (5,5,'pending',45.75,2,'2024-03-08 17:20:00',NULL,'Leave at the door;\nring twice',NULL);
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`receipt`) VALUES (6,6,'shipped',310.4,5,'2024-03-10 13:00:00','2024-03-11 09:00:00','Fragile: "glass"',NULL);
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`receipt`) VALUES (7,8,'paid',76.2,2,'2024-03-11 18:45:00',NULL,NULL,NULL);
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`receipt`) VALUES (8,2,'paid',19.99,1,'2024-03-12 08:00:00',NULL,'Paid at the counter',NULL);
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`receipt`) VALUES (9,3,'shipped',64,2,'2024-03-14 15:30:00',NULL,'Shipping date never recorded',NULL);
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`receipt`) VALUES (10,7,'paid',1499,1,'2024-03-15 21:05:00',NULL,'C:\\Users\\ravi\\invoice.pdf',NULL);
SET UNIQUE_CHECKS = 1;
SET FOREIGN_KEY_CHECKS = 1;
Poprawki
Nic nie wymagało poprawek.
Do sprawdzenia
- W źródle 1 kolumna tekstowa ignoruje wielkość liter przy porównaniu; MariaDB porównuje dokładnie, więc klucze unikalne i wyszukiwanie mogą działać inaczej. Użyj collation lub typu kolumny ignorującego wielkość liter w kolumnach, które tego potrzebują.
- Widoki, wyzwalacze, procedury i zdarzenia nie są konwertowane: 2 obiekty, każdy wymieniony w raporcie. Utwórz je ręcznie w MariaDB.
Plik jest konwertowany na tym komputerze i nigdy nie jest wysyłany.
Inne przykłady:
Co zmienia się między SQLite a MariaDB
Każdy wiersz to reguła stosowana przez konwerter, z wpisem, który dodaje do raportu, gdy reguła coś zmienia w twoich danych.
declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none)
typ, w którym mieści się każda wartość kolumny
SQLite przechowuje dowolną wartość w dowolnej kolumnie, więc zadeklarowany typ jest tylko wskazówką: każda kolumna dostaje typ, w którym mieszczą się wszystkie jej wartości, a kolumna z mieszanymi wartościami zachowuje ich tekst.
BOOLEAN, BOOL
tinyint(1)
Gdy każda wartość to 0 lub 1; kolumna, która zawiera też inne wartości, zachowuje je jako liczby lub tekst.
TEXT, VARCHAR(n), CHAR(n), CLOB
varchar(n) do 1024 znaków, powyżej typy text
SQLite nigdy nie wymusza długości; zadeklarowana długość obowiązuje tylko wtedy, gdy mieści się w niej każda wartość.
DECIMAL(p,s), NUMERIC
dokładny typ, gdy mieści się w nim każda wartość, w przeciwnym razie double
SQLite przechowuje je jako liczby całkowite lub double; zadeklarowana precyzja obowiązuje tylko wtedy, gdy wartości się w niej mieszczą.
BLOB, and columns holding bytes
typy blob
Bajty pozostają bajtami; tekst i liczby w tej samej kolumnie są zachowywane jako ich bajty.
DATE, DATETIME, TIMESTAMP holding ISO 8601 text
date, datetime(p)
Gdy każda wartość to data lub data z godziną; liczby epoch i inny tekst zachowują swoje wartości bez zmian.
JSON holding JSON text
json
Gdy każda wartość to obiekt lub tablica JSON.
Infinity in REAL columns
NULL
Typ double w MariaDB nie ma nieskończoności, więc te wartości stają się NULL, a raport je liczy.
Wpis w raporcie: invalid_value_null
INTEGER PRIMARY KEY, AUTOINCREMENT
AUTO_INCREMENT, kontynuowane po najwyższym id lub wartości z sqlite_sequence
Tylko kolumna zadeklarowana dokładnie jako INTEGER PRIMARY KEY jest rowid; każdy wiersz zachowuje swoje id, a licznik zaczyna po najwyższym kiedykolwiek wydanym id.
COLLATE NOCASE
dokładne porównanie (utf8mb4_bin)
Tabele używają utf8mb4_bin, więc tekst jest porównywany dokładnie, jak domyślnie w SQLite; kolumny NOCASE przestają ignorować wielkość liter.
Wpis w raporcie: case_insensitive_collation
generated columns
kolumny generowane, STORED lub VIRTUAL jak w źródle
MariaDB oblicza je tak samo.
generated columns with functions IntoSQL doesn't write, and the || operator
zwykła kolumna
Formuła, której nie da się zapisać, zostawia zwykłą kolumnę i wpis w raporcie; zrzut nie zawiera wartości kolumn generowanych.
Wpis w raporcie: generated_not_translated
defaults with functions IntoSQL doesn't write (strftime, randomblob)
brak wartości domyślnej
Wartość domyślna, której nie da się zapisać, jest pomijana i zgłaszana w raporcie; CURRENT_TIMESTAMP i datetime('now') są zapisywane.
Wpis w raporcie: default_not_translated
CHECK constraints
przetłumaczone
Te same ograniczenia CHECK, sprawdzane przy ładowaniu każdego wiersza.
CHECK constraints with functions IntoSQL doesn't write
nie jest tworzone
Ograniczenie CHECK, którego nie da się zapisać, jest pomijane i zgłaszane w raporcie.
Wpis w raporcie: check_skipped
partial and expression indexes
nie jest tworzone
IntoSQL zapisuje indeksy na całych kolumnach; pozostałe utwórz ponownie po załadowaniu.
Wpis w raporcie: index_skipped
foreign keys (unenforced unless PRAGMA foreign_keys=ON)
klucze obce, ładowane z FOREIGN_KEY_CHECKS=0
SQLite sprawdza klucze obce tylko na żądanie, więc wiersze bez rodzica są częste: ładują się, a klucz zostaje niesprawdzony z ostrzeżeniem, zamiast zatrzymać ładowanie.
foreign keys to tables the dump doesn't create
nie jest tworzone
Klucz nie może wskazywać tabeli, której nie ma.
Wpis w raporcie: foreign_key_skipped
primary keys holding NULL, and NOT NULL columns with values that become NULL
NOT NULL usunięte
SQLite pozwala, by klucz główny inny niż rowid zawierał NULL; kolumna nie może być NOT NULL w bazie docelowej, bo ładowanie by się zatrzymało.
Wpis w raporcie: not_null_relaxed
views, triggers and virtual tables (FTS, R*Tree)
wymienione w raporcie
Ich kod jest napisany we własnym języku SQLite, a tabele wirtualne wymagają modułów SQLite; trafiają na listę do ręcznego odtworzenia. Ich wewnętrzne tabele nie są kopiowane.
Wpis w raporcie: not_converted_objects
dumps without CREATE TABLE (--data-only)
typy odczytane z wartości
Zrzut samych danych zawiera tylko wiersze, więc typy pochodzą z wartości, a kolumny są numerowane.
Wpis w raporcie: no_schema
expressions in INSERT values other than the text functions dumps write
NULL
unistr(), replace(), char() i || są obliczane tak, jak zapisuje je powłoka; innych wyrażeń nie da się obliczyć bez bazy danych.
Wpis w raporcie: expression_value
NUL characters in text
zachowane
Powłoka sqlite3 i Python obcinają tekst na znaku NUL podczas zrzutu, więc w zrzucie jest tylko to, co go poprzedza.
text that isn't valid UTF-8
błędne bajty jako znak zastępczy
Zrzuty zapisują taki tekst jako surowe bajty; skrypt jest w UTF-8.
Wpis w raporcie: invalid_utf8_replaced
text decoded twice (ñ)
skopiowane bez zmian
Zrzut zawiera dokładnie te znaki, więc są kopiowane; raport je wskazuje.
Wpis w raporcie: mojibake_suspected
| W SQLite | W MariaDB | Wpis w raporcie |
|---|---|---|
| declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none) | typ, w którym mieści się każda wartość kolumnySQLite przechowuje dowolną wartość w dowolnej kolumnie, więc zadeklarowany typ jest tylko wskazówką: każda kolumna dostaje typ, w którym mieszczą się wszystkie jej wartości, a kolumna z mieszanymi wartościami zachowuje ich tekst. | |
| BOOLEAN, BOOL | tinyint(1)Gdy każda wartość to 0 lub 1; kolumna, która zawiera też inne wartości, zachowuje je jako liczby lub tekst. | |
| TEXT, VARCHAR(n), CHAR(n), CLOB | varchar(n) do 1024 znaków, powyżej typy textSQLite nigdy nie wymusza długości; zadeklarowana długość obowiązuje tylko wtedy, gdy mieści się w niej każda wartość. | |
| DECIMAL(p,s), NUMERIC | dokładny typ, gdy mieści się w nim każda wartość, w przeciwnym razie doubleSQLite przechowuje je jako liczby całkowite lub double; zadeklarowana precyzja obowiązuje tylko wtedy, gdy wartości się w niej mieszczą. | |
| BLOB, and columns holding bytes | typy blobBajty pozostają bajtami; tekst i liczby w tej samej kolumnie są zachowywane jako ich bajty. | |
| DATE, DATETIME, TIMESTAMP holding ISO 8601 text | date, datetime(p)Gdy każda wartość to data lub data z godziną; liczby epoch i inny tekst zachowują swoje wartości bez zmian. | |
| JSON holding JSON text | jsonGdy każda wartość to obiekt lub tablica JSON. | |
| Infinity in REAL columns | NULLTyp double w MariaDB nie ma nieskończoności, więc te wartości stają się NULL, a raport je liczy. | invalid_value_null |
| INTEGER PRIMARY KEY, AUTOINCREMENT | AUTO_INCREMENT, kontynuowane po najwyższym id lub wartości z sqlite_sequenceTylko kolumna zadeklarowana dokładnie jako INTEGER PRIMARY KEY jest rowid; każdy wiersz zachowuje swoje id, a licznik zaczyna po najwyższym kiedykolwiek wydanym id. | |
| COLLATE NOCASE | dokładne porównanie (utf8mb4_bin)Tabele używają utf8mb4_bin, więc tekst jest porównywany dokładnie, jak domyślnie w SQLite; kolumny NOCASE przestają ignorować wielkość liter. | case_insensitive_collation |
| generated columns | kolumny generowane, STORED lub VIRTUAL jak w źródleMariaDB oblicza je tak samo. | |
| generated columns with functions IntoSQL doesn't write, and the || operator | zwykła kolumnaFormuła, której nie da się zapisać, zostawia zwykłą kolumnę i wpis w raporcie; zrzut nie zawiera wartości kolumn generowanych. | generated_not_translated |
| defaults with functions IntoSQL doesn't write (strftime, randomblob) | brak wartości domyślnejWartość domyślna, której nie da się zapisać, jest pomijana i zgłaszana w raporcie; CURRENT_TIMESTAMP i datetime('now') są zapisywane. | default_not_translated |
| CHECK constraints | przetłumaczoneTe same ograniczenia CHECK, sprawdzane przy ładowaniu każdego wiersza. | |
| CHECK constraints with functions IntoSQL doesn't write | nie jest tworzoneOgraniczenie CHECK, którego nie da się zapisać, jest pomijane i zgłaszane w raporcie. | check_skipped |
| partial and expression indexes | nie jest tworzoneIntoSQL zapisuje indeksy na całych kolumnach; pozostałe utwórz ponownie po załadowaniu. | index_skipped |
| foreign keys (unenforced unless PRAGMA foreign_keys=ON) | klucze obce, ładowane z FOREIGN_KEY_CHECKS=0SQLite sprawdza klucze obce tylko na żądanie, więc wiersze bez rodzica są częste: ładują się, a klucz zostaje niesprawdzony z ostrzeżeniem, zamiast zatrzymać ładowanie. | |
| foreign keys to tables the dump doesn't create | nie jest tworzoneKlucz nie może wskazywać tabeli, której nie ma. | foreign_key_skipped |
| primary keys holding NULL, and NOT NULL columns with values that become NULL | NOT NULL usunięteSQLite pozwala, by klucz główny inny niż rowid zawierał NULL; kolumna nie może być NOT NULL w bazie docelowej, bo ładowanie by się zatrzymało. | not_null_relaxed |
| views, triggers and virtual tables (FTS, R*Tree) | wymienione w raporcieIch kod jest napisany we własnym języku SQLite, a tabele wirtualne wymagają modułów SQLite; trafiają na listę do ręcznego odtworzenia. Ich wewnętrzne tabele nie są kopiowane. | not_converted_objects |
| dumps without CREATE TABLE (--data-only) | typy odczytane z wartościZrzut samych danych zawiera tylko wiersze, więc typy pochodzą z wartości, a kolumny są numerowane. | no_schema |
| expressions in INSERT values other than the text functions dumps write | NULLunistr(), replace(), char() i || są obliczane tak, jak zapisuje je powłoka; innych wyrażeń nie da się obliczyć bez bazy danych. | expression_value |
| NUL characters in text | zachowanePowłoka sqlite3 i Python obcinają tekst na znaku NUL podczas zrzutu, więc w zrzucie jest tylko to, co go poprzedza. | |
| text that isn't valid UTF-8 | błędne bajty jako znak zastępczyZrzuty zapisują taki tekst jako surowe bajty; skrypt jest w UTF-8. | invalid_utf8_replaced |
| text decoded twice (ñ) | skopiowane bez zmianZrzut zawiera dokładnie te znaki, więc są kopiowane; raport je wskazuje. | mojibake_suspected |
Załaduj skrypt do MariaDB
Skrypt tworzy tabele, kopiuje wiersze, a potem dodaje klucze, indeksy i klucze obce, więc ładuje się szybko i zatrzymuje przy pierwszym błędzie.
mariadb --default-character-set=utf8mb4 mydb < sqlite.mariadb.sqlKlucze obce są tworzone tak, jak deklaruje je zrzut, z FOREIGN_KEY_CHECKS=0 podczas ładowania wierszy, tak jak robi to mysqldump.
Przy dużym zrzucie uruchom klienta na tej samej maszynie co serwer i zwiększ max_allowed_packet, jeśli pojedynczy wiersz jest bardzo duży.
IntoSQL Pro ładuje plik prosto do MariaDB z aplikacji na komputer lub wiersza poleceń, bez pisania skryptu.
Jak zrobić zrzut SQLite dla najlepszego wyniku
Konwerter odczytuje to, co zawiera zrzut. Te opcje zachowują w nim więcej twoich danych:
- Sam plik bazy danych konwertuje się bez zmian, odczytywany strona po stronie w przeglądarce. Najpierw zamknij aplikację, która do niego zapisuje, żeby żadna zmiana nie została w jego pliku -wal.
- sqlite3 app.db .dump > app.sql zapisuje tę samą bazę danych jako SQL, który też się konwertuje, jako .sql lub .sql.gz.
- DB Browser for SQLite zapisuje ten SQL przez File, Export, Database to SQL file, podobnie jak iterdump() w Pythonie.
Co nie jest konwertowane
Widoki i wyzwalacze są pisane we własnym języku SQLite. Raport wymienia je z nazwy i nigdy nie pomija ich po cichu, więc możesz je przepisać dla MariaDB. Tabele wirtualne, takie jak FTS5 i R*Tree, też są wymienione, a ich tabele cieni są pomijane.
Pytania o konwersję SQLite do MariaDB
Nie ma tu odpowiedzi? Napisz do nas przez stronę kontaktu, a odpowie człowiek. Strona kontaktu
Czy mój zrzut jest wysyłany?
Nie. Konwerter działa w przeglądarce i odczytuje zrzut z dysku po kawałku, więc nigdy nie opuszcza on twojego komputera. Aplikacja na komputer i wiersz poleceń też konwertują na twoim komputerze.
Jak duży może być zrzut?
Konwerter nigdy nie trzyma całego zrzutu w pamięci: czyta plik dwa razy, fragmentami, i zapisuje skrypt na bieżąco. Zrzuty wielogigabajtowe konwertują się w przeglądarce, w aplikacji na komputer i w wierszu poleceń.
Czy mogę przekonwertować sam plik .db?
Tak. Upuść plik .db, .sqlite lub .sqlite3: jest odczytywany w przeglądarce i nigdy nie jest wysyłany. Tekst ze znakami NUL i każda cyfra wartości double docierają tak, jak zostały zapisane, a .dump może je obciąć.
Z jakich wersji SQLite może pochodzić zrzut?
Pliki bazy danych od SQLite 3.0, w UTF-8 lub UTF-16, oraz zrzuty z .dump powłoki sqlite3 lub z iterdump() w Pythonie. Każdy testowy plik i zrzut pochodzi z sqlite3 od 3.31 do 3.54, łącznie z tabelami STRICT i WITHOUT ROWID, i jest porównywany ze źródłem komórka po komórce.
Jak ustalane są typy kolumn, skoro SQLite ich nie wymusza?
Zadeklarowany typ jest wskazówką, a decydują wartości: kolumna dostaje typ integer, decimal, double, date, datetime, tinyint(1), blob lub text, gdy mieści się w nim każda wartość. Kolumna z mieszanymi wartościami zachowuje ich tekst, a raport podaje, które to kolumny.
Czy INTEGER PRIMARY KEY i AUTOINCREMENT są zachowywane?
Tak. INTEGER PRIMARY KEY staje się AUTO_INCREMENT, każdy wiersz zachowuje swoje id, a kolejne id idzie po najwyższym albo, przy AUTOINCREMENT, po wartości z sqlite_sequence.
A widoki i wyzwalacze?
Raport wymienia je z nazwy, ale nie są konwertowane, bo każda baza danych zapisuje je we własnym języku.
Na jakich wersjach MariaDB ładuje się skrypt?
MariaDB 10.11 i nowsze. Każdy testowy zrzut ładuje się na 10.11 i 11.4 i zatrzymuje przy pierwszym błędzie, jeśli coś pójdzie nie tak.