Converta MariaDB para SQLite
Solte um dump do mariadb-dump, mysqldump, phpMyAdmin ou Adminer, em .sql ou .sql.gz, e baixe um script do SQLite com as mesmas tabelas, chaves, índices e dados. Cada valor que o SQLite não aceita como está, e cada objeto que ele não traz, aparece no relatório.
18 linhas convertidas, 8 correções, nenhuma rejeitada
Tabelas em shop_2024_mariadb.sqlDump do MariaDB 11.8.9-MariaDB-ubu2404 · gerado por mariadb-dump · utf8mb4
customers8 linhas3
8 colunas 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 last_ip TEXT orders10 linhas5
12 colunas 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) order_ref TEXT not null invoice INTEGER not null details TEXT 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,
last_ip TEXT,
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),
order_ref TEXT NOT NULL,
invoice INTEGER NOT NULL,
details TEXT,
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, last_ip) VALUES
(1,'Ana Martínez','ana@example.com','MX',1,'2023-01-15','2023-01-15 10:24:00','::ffff:203.0.113.7'),
(2,'Zoë Müller','zoe@example.de','DE',1,'2023-02-03','2023-02-03 08:11:42','2001:db8::1'),
(3,'José Peña','jose@example.es','ES',0,'2023-03-21','2023-03-21 19:05:17',NULL),
(4,'李雷','lilei@example.cn','CN',1,'2023-05-09','2023-05-09 02:40:00','::ffff:198.51.100.23'),
(5,'Noah O''Brien','noah@example.ie','IE',1,NULL,'2023-06-30 14:00:00',NULL),
(6,'Amélie Laurent','amelie@example.fr','FR',1,'2024-01-02','2024-01-02 09:30:00','2001:db8:85a3::8a2e:370:7334'),
(7,'Ravi Patel','ravi@example.in','IN',0,'2024-02-29','2024-02-29 23:59:59','::ffff:192.0.2.200'),
(8,'Sofia Rossi 🌻','sofia@example.it','IT',1,'2024-04-12','2024-04-12 12:12:12',NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, order_ref, invoice, details, updated_at) VALUES
(1,1,'shipped',129.90,3,'2024-03-01 10:00:00','2024-03-02 16:30:00',NULL,'0b7a4c2e-3f1d-4e8a-9c55-1a2b3c4d5e6f',1000,'{"gift": false}','2024-03-02 16:30:00'),
(2,2,'paid',54.00,1,'2024-03-02 11:15:00',NULL,'Gift wrap 🎁','1c8b5d3f-4a2e-4f9b-8d66-2b3c4d5e6f70',1001,'{"gift": true, "wrap": "red"}','2024-03-02 11:20:00'),
(3,1,'cancelled',12.50,1,'2024-03-03 09:45:00',NULL,'Customer changed their mind','2d9c6e4a-5b3f-4a0c-9e77-3c4d5e6f7081',1002,NULL,'2024-03-03 10:00:00'),
(4,4,'shipped',980.00,12,'2024-03-05 02:10:00','2024-03-07 08:00:00','请小心轻放','3e0d7f5b-6c4a-4b1d-8f88-4d5e6f708192',1003,'{"fragile": true}','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','4f1e806c-7d5b-4c2e-9a99-5e6f708192a3',1004,NULL,'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"','50f2917d-8e6c-4d3f-8baa-6f708192a3b4',1005,'{"fragile": true}','2024-03-11 09:00:00'),
(7,8,'paid',76.20,2,'2024-03-11 18:45:00',NULL,NULL,'6103a28e-9f7d-4e40-9cbb-708192a3b4c5',1006,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','7214b39f-a08e-4f51-8dcc-8192a3b4c5d6',1007,NULL,'2024-03-12 08:00:00'),
(9,3,'shipped',64.00,2,'2024-03-14 15:30:00',NULL,'Shipping date never recorded','8325c4a0-b19f-4062-9edd-92a3b4c5d6e7',1008,'{"parcels": [1, 2]}','2024-03-15 10:00:00'),
(10,7,'paid',1499.00,1,'2024-03-15 21:05:00',NULL,'C:\Users\ravi\invoice.pdf','9436d5b1-c2a0-4173-8fee-a3b4c5d6e7f8',1009,NULL,'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 OR NEW.order_ref IS NOT OLD.order_ref OR NEW.invoice IS NOT OLD.invoice OR NEW.details IS NOT OLD.details)
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;
Correções
- "id" de customers é sem sinal, então virou INTEGER com um CHECK de que não é negativa.
- "signed_up" de customers agora aceita NULL: alguns dos seus valores não puderam ser guardados e são NULL.
- O valor padrão de "signed_up" em customers, 0000‑00‑00, não é uma data que o SQLite aceite, então a coluna fica sem valor padrão.
- "customer_id" de orders é sem sinal, então virou INTEGER com um CHECK de que não é negativa.
- "id" de orders é sem sinal, então virou INTEGER com um CHECK de que não é negativa.
- "items" de orders é sem sinal, então virou INTEGER com um CHECK de que não é negativa.
- 1 linha de "status" em orders contém o valor vazio que o MySQL guarda para entradas inválidas; o CHECK dos valores o permite.
- "updated_at" de orders muda para a hora atual a cada atualização; no SQLite, um gatilho faz isso.
Para revisar
- 1 sequência não foi criada; o SQLite não tem sequências. Guarde o próximo valor em uma tabela se a sua aplicação precisar.
- 1 valor em "signed_up" de customers é uma data zero ou impossível, como 0000‑00‑00, que o SQLite não consegue guardar, então ficou NULL. Se essas datas têm significado, troque-as na origem por datas reais antes do dump.
- O valor padrão de "invoice" em orders não pode ser escrito para o SQLite (a sequence), então a coluna fica sem valor padrão. Adicione o valor padrão manualmente se novas linhas precisarem dele.
- 1 valor em "shipped_at" de orders é uma data zero ou impossível, como 0000‑00‑00 00:00:00, que o SQLite não consegue guardar, então ficou NULL. Se essas datas têm significado, troque-as na origem por datas reais antes do dump.
Seu arquivo é convertido neste computador e nunca é enviado.
Outros exemplos:
O que muda do MariaDB para o SQLite
Cada linha é uma regra que o conversor aplica, com a linha do relatório que ele escreve quando a regra muda algo nos seus dados.
TINYINT(1), BOOL
INTEGER com os valores como estão
O SQLite não tem tipo booleano; true e false são os inteiros 1 e 0, então cada valor mantém o significado.
UNSIGNED integers
INTEGER com um CHECK de que não é negativo; BIGINT UNSIGNED com valores acima de 2^63-1 vira TEXT
Os inteiros do SQLite são de 64 bits com sinal. O CHECK impede valores negativos, como o MySQL fazia; valores além do intervalo com sinal ficam como texto, para que nenhum dígito se perca.
Linha do relatório: unsigned_widened
ZEROFILL and display widths
descartado
O preenchimento com zeros é uma forma de exibir um número, não parte dele. Os números são mantidos; formate-os na leitura se o preenchimento for importante.
Linha do relatório: zerofill_dropped
FLOAT(M,D)
REAL, sem a escala
Os floats do SQLite não têm escala fixa. Os valores guardados são copiados como estão.
Linha do relatório: float_scale_dropped
DECIMAL(p,s)
DECIMAL(p,s) até 15 dígitos; TEXT acima disso
O SQLite guarda cerca de 15 dígitos significativos em um número. Decimais mais largos ficam como texto, para que cada dígito continue exato.
Linha do relatório: decimal_as_text
BIT(1), BIT(n)
INTEGER com o valor dos bits; BIT(64) como dígitos em TEXT
Um campo de bits é guardado como o número que seus bits formam. O bit mais alto de um BIT(64) não cabe em um inteiro com sinal, então o número fica como texto.
zero, partial or impossible dates (0000-00-00, 2024-02-30)
NULL
As funções de data do SQLite só leem datas reais do calendário. Elas viram NULL e o relatório as conta, como em todos os outros bancos de dados.
Linha do relatório: invalid_date_null
NOT NULL columns with values that become NULL
NOT NULL removido
Uma coluna cujos valores tiveram de virar NULL não pode manter NOT NULL, senão a carga pararia.
Linha do relatório: not_null_relaxed
DEFAULT '0000-00-00'
sem valor padrão
Um valor padrão que não é uma data real fica de fora em vez de ser trocado por uma inventada.
Linha do relatório: zero_date_default
TIME
TIME como texto, do jeito que o MySQL escreve, incluindo durações
O SQLite guarda horas como texto, então durações acima de um dia ou abaixo de zero são mantidas exatamente.
YEAR
INTEGER com um CHECK do intervalo
O SQLite não tem tipo de ano; o CHECK mantém os mesmos valores que o MySQL permite.
CHAR(n), VARCHAR(n)
VARCHAR(n), sem limite aplicado
O SQLite mantém o tipo declarado para as ferramentas lerem, mas não limita o tamanho; os valores são os que o MySQL retorna.
DATETIME
DATETIME como texto ISO 8601
O SQLite guarda datas como texto que suas funções de data leem.
TIMESTAMP
TIMESTAMP como texto ISO 8601 em UTC; no fuso que o dump informa, UTC quando ele não informa nenhum
Um TIMESTAMP é um instante, escrito em UTC. Os dumps informam o fuso em que foram escritos (o mysqldump escreve em UTC); sem isso, os valores são lidos como UTC e o relatório avisa.
Linha do relatório: timestamp_zone_assumed
ENUM
TEXT com um CHECK dos valores
Texto com CHECK mantém os mesmos valores.
ENUM holding '' (MySQL's error value)
o valor vazio, permitido pelo CHECK
O MySQL guarda uma string vazia quando um valor inválido entra em um ENUM em um modo SQL permissivo. Essas linhas são mantidas e o CHECK as permite.
Linha do relatório: enum_invalid_value
ENUM holding values outside its list
sem CHECK
Valores que a lista não nomeia falhariam no CHECK, então o CHECK não é criado.
Linha do relatório: enum_check_skipped
SET
TEXT como o MySQL escreve ('a,b')
O SQLite não tem arrays; o texto é o que o MySQL retorna.
JSON
TEXT
As funções JSON do SQLite leem JSON a partir de texto. Uma coluna declarada JSON transformaria "123" em número, então ela é TEXT.
NUL bytes in text
mantido
O texto do SQLite aceita o byte NUL, então o valor é copiado como está.
text that isn't valid in its character set
os bytes inválidos como o caractere de substituição
O texto do SQLite é UTF-8; suas funções leem errado os bytes que não são.
Linha do relatório: invalid_utf8_replaced
text decoded twice (ñ)
copiado como está
O dump contém exatamente esses caracteres, então eles são copiados; o relatório os aponta.
Linha do relatório: mojibake_suspected
AUTO_INCREMENT
INTEGER PRIMARY KEY AUTOINCREMENT, com o contador ajustado depois dos ids copiados
O SQLite conta uma chave primária formada por uma única coluna inteira. AUTOINCREMENT impede que ids sejam reutilizados, como no MySQL, e o contador continua depois do maior id ou do AUTO_INCREMENT do dump, o que for maior.
AUTO_INCREMENT on part of a key or outside one
INTEGER sem contador
O SQLite só conta uma coluna que é toda a chave primária, então a coluna mantém seus valores e as novas linhas precisam dos delas.
Linha do relatório: identity_without_counter
ON UPDATE CURRENT_TIMESTAMP
um gatilho AFTER UPDATE
O gatilho define a coluna com a hora atual quando uma linha muda e a atualização não a definiu, como o MySQL faz.
Linha do relatório: on_update_trigger
generated columns
GENERATED ALWAYS AS, VIRTUAL ou STORED como na origem
O SQLite 3.31 e posteriores calculam colunas geradas dos mesmos dois jeitos.
generated columns with functions SQLite lacks
uma coluna simples
Uma fórmula que não pode ser escrita para o SQLite deixa uma coluna simples e uma linha no relatório.
Linha do relatório: generated_not_translated
INVISIBLE columns
colunas comuns
O SQLite não tem colunas invisíveis.
Linha do relatório: invisible_column
CHECK constraints
traduzido, dentro do CREATE TABLE
O SQLite só aceita CHECKs no CREATE TABLE.
CHECK constraints with functions SQLite lacks
não criado
Um CHECK que não pode ser escrito para o SQLite fica de fora e é informado no relatório.
Linha do relatório: check_skipped
CHECK ... NOT ENFORCED
não criado
O MySQL mantém esses CHECKs sem aplicá-los, então as linhas podem violá-los.
Linha do relatório: check_not_enforced
defaults with functions SQLite lacks
sem valor padrão
Um valor padrão que não pode ser escrito para o SQLite fica de fora e é informado no relatório.
Linha do relatório: default_not_translated
keys and indexes on a prefix, c(20)
um índice sobre substr(c, 1, 20)
O SQLite indexa expressões, então o mesmo prefixo é indexado e um prefixo único continua único.
Linha do relatório: prefix_unique
FULLTEXT indexes
não criado
O SQLite busca texto com tabelas FTS5 separadas, que precisam de consultas próprias.
Linha do relatório: fulltext_not_created
SPATIAL indexes
não criado
O SQLite não tem índice espacial em uma coluna.
Linha do relatório: spatial_index_not_created
functional indexes SQLite can't write
não criado
Um índice sobre uma expressão que não pode ser escrita para o SQLite fica de fora e é informado no relatório.
Linha do relatório: index_skipped
foreign keys
no CREATE TABLE, carregadas sem verificação, depois listadas por PRAGMA foreign_key_check
O SQLite só aceita chaves estrangeiras no CREATE TABLE e só as verifica com PRAGMA foreign_keys ligado. As linhas carregam sem verificação, como no MySQL, e o script termina listando cada linha sem pai.
foreign keys to columns without a unique key
não criada
O SQLite exige uma chave única nas colunas referenciadas; o InnoDB não.
Linha do relatório: foreign_key_skipped
table, index and column names
como escritos; renomeados quando diferem só em maiúsculas e minúsculas ou quando um nome de índice se repete
Os nomes do SQLite ignoram maiúsculas e minúsculas, e os nomes de índice compartilham um namespace por banco de dados.
Linha do relatório: identifier_renamed
GEOMETRY, POINT, POLYGON...
WKB em um BLOB
O formato binário padrão WKB (well-known binary) mantém cada geometria exata.
Linha do relatório: geometry_as_blob
INET4, INET6, UUID (MariaDB)
TEXT
O SQLite não tem esses tipos; o texto é o que o MariaDB retorna.
BINARY, VARBINARY, BLOB
BLOB
Bytes continuam sendo bytes.
PARTITION BY
uma tabela
As linhas são as mesmas.
Linha do relatório: partitions_dropped
WITH SYSTEM VERSIONING (MariaDB)
uma tabela com as linhas atuais
Um dump contém só as linhas atuais.
Linha do relatório: system_versioning_dropped
MyISAM, MEMORY and other engines
uma tabela comum
O SQLite tem um único mecanismo de tabelas.
Linha do relatório: engine_dropped
dumps of several databases
um arquivo, cada tabela com o nome do seu banco na frente
Um arquivo SQLite é um banco de dados, então o nome do banco separa tabelas com o mesmo nome.
Linha do relatório: databases_merged
views, triggers, procedures, functions and events
listados no relatório
O código deles é escrito na linguagem do MySQL, então eles são listados para você recriá-los.
Linha do relatório: not_converted_objects
dumps without CREATE TABLE
tipos deduzidos dos valores
Um dump feito com --no-create-info só tem linhas, então os tipos vêm dos valores.
Linha do relatório: no_schema
geometries in a dump without CREATE TABLE
WKB em um BLOB
O formato de geometria do MySQL é reconhecido pelos valores e guardado como WKB padrão.
Linha do relatório: geometry_as_blob
_ci collations
comparação exata
O SQLite compara texto de forma exata, a menos que se indique o contrário, e o seu NOCASE só iguala letras ASCII.
Linha do relatório: case_insensitive_collation
SET NAMES utf8 from utf8mb4 tables
convertido, com um aviso
O mysqldump do MySQL 5.x escreve utf8 de 3 bytes por padrão e troca cada emoji por um ponto de interrogação antes que qualquer conversor veja o arquivo.
Linha do relatório: dump_lost_four_byte_chars
dumps without SET NAMES whose text isn't UTF-8
lido como Latin-1 (Windows-1252)
O latin1 do MySQL é o Windows-1252, a codificação comum desses dumps.
Linha do relatório: charset_guessed
sjis, cp932, gbk, big5 dumps
lido como UTF-8, com um aviso
Essas codificações ainda não são decodificadas.
Linha do relatório: unsupported_charset
UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows
avaliadas
Algumas ferramentas de dump escrevem valores como essas chamadas; elas são lidas como os valores que produzem, com o WKT geográfico convertido para longitude primeiro.
other expressions in rows
NULL
Um conversor que não executa um banco de dados não consegue avaliá-las.
Linha do relatório: expression_value
DEFAULT in VALUES
o valor padrão da coluna
Um valor padrão literal é copiado para a linha.
Linha do relatório: default_keyword_filled
DEFAULT in VALUES without a literal default
NULL
Não há valor para copiar.
Linha do relatório: default_keyword_null
REPLACE and INSERT IGNORE
linhas simples
Um dump tem uma linha por chave, então as linhas são as mesmas.
Linha do relatório: replace_as_insert
types IntoSQL doesn't know
TEXT
O tipo text aceita qualquer valor; mude o tipo depois da carga.
Linha do relatório: unknown_type
values that don't fit their column
NULL
Um dump danificado ou escrito à mão pode conter valores que a coluna não aceita; eles viram NULL para que o resto carregue.
Linha do relatório: invalid_value_null
unreadable geometries
NULL
Bytes que não são uma geometria não podem ser guardados como uma.
Linha do relatório: bad_geometry
CREATE SEQUENCE (MariaDB)
não criado
O SQLite não tem sequências.
Linha do relatório: sequence_not_converted
VECTOR(n) (MariaDB 11.7+)
TEXT com os floats como array JSON
O SQLite não tem tipo vector; um array JSON mantém cada float.
Linha do relatório: type_replaced
| No MariaDB | No SQLite | Linha do relatório |
|---|---|---|
| TINYINT(1), BOOL | INTEGER com os valores como estãoO SQLite não tem tipo booleano; true e false são os inteiros 1 e 0, então cada valor mantém o significado. | |
| UNSIGNED integers | INTEGER com um CHECK de que não é negativo; BIGINT UNSIGNED com valores acima de 2^63-1 vira TEXTOs inteiros do SQLite são de 64 bits com sinal. O CHECK impede valores negativos, como o MySQL fazia; valores além do intervalo com sinal ficam como texto, para que nenhum dígito se perca. | unsigned_widened |
| ZEROFILL and display widths | descartadoO preenchimento com zeros é uma forma de exibir um número, não parte dele. Os números são mantidos; formate-os na leitura se o preenchimento for importante. | zerofill_dropped |
| FLOAT(M,D) | REAL, sem a escalaOs floats do SQLite não têm escala fixa. Os valores guardados são copiados como estão. | float_scale_dropped |
| DECIMAL(p,s) | DECIMAL(p,s) até 15 dígitos; TEXT acima dissoO SQLite guarda cerca de 15 dígitos significativos em um número. Decimais mais largos ficam como texto, para que cada dígito continue exato. | decimal_as_text |
| BIT(1), BIT(n) | INTEGER com o valor dos bits; BIT(64) como dígitos em TEXTUm campo de bits é guardado como o número que seus bits formam. O bit mais alto de um BIT(64) não cabe em um inteiro com sinal, então o número fica como texto. | |
| zero, partial or impossible dates (0000-00-00, 2024-02-30) | NULLAs funções de data do SQLite só leem datas reais do calendário. Elas viram NULL e o relatório as conta, como em todos os outros bancos de dados. | invalid_date_null |
| NOT NULL columns with values that become NULL | NOT NULL removidoUma coluna cujos valores tiveram de virar NULL não pode manter NOT NULL, senão a carga pararia. | not_null_relaxed |
| DEFAULT '0000-00-00' | sem valor padrãoUm valor padrão que não é uma data real fica de fora em vez de ser trocado por uma inventada. | zero_date_default |
| TIME | TIME como texto, do jeito que o MySQL escreve, incluindo duraçõesO SQLite guarda horas como texto, então durações acima de um dia ou abaixo de zero são mantidas exatamente. | |
| YEAR | INTEGER com um CHECK do intervaloO SQLite não tem tipo de ano; o CHECK mantém os mesmos valores que o MySQL permite. | |
| CHAR(n), VARCHAR(n) | VARCHAR(n), sem limite aplicadoO SQLite mantém o tipo declarado para as ferramentas lerem, mas não limita o tamanho; os valores são os que o MySQL retorna. | |
| DATETIME | DATETIME como texto ISO 8601O SQLite guarda datas como texto que suas funções de data leem. | |
| TIMESTAMP | TIMESTAMP como texto ISO 8601 em UTC; no fuso que o dump informa, UTC quando ele não informa nenhumUm TIMESTAMP é um instante, escrito em UTC. Os dumps informam o fuso em que foram escritos (o mysqldump escreve em UTC); sem isso, os valores são lidos como UTC e o relatório avisa. | timestamp_zone_assumed |
| ENUM | TEXT com um CHECK dos valoresTexto com CHECK mantém os mesmos valores. | |
| ENUM holding '' (MySQL's error value) | o valor vazio, permitido pelo CHECKO MySQL guarda uma string vazia quando um valor inválido entra em um ENUM em um modo SQL permissivo. Essas linhas são mantidas e o CHECK as permite. | enum_invalid_value |
| ENUM holding values outside its list | sem CHECKValores que a lista não nomeia falhariam no CHECK, então o CHECK não é criado. | enum_check_skipped |
| SET | TEXT como o MySQL escreve ('a,b')O SQLite não tem arrays; o texto é o que o MySQL retorna. | |
| JSON | TEXTAs funções JSON do SQLite leem JSON a partir de texto. Uma coluna declarada JSON transformaria "123" em número, então ela é TEXT. | |
| NUL bytes in text | mantidoO texto do SQLite aceita o byte NUL, então o valor é copiado como está. | |
| text that isn't valid in its character set | os bytes inválidos como o caractere de substituiçãoO texto do SQLite é UTF-8; suas funções leem errado os bytes que não são. | invalid_utf8_replaced |
| text decoded twice (ñ) | copiado como estáO dump contém exatamente esses caracteres, então eles são copiados; o relatório os aponta. | mojibake_suspected |
| AUTO_INCREMENT | INTEGER PRIMARY KEY AUTOINCREMENT, com o contador ajustado depois dos ids copiadosO SQLite conta uma chave primária formada por uma única coluna inteira. AUTOINCREMENT impede que ids sejam reutilizados, como no MySQL, e o contador continua depois do maior id ou do AUTO_INCREMENT do dump, o que for maior. | |
| AUTO_INCREMENT on part of a key or outside one | INTEGER sem contadorO SQLite só conta uma coluna que é toda a chave primária, então a coluna mantém seus valores e as novas linhas precisam dos delas. | identity_without_counter |
| ON UPDATE CURRENT_TIMESTAMP | um gatilho AFTER UPDATEO gatilho define a coluna com a hora atual quando uma linha muda e a atualização não a definiu, como o MySQL faz. | on_update_trigger |
| generated columns | GENERATED ALWAYS AS, VIRTUAL ou STORED como na origemO SQLite 3.31 e posteriores calculam colunas geradas dos mesmos dois jeitos. | |
| generated columns with functions SQLite lacks | uma coluna simplesUma fórmula que não pode ser escrita para o SQLite deixa uma coluna simples e uma linha no relatório. | generated_not_translated |
| INVISIBLE columns | colunas comunsO SQLite não tem colunas invisíveis. | invisible_column |
| CHECK constraints | traduzido, dentro do CREATE TABLEO SQLite só aceita CHECKs no CREATE TABLE. | |
| CHECK constraints with functions SQLite lacks | não criadoUm CHECK que não pode ser escrito para o SQLite fica de fora e é informado no relatório. | check_skipped |
| CHECK ... NOT ENFORCED | não criadoO MySQL mantém esses CHECKs sem aplicá-los, então as linhas podem violá-los. | check_not_enforced |
| defaults with functions SQLite lacks | sem valor padrãoUm valor padrão que não pode ser escrito para o SQLite fica de fora e é informado no relatório. | default_not_translated |
| keys and indexes on a prefix, c(20) | um índice sobre substr(c, 1, 20)O SQLite indexa expressões, então o mesmo prefixo é indexado e um prefixo único continua único. | prefix_unique |
| FULLTEXT indexes | não criadoO SQLite busca texto com tabelas FTS5 separadas, que precisam de consultas próprias. | fulltext_not_created |
| SPATIAL indexes | não criadoO SQLite não tem índice espacial em uma coluna. | spatial_index_not_created |
| functional indexes SQLite can't write | não criadoUm índice sobre uma expressão que não pode ser escrita para o SQLite fica de fora e é informado no relatório. | index_skipped |
| foreign keys | no CREATE TABLE, carregadas sem verificação, depois listadas por PRAGMA foreign_key_checkO SQLite só aceita chaves estrangeiras no CREATE TABLE e só as verifica com PRAGMA foreign_keys ligado. As linhas carregam sem verificação, como no MySQL, e o script termina listando cada linha sem pai. | |
| foreign keys to columns without a unique key | não criadaO SQLite exige uma chave única nas colunas referenciadas; o InnoDB não. | foreign_key_skipped |
| table, index and column names | como escritos; renomeados quando diferem só em maiúsculas e minúsculas ou quando um nome de índice se repeteOs nomes do SQLite ignoram maiúsculas e minúsculas, e os nomes de índice compartilham um namespace por banco de dados. | identifier_renamed |
| GEOMETRY, POINT, POLYGON... | WKB em um BLOBO formato binário padrão WKB (well-known binary) mantém cada geometria exata. | geometry_as_blob |
| INET4, INET6, UUID (MariaDB) | TEXTO SQLite não tem esses tipos; o texto é o que o MariaDB retorna. | |
| BINARY, VARBINARY, BLOB | BLOBBytes continuam sendo bytes. | |
| PARTITION BY | uma tabelaAs linhas são as mesmas. | partitions_dropped |
| WITH SYSTEM VERSIONING (MariaDB) | uma tabela com as linhas atuaisUm dump contém só as linhas atuais. | system_versioning_dropped |
| MyISAM, MEMORY and other engines | uma tabela comumO SQLite tem um único mecanismo de tabelas. | engine_dropped |
| dumps of several databases | um arquivo, cada tabela com o nome do seu banco na frenteUm arquivo SQLite é um banco de dados, então o nome do banco separa tabelas com o mesmo nome. | databases_merged |
| views, triggers, procedures, functions and events | listados no relatórioO código deles é escrito na linguagem do MySQL, então eles são listados para você recriá-los. | not_converted_objects |
| dumps without CREATE TABLE | tipos deduzidos dos valoresUm dump feito com --no-create-info só tem linhas, então os tipos vêm dos valores. | no_schema |
| geometries in a dump without CREATE TABLE | WKB em um BLOBO formato de geometria do MySQL é reconhecido pelos valores e guardado como WKB padrão. | geometry_as_blob |
| _ci collations | comparação exataO SQLite compara texto de forma exata, a menos que se indique o contrário, e o seu NOCASE só iguala letras ASCII. | case_insensitive_collation |
| SET NAMES utf8 from utf8mb4 tables | convertido, com um avisoO mysqldump do MySQL 5.x escreve utf8 de 3 bytes por padrão e troca cada emoji por um ponto de interrogação antes que qualquer conversor veja o arquivo. | dump_lost_four_byte_chars |
| dumps without SET NAMES whose text isn't UTF-8 | lido como Latin-1 (Windows-1252)O latin1 do MySQL é o Windows-1252, a codificação comum desses dumps. | charset_guessed |
| sjis, cp932, gbk, big5 dumps | lido como UTF-8, com um avisoEssas codificações ainda não são decodificadas. | unsupported_charset |
| UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows | avaliadasAlgumas ferramentas de dump escrevem valores como essas chamadas; elas são lidas como os valores que produzem, com o WKT geográfico convertido para longitude primeiro. | |
| other expressions in rows | NULLUm conversor que não executa um banco de dados não consegue avaliá-las. | expression_value |
| DEFAULT in VALUES | o valor padrão da colunaUm valor padrão literal é copiado para a linha. | default_keyword_filled |
| DEFAULT in VALUES without a literal default | NULLNão há valor para copiar. | default_keyword_null |
| REPLACE and INSERT IGNORE | linhas simplesUm dump tem uma linha por chave, então as linhas são as mesmas. | replace_as_insert |
| types IntoSQL doesn't know | TEXTO tipo text aceita qualquer valor; mude o tipo depois da carga. | unknown_type |
| values that don't fit their column | NULLUm dump danificado ou escrito à mão pode conter valores que a coluna não aceita; eles viram NULL para que o resto carregue. | invalid_value_null |
| unreadable geometries | NULLBytes que não são uma geometria não podem ser guardados como uma. | bad_geometry |
| CREATE SEQUENCE (MariaDB) | não criadoO SQLite não tem sequências. | sequence_not_converted |
| VECTOR(n) (MariaDB 11.7+) | TEXT com os floats como array JSONO SQLite não tem tipo vector; um array JSON mantém cada float. | type_replaced |
Carregue o script no SQLite
O script cria as tabelas, copia as linhas e depois adiciona chaves, índices e chaves estrangeiras, então carrega rápido e para no primeiro erro.
sqlite3 -bail mydb.sqlite < mariadb.sqlite.sqlAs chaves estrangeiras são declaradas em cada tabela e as linhas carregam com a verificação de chaves estrangeiras desligada. Depois o script lista cada linha que aponta para uma linha que não existe, em vez de falhar no meio do caminho.
Para um dump grande, carregue em um arquivo novo em um disco local. O script carrega tudo em uma transação com a sincronização desligada, então roda na velocidade do disco, e uma carga interrompida no meio não deixa tabelas incompletas.
A linha de comando carrega o arquivo direto em um banco SQLite, sem escrever um script. É grátis.
Gere o dump do MariaDB para o melhor resultado
O conversor lê o que o dump contém. Estas opções mantêm mais dos seus dados nele:
- --default-character-set=utf8mb4 mantém emoji e outros caracteres de 4 bytes, que um dump em utf8mb3 perde antes de o conversor vê-lo.
- --hex-blob escreve as colunas binárias e os valores VECTOR em hexadecimal, o que sobrevive à cópia entre sistemas.
- --routines --triggers --events adicionam esses objetos ao dump, para que o relatório possa listá-los.
O que não é convertido
Visões, gatilhos, procedimentos armazenados, funções e eventos são escritos na linguagem própria do MariaDB. Eles aparecem no relatório pelo nome, nunca são descartados em silêncio, para que você possa reescrevê-los para o SQLite.
Perguntas sobre MariaDB para SQLite
Não encontrou a resposta? Escreva para nós pela página de contato e uma pessoa responde. Página de contato
Meu dump é enviado?
Não. O conversor roda no seu navegador e lê o dump do seu disco em partes, então ele nunca sai do seu computador. O app para desktop e a linha de comando também convertem no seu computador.
Qual o tamanho máximo do dump?
O conversor nunca guarda o dump inteiro na memória: ele lê o arquivo duas vezes, por intervalos, e escreve o script à medida que avança. Dumps de vários gigabytes são convertidos no navegador, no app para desktop e com a linha de comando.
De quais versões do MariaDB o dump pode vir?
Dumps do mariadb-dump e do mysqldump no MariaDB 10.3 ao 12, com um INSERT por tabela ou um por linha. Cada dump de teste vem do MariaDB 10.11, 11.4 e 11.8 e é comparado com a origem célula por célula.
As colunas UUID, INET6, JSON e VECTOR são mantidas?
Colunas UUID e INET viram text, JSON text, e VECTOR um array JSON dos seus floats. Datas zero viram NULL e o relatório as conta.
Os valores de AUTO_INCREMENT e as sequências são mantidos?
Uma coluna AUTO_INCREMENT que é toda a chave primária da tabela vira INTEGER PRIMARY KEY AUTOINCREMENT e continua depois do maior id. O SQLite não tem sequências, então elas aparecem no relatório.
E os procedimentos armazenados e gatilhos?
Eles aparecem no relatório pelo nome e não são convertidos, porque cada banco de dados os escreve na sua própria linguagem.
Em quais versões do SQLite o script carrega?
SQLite 3.31 e posteriores. Cada dump de teste carrega no 3.31 e no 3.54 e para no primeiro erro se algo der errado.