Перейти к содержимому
Главная страница IntoSQL

Конвертация MariaDB в SQLite

Перетащите дамп из mariadb-dump, mysqldump, phpMyAdmin или Adminer в формате .sql или .sql.gz и скачайте скрипт SQLite с теми же таблицами, ключами, индексами и данными. Каждое значение, которое SQLite не может хранить как есть, и каждый объект, который он не переносит, указаны в отчете.

Ваш файл
sqlshop_2024_mariadb.sqlПример файла, 6,6 кБ
Ваша база данных

18 строк конвертировано, 8 исправлений, ни одна не отклонена

Показать

Таблицы в shop_2024_mariadb.sqlДамп MariaDB 11.8.9-MariaDB-ubu2404 · создан программой mariadb-dump · utf8mb4

  • customers8 строк3
    8 столбцов
    idINTEGER not null
    nameVARCHAR(100) not null
    emailVARCHAR(150) not null
    countryVARCHAR(2) not null
    is_activeINTEGER not null
    signed_upDATE
    created_atTIMESTAMP not null
    last_ipTEXT
  • orders10 строк5
    12 столбцов
    idINTEGER not null
    customer_idINTEGER not null
    statusTEXT not null
    totalDECIMAL(10,2) not null
    itemsINTEGER not null
    ordered_atDATETIME not null
    shipped_atDATETIME
    noteVARCHAR(255)
    order_refTEXT not null
    invoiceINTEGER not null
    detailsTEXT
    updated_atTIMESTAMP 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;

Исправления

  1. Столбец "id" таблицы customers беззнаковый, поэтому он стал INTEGER с проверкой, что значение не отрицательное.
  2. Столбец "signed_up" таблицы customers теперь допускает NULL: часть его значений нельзя было сохранить, и они записаны как NULL.
  3. Значение по умолчанию столбца "signed_up" таблицы customers, 0000‑00‑00, не является датой, которую принимает SQLite, поэтому у столбца его нет.
  4. Столбец "customer_id" таблицы orders беззнаковый, поэтому он стал INTEGER с проверкой, что значение не отрицательное.
  5. Столбец "id" таблицы orders беззнаковый, поэтому он стал INTEGER с проверкой, что значение не отрицательное.
  6. Столбец "items" таблицы orders беззнаковый, поэтому он стал INTEGER с проверкой, что значение не отрицательное.
  7. В 1 строке столбца "status" таблицы orders пустое значение, которое MySQL записывает вместо недопустимых; проверка значений его допускает.
  8. Столбец "updated_at" таблицы orders получает текущее время при каждом обновлении; в SQLite это делает триггер.

Требует проверки

  • Не создано последовательностей: 1; в SQLite их нет. Храните следующее значение в таблице, если оно нужно вашему приложению.
  • В "signed_up" таблицы customers 1 значение - нулевая или невозможная дата, например 0000‑00‑00; SQLite не может их хранить, поэтому записан NULL. Если эти даты что-то значат, замените их в источнике настоящими до создания дампа.
  • Значение по умолчанию столбца "invoice" таблицы orders нельзя записать для SQLite (a sequence), поэтому у столбца его нет. Добавьте значение по умолчанию вручную, если оно нужно новым строкам.
  • В "shipped_at" таблицы orders 1 значение - нулевая или невозможная дата, например 0000‑00‑00 00:00:00; SQLite не может их хранить, поэтому записан NULL. Если эти даты что-то значат, замените их в источнике настоящими до создания дампа.

Файл конвертируется на этом компьютере и никуда не загружается.

Другие примеры:

Что меняется при переходе с MariaDB на SQLite

Каждая строка - это правило, которое применяет конвертер, и строка отчета, которую он пишет, когда правило что-то меняет в ваших данных.

  • TINYINT(1), BOOL

    INTEGER со значениями как есть

    В SQLite нет логического типа; true и false - это целые 1 и 0, поэтому каждое значение сохраняет смысл.

  • UNSIGNED integers

    INTEGER с CHECK на неотрицательность; BIGINT UNSIGNED со значениями больше 2^63-1 становится TEXT

    Целые в SQLite 64-битные и знаковые. Проверка не пропускает отрицательные значения, как в MySQL; значения за пределами знакового диапазона хранятся как текст, чтобы ни одна цифра не потерялась.

    Строка отчета: unsigned_widened

  • ZEROFILL and display widths

    удаляется

    Дополнение нулями - это способ показа числа, а не его часть. Числа сохраняются; если дополнение важно, форматируйте их при чтении.

    Строка отчета: zerofill_dropped

  • FLOAT(M,D)

    REAL, без масштаба

    У чисел с плавающей точкой в SQLite нет фиксированного масштаба. Записанные значения копируются как есть.

    Строка отчета: float_scale_dropped

  • DECIMAL(p,s)

    DECIMAL(p,s) до 15 цифр; дальше TEXT

    SQLite хранит в числе около 15 значащих цифр. Более широкие десятичные числа хранятся как текст, чтобы каждая цифра осталась точной.

    Строка отчета: decimal_as_text

  • BIT(1), BIT(n)

    INTEGER со значением битов; BIT(64) как цифры в TEXT

    Битовое поле хранится как число, которое составляют его биты. Старший бит BIT(64) не помещается в знаковое целое, поэтому его число хранится как текст.

  • zero, partial or impossible dates (0000-00-00, 2024-02-30)

    NULL

    Функции дат в SQLite читают только настоящие календарные даты. Они становятся NULL, а отчет их подсчитывает, как и для любой другой базы данных.

    Строка отчета: invalid_date_null

  • NOT NULL columns with values that become NULL

    NOT NULL снимается

    Столбец, значения которого пришлось заменить на NULL, не может сохранить NOT NULL, иначе загрузка остановится.

    Строка отчета: not_null_relaxed

  • DEFAULT '0000-00-00'

    без значения по умолчанию

    Значение по умолчанию, которое не является настоящей датой, опускается, а не заменяется выдуманной.

    Строка отчета: zero_date_default

  • TIME

    TIME как текст в записи MySQL, включая длительности

    SQLite хранит время как текст, поэтому длительности больше суток или меньше нуля сохраняются точно.

  • YEAR

    INTEGER с CHECK диапазона

    В SQLite нет типа для года; проверка допускает те же значения, что и MySQL.

  • CHAR(n), VARCHAR(n)

    VARCHAR(n), без ограничения

    SQLite сохраняет объявленный тип для инструментов, но не ограничивает длину; значения те же, что возвращает MySQL.

  • DATETIME

    DATETIME как текст ISO 8601

    SQLite хранит даты как текст, который читают его функции дат.

  • TIMESTAMP

    TIMESTAMP как текст ISO 8601 в UTC; из пояса, указанного в дампе, или UTC, если он не указан

    TIMESTAMP - это момент времени, записанный в UTC. Дампы указывают пояс, в котором он записан (mysqldump пишет UTC); без этого значения читаются как UTC, и отчет это отмечает.

    Строка отчета: timestamp_zone_assumed

  • ENUM

    TEXT с CHECK значений

    Текст с проверкой хранит те же значения.

  • ENUM holding '' (MySQL's error value)

    пустое значение, которое допускает проверка

    MySQL записывает пустую строку, когда недопустимое значение попадает в ENUM в нестрогом режиме SQL. Такие строки сохраняются, и проверка их допускает.

    Строка отчета: enum_invalid_value

  • ENUM holding values outside its list

    без CHECK

    Значения, которых нет в списке, не прошли бы проверку, поэтому она не создается.

    Строка отчета: enum_check_skipped

  • SET

    TEXT в записи MySQL ('a,b')

    В SQLite нет массивов; текст тот же, что возвращает MySQL.

  • JSON

    TEXT

    Функции JSON в SQLite читают JSON из текста. Столбец, объявленный как JSON, превратил бы "123" в число, поэтому он TEXT.

  • NUL bytes in text

    сохраняется

    Текст в SQLite может содержать байт NUL, поэтому значение копируется как есть.

  • text that isn't valid in its character set

    неверные байты заменяются символом замены

    Текст в SQLite - это UTF-8; его функции неверно читают байты, которые им не являются.

    Строка отчета: invalid_utf8_replaced

  • text decoded twice (ñ)

    копируется как есть

    Дамп содержит именно эти символы, поэтому они копируются; отчет на них указывает.

    Строка отчета: mojibake_suspected

  • AUTO_INCREMENT

    INTEGER PRIMARY KEY AUTOINCREMENT, счетчик выставлен после скопированных id

    SQLite считает первичный ключ из одного целого столбца. AUTOINCREMENT не дает повторно использовать id, как в MySQL, а счетчик продолжается после наибольшего id или после AUTO_INCREMENT дампа, смотря что больше.

  • AUTO_INCREMENT on part of a key or outside one

    INTEGER без счетчика

    SQLite считает только столбец, который составляет весь первичный ключ, поэтому столбец сохраняет свои значения, а новым строкам нужны свои.

    Строка отчета: identity_without_counter

  • ON UPDATE CURRENT_TIMESTAMP

    триггер AFTER UPDATE

    Триггер записывает в столбец текущее время, когда строка меняется, а обновление не задало его, как это делает MySQL.

    Строка отчета: on_update_trigger

  • generated columns

    GENERATED ALWAYS AS, VIRTUAL или STORED, как в источнике

    SQLite 3.31 и новее вычисляет генерируемые столбцы теми же двумя способами.

  • generated columns with functions SQLite lacks

    обычный столбец

    Формула, которую нельзя записать для SQLite, оставляет обычный столбец и строку в отчете.

    Строка отчета: generated_not_translated

  • INVISIBLE columns

    обычные столбцы

    В SQLite нет невидимых столбцов.

    Строка отчета: invisible_column

  • CHECK constraints

    переводится, внутри CREATE TABLE

    SQLite принимает проверки только в CREATE TABLE.

  • CHECK constraints with functions SQLite lacks

    не создается

    Проверка, которую нельзя записать для SQLite, опускается и попадает в отчет.

    Строка отчета: check_skipped

  • CHECK ... NOT ENFORCED

    не создается

    MySQL хранит эти проверки, но не применяет их, поэтому строки могут их нарушать.

    Строка отчета: check_not_enforced

  • defaults with functions SQLite lacks

    без значения по умолчанию

    Значение по умолчанию, которое нельзя записать для SQLite, опускается и попадает в отчет.

    Строка отчета: default_not_translated

  • keys and indexes on a prefix, c(20)

    индекс по substr(c, 1, 20)

    SQLite индексирует выражения, поэтому индексируется тот же префикс, а уникальный префикс остается уникальным.

    Строка отчета: prefix_unique

  • FULLTEXT indexes

    не создается

    SQLite ищет по тексту через отдельные таблицы FTS5, которым нужны свои запросы.

    Строка отчета: fulltext_not_created

  • SPATIAL indexes

    не создается

    В SQLite нет пространственного индекса по столбцу.

    Строка отчета: spatial_index_not_created

  • functional indexes SQLite can't write

    не создается

    Индекс по выражению, которое нельзя записать для SQLite, опускается и попадает в отчет.

    Строка отчета: index_skipped

  • foreign keys

    в CREATE TABLE, загрузка без проверки, затем список через PRAGMA foreign_key_check

    SQLite принимает внешние ключи только в CREATE TABLE и проверяет их только при включенном PRAGMA foreign_keys. Строки загружаются без проверки, как из MySQL, а в конце скрипт перечисляет все строки без родителя.

  • foreign keys to columns without a unique key

    не создается

    SQLite требует уникальный ключ на столбцах, на которые ссылается внешний ключ; InnoDB - нет.

    Строка отчета: foreign_key_skipped

  • table, index and column names

    как в источнике; переименовываются, если отличаются только регистром или имя индекса повторяется

    Имена в SQLite не учитывают регистр, а имена индексов делят одно пространство имен на базу данных.

    Строка отчета: identifier_renamed

  • GEOMETRY, POINT, POLYGON...

    WKB в BLOB

    Стандартный формат well-known binary точно сохраняет каждую геометрию.

    Строка отчета: geometry_as_blob

  • INET4, INET6, UUID (MariaDB)

    TEXT

    В SQLite нет таких типов; текст тот же, что возвращает MariaDB.

  • BINARY, VARBINARY, BLOB

    BLOB

    Байты остаются байтами.

  • PARTITION BY

    одна таблица

    Строки те же.

    Строка отчета: partitions_dropped

  • WITH SYSTEM VERSIONING (MariaDB)

    таблица с текущими строками

    Дамп содержит только текущие строки.

    Строка отчета: system_versioning_dropped

  • MyISAM, MEMORY and other engines

    обычная таблица

    В SQLite один движок таблиц.

    Строка отчета: engine_dropped

  • dumps of several databases

    один файл, имя каждой таблицы начинается с имени ее базы

    Файл SQLite - это одна база данных, поэтому имя базы различает таблицы с одинаковыми именами.

    Строка отчета: databases_merged

  • views, triggers, procedures, functions and events

    перечисляются в отчете

    Их код написан на языке MySQL, поэтому они перечислены, чтобы вы создали их заново.

    Строка отчета: not_converted_objects

  • dumps without CREATE TABLE

    типы определяются по значениям

    Дамп, созданный с --no-create-info, содержит только строки, поэтому типы берутся из значений.

    Строка отчета: no_schema

  • geometries in a dump without CREATE TABLE

    WKB в BLOB

    Формат геометрии MySQL распознается по значениям и сохраняется как стандартный WKB.

    Строка отчета: geometry_as_blob

  • _ci collations

    точное сравнение

    SQLite сравнивает текст точно, если не указано иное, а его NOCASE приводит к одному регистру только буквы ASCII.

    Строка отчета: case_insensitive_collation

  • SET NAMES utf8 from utf8mb4 tables

    конвертируется с предупреждением

    mysqldump из MySQL 5.x по умолчанию пишет 3-байтовую utf8 и заменяет каждый эмодзи вопросительным знаком еще до того, как файл увидит какой-либо конвертер.

    Строка отчета: dump_lost_four_byte_chars

  • dumps without SET NAMES whose text isn't UTF-8

    читается как Latin-1 (Windows-1252)

    latin1 в MySQL - это Windows-1252, обычная кодировка таких дампов.

    Строка отчета: charset_guessed

  • sjis, cp932, gbk, big5 dumps

    читается как UTF-8, с предупреждением

    Эти кодировки пока не декодируются.

    Строка отчета: unsupported_charset

  • UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows

    вычисляются

    Некоторые программы дампа записывают значения как такие вызовы; они читаются как значения, которые возвращают, а в географическом WKT долгота ставится первой.

  • other expressions in rows

    NULL

    Конвертер, который не запускает базу данных, не может их вычислить.

    Строка отчета: expression_value

  • DEFAULT in VALUES

    значение столбца по умолчанию

    Литеральное значение по умолчанию копируется в строку.

    Строка отчета: default_keyword_filled

  • DEFAULT in VALUES without a literal default

    NULL

    Копировать нечего.

    Строка отчета: default_keyword_null

  • REPLACE and INSERT IGNORE

    обычные строки

    В дампе одна строка на ключ, поэтому строки те же.

    Строка отчета: replace_as_insert

  • types IntoSQL doesn't know

    TEXT

    Тип text вмещает любое значение; измените тип после загрузки.

    Строка отчета: unknown_type

  • values that don't fit their column

    NULL

    Поврежденный или написанный вручную дамп может содержать значения, которые столбец не вмещает; они становятся NULL, чтобы остальное загрузилось.

    Строка отчета: invalid_value_null

  • unreadable geometries

    NULL

    Байты, которые не являются геометрией, нельзя сохранить как геометрию.

    Строка отчета: bad_geometry

  • CREATE SEQUENCE (MariaDB)

    не создается

    В SQLite нет последовательностей.

    Строка отчета: sequence_not_converted

  • VECTOR(n) (MariaDB 11.7+)

    TEXT с числами float в виде массива JSON

    В SQLite нет векторного типа; массив JSON сохраняет каждое число float.

    Строка отчета: type_replaced

В MariaDBВ SQLiteСтрока отчета
TINYINT(1), BOOLINTEGER со значениями как естьВ SQLite нет логического типа; true и false - это целые 1 и 0, поэтому каждое значение сохраняет смысл.
UNSIGNED integersINTEGER с CHECK на неотрицательность; BIGINT UNSIGNED со значениями больше 2^63-1 становится TEXTЦелые в SQLite 64-битные и знаковые. Проверка не пропускает отрицательные значения, как в MySQL; значения за пределами знакового диапазона хранятся как текст, чтобы ни одна цифра не потерялась.unsigned_widened
ZEROFILL and display widthsудаляетсяДополнение нулями - это способ показа числа, а не его часть. Числа сохраняются; если дополнение важно, форматируйте их при чтении.zerofill_dropped
FLOAT(M,D)REAL, без масштабаУ чисел с плавающей точкой в SQLite нет фиксированного масштаба. Записанные значения копируются как есть.float_scale_dropped
DECIMAL(p,s)DECIMAL(p,s) до 15 цифр; дальше TEXTSQLite хранит в числе около 15 значащих цифр. Более широкие десятичные числа хранятся как текст, чтобы каждая цифра осталась точной.decimal_as_text
BIT(1), BIT(n)INTEGER со значением битов; BIT(64) как цифры в TEXTБитовое поле хранится как число, которое составляют его биты. Старший бит BIT(64) не помещается в знаковое целое, поэтому его число хранится как текст.
zero, partial or impossible dates (0000-00-00, 2024-02-30)NULLФункции дат в SQLite читают только настоящие календарные даты. Они становятся NULL, а отчет их подсчитывает, как и для любой другой базы данных.invalid_date_null
NOT NULL columns with values that become NULLNOT NULL снимаетсяСтолбец, значения которого пришлось заменить на NULL, не может сохранить NOT NULL, иначе загрузка остановится.not_null_relaxed
DEFAULT '0000-00-00'без значения по умолчаниюЗначение по умолчанию, которое не является настоящей датой, опускается, а не заменяется выдуманной.zero_date_default
TIMETIME как текст в записи MySQL, включая длительностиSQLite хранит время как текст, поэтому длительности больше суток или меньше нуля сохраняются точно.
YEARINTEGER с CHECK диапазонаВ SQLite нет типа для года; проверка допускает те же значения, что и MySQL.
CHAR(n), VARCHAR(n)VARCHAR(n), без ограниченияSQLite сохраняет объявленный тип для инструментов, но не ограничивает длину; значения те же, что возвращает MySQL.
DATETIMEDATETIME как текст ISO 8601SQLite хранит даты как текст, который читают его функции дат.
TIMESTAMPTIMESTAMP как текст ISO 8601 в UTC; из пояса, указанного в дампе, или UTC, если он не указанTIMESTAMP - это момент времени, записанный в UTC. Дампы указывают пояс, в котором он записан (mysqldump пишет UTC); без этого значения читаются как UTC, и отчет это отмечает.timestamp_zone_assumed
ENUMTEXT с CHECK значенийТекст с проверкой хранит те же значения.
ENUM holding '' (MySQL's error value)пустое значение, которое допускает проверкаMySQL записывает пустую строку, когда недопустимое значение попадает в ENUM в нестрогом режиме SQL. Такие строки сохраняются, и проверка их допускает.enum_invalid_value
ENUM holding values outside its listбез CHECKЗначения, которых нет в списке, не прошли бы проверку, поэтому она не создается.enum_check_skipped
SETTEXT в записи MySQL ('a,b')В SQLite нет массивов; текст тот же, что возвращает MySQL.
JSONTEXTФункции JSON в SQLite читают JSON из текста. Столбец, объявленный как JSON, превратил бы "123" в число, поэтому он TEXT.
NUL bytes in textсохраняетсяТекст в SQLite может содержать байт NUL, поэтому значение копируется как есть.
text that isn't valid in its character setневерные байты заменяются символом заменыТекст в SQLite - это UTF-8; его функции неверно читают байты, которые им не являются.invalid_utf8_replaced
text decoded twice (ñ)копируется как естьДамп содержит именно эти символы, поэтому они копируются; отчет на них указывает.mojibake_suspected
AUTO_INCREMENTINTEGER PRIMARY KEY AUTOINCREMENT, счетчик выставлен после скопированных idSQLite считает первичный ключ из одного целого столбца. AUTOINCREMENT не дает повторно использовать id, как в MySQL, а счетчик продолжается после наибольшего id или после AUTO_INCREMENT дампа, смотря что больше.
AUTO_INCREMENT on part of a key or outside oneINTEGER без счетчикаSQLite считает только столбец, который составляет весь первичный ключ, поэтому столбец сохраняет свои значения, а новым строкам нужны свои.identity_without_counter
ON UPDATE CURRENT_TIMESTAMPтриггер AFTER UPDATEТриггер записывает в столбец текущее время, когда строка меняется, а обновление не задало его, как это делает MySQL.on_update_trigger
generated columnsGENERATED ALWAYS AS, VIRTUAL или STORED, как в источникеSQLite 3.31 и новее вычисляет генерируемые столбцы теми же двумя способами.
generated columns with functions SQLite lacksобычный столбецФормула, которую нельзя записать для SQLite, оставляет обычный столбец и строку в отчете.generated_not_translated
INVISIBLE columnsобычные столбцыВ SQLite нет невидимых столбцов.invisible_column
CHECK constraintsпереводится, внутри CREATE TABLESQLite принимает проверки только в CREATE TABLE.
CHECK constraints with functions SQLite lacksне создаетсяПроверка, которую нельзя записать для SQLite, опускается и попадает в отчет.check_skipped
CHECK ... NOT ENFORCEDне создаетсяMySQL хранит эти проверки, но не применяет их, поэтому строки могут их нарушать.check_not_enforced
defaults with functions SQLite lacksбез значения по умолчаниюЗначение по умолчанию, которое нельзя записать для SQLite, опускается и попадает в отчет.default_not_translated
keys and indexes on a prefix, c(20)индекс по substr(c, 1, 20)SQLite индексирует выражения, поэтому индексируется тот же префикс, а уникальный префикс остается уникальным.prefix_unique
FULLTEXT indexesне создаетсяSQLite ищет по тексту через отдельные таблицы FTS5, которым нужны свои запросы.fulltext_not_created
SPATIAL indexesне создаетсяВ SQLite нет пространственного индекса по столбцу.spatial_index_not_created
functional indexes SQLite can't writeне создаетсяИндекс по выражению, которое нельзя записать для SQLite, опускается и попадает в отчет.index_skipped
foreign keysв CREATE TABLE, загрузка без проверки, затем список через PRAGMA foreign_key_checkSQLite принимает внешние ключи только в CREATE TABLE и проверяет их только при включенном PRAGMA foreign_keys. Строки загружаются без проверки, как из MySQL, а в конце скрипт перечисляет все строки без родителя.
foreign keys to columns without a unique keyне создаетсяSQLite требует уникальный ключ на столбцах, на которые ссылается внешний ключ; InnoDB - нет.foreign_key_skipped
table, index and column namesкак в источнике; переименовываются, если отличаются только регистром или имя индекса повторяетсяИмена в SQLite не учитывают регистр, а имена индексов делят одно пространство имен на базу данных.identifier_renamed
GEOMETRY, POINT, POLYGON...WKB в BLOBСтандартный формат well-known binary точно сохраняет каждую геометрию.geometry_as_blob
INET4, INET6, UUID (MariaDB)TEXTВ SQLite нет таких типов; текст тот же, что возвращает MariaDB.
BINARY, VARBINARY, BLOBBLOBБайты остаются байтами.
PARTITION BYодна таблицаСтроки те же.partitions_dropped
WITH SYSTEM VERSIONING (MariaDB)таблица с текущими строкамиДамп содержит только текущие строки.system_versioning_dropped
MyISAM, MEMORY and other enginesобычная таблицаВ SQLite один движок таблиц.engine_dropped
dumps of several databasesодин файл, имя каждой таблицы начинается с имени ее базыФайл SQLite - это одна база данных, поэтому имя базы различает таблицы с одинаковыми именами.databases_merged
views, triggers, procedures, functions and eventsперечисляются в отчетеИх код написан на языке MySQL, поэтому они перечислены, чтобы вы создали их заново.not_converted_objects
dumps without CREATE TABLEтипы определяются по значениямДамп, созданный с --no-create-info, содержит только строки, поэтому типы берутся из значений.no_schema
geometries in a dump without CREATE TABLEWKB в BLOBФормат геометрии MySQL распознается по значениям и сохраняется как стандартный WKB.geometry_as_blob
_ci collationsточное сравнениеSQLite сравнивает текст точно, если не указано иное, а его NOCASE приводит к одному регистру только буквы ASCII.case_insensitive_collation
SET NAMES utf8 from utf8mb4 tablesконвертируется с предупреждениемmysqldump из MySQL 5.x по умолчанию пишет 3-байтовую utf8 и заменяет каждый эмодзи вопросительным знаком еще до того, как файл увидит какой-либо конвертер.dump_lost_four_byte_chars
dumps without SET NAMES whose text isn't UTF-8читается как Latin-1 (Windows-1252)latin1 в MySQL - это Windows-1252, обычная кодировка таких дампов.charset_guessed
sjis, cp932, gbk, big5 dumpsчитается как UTF-8, с предупреждениемЭти кодировки пока не декодируются.unsupported_charset
UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rowsвычисляютсяНекоторые программы дампа записывают значения как такие вызовы; они читаются как значения, которые возвращают, а в географическом WKT долгота ставится первой.
other expressions in rowsNULLКонвертер, который не запускает базу данных, не может их вычислить.expression_value
DEFAULT in VALUESзначение столбца по умолчаниюЛитеральное значение по умолчанию копируется в строку.default_keyword_filled
DEFAULT in VALUES without a literal defaultNULLКопировать нечего.default_keyword_null
REPLACE and INSERT IGNOREобычные строкиВ дампе одна строка на ключ, поэтому строки те же.replace_as_insert
types IntoSQL doesn't knowTEXTТип text вмещает любое значение; измените тип после загрузки.unknown_type
values that don't fit their columnNULLПоврежденный или написанный вручную дамп может содержать значения, которые столбец не вмещает; они становятся NULL, чтобы остальное загрузилось.invalid_value_null
unreadable geometriesNULLБайты, которые не являются геометрией, нельзя сохранить как геометрию.bad_geometry
CREATE SEQUENCE (MariaDB)не создаетсяВ SQLite нет последовательностей.sequence_not_converted
VECTOR(n) (MariaDB 11.7+)TEXT с числами float в виде массива JSONВ SQLite нет векторного типа; массив JSON сохраняет каждое число float.type_replaced

Загрузите скрипт в SQLite

Скрипт создает таблицы, копирует строки, затем добавляет ключи, индексы и внешние ключи, поэтому загрузка идет быстро и останавливается на первой ошибке.

sqlite3 -bail mydb.sqlite < mariadb.sqlite.sql

Внешние ключи объявляются в каждой таблице, а строки загружаются с отключенной проверкой внешних ключей. Затем скрипт перечисляет все строки, которые ссылаются на несуществующие строки, а не прерывается на полпути.

Большой дамп загружайте в новый файл на локальном диске. Скрипт загружает все в одной транзакции с отключенной синхронизацией, поэтому работает со скоростью диска, а прерванная загрузка не оставляет неполных таблиц.

Командная строка загружает файл прямо в базу SQLite, без написания скрипта. Это бесплатно.

Как создать дамп MariaDB для лучшего результата

Конвертер читает то, что есть в дампе. Эти параметры сохраняют в нем больше ваших данных:

  • --default-character-set=utf8mb4 сохраняет эмодзи и другие 4-байтовые символы, которые дамп в utf8mb3 теряет еще до конвертера.
  • --hex-blob записывает двоичные столбцы и значения VECTOR в шестнадцатеричном виде, который не портится при копировании между системами.
  • --routines --triggers --events добавляют эти объекты в дамп, чтобы отчет мог их перечислить.

Что не конвертируется

Представления, триггеры, хранимые процедуры, функции и события написаны на собственном языке MariaDB. Они перечислены в отчете по имени и никогда не удаляются молча, чтобы вы могли переписать их для SQLite.

Вопросы о MariaDB в SQLite

Нет ответа на ваш вопрос? Напишите нам через страницу контактов, и вам ответит человек. Страница контактов

Мой дамп загружается на сервер?

Нет. Конвертер работает в вашем браузере и читает дамп с диска по частям, поэтому он никогда не покидает ваш компьютер. Приложение для компьютера и командная строка тоже конвертируют на вашем компьютере.

Насколько большим может быть дамп?

Конвертер никогда не держит весь дамп в памяти: он читает файл дважды, по диапазонам, и пишет скрипт по ходу чтения. Дампы в несколько гигабайт конвертируются в браузере, в приложении для компьютера и в командной строке.

Из каких версий MariaDB может быть дамп?

Дампы из mariadb-dump и mysqldump на MariaDB с 10.3 по 12, с одним INSERT на таблицу или одним на строку. Каждый тестовый дамп создан в MariaDB 10.11, 11.4 и 11.8 и сверен с источником ячейка за ячейкой.

Сохраняются ли столбцы UUID, INET6, JSON и VECTOR?

Столбцы UUID и INET становятся text, JSON - text, а VECTOR - массивом JSON из его чисел float. Нулевые даты становятся NULL, и отчет их подсчитывает.

Сохраняются ли значения AUTO_INCREMENT и последовательности?

Столбец AUTO_INCREMENT, который составляет весь первичный ключ таблицы, становится INTEGER PRIMARY KEY AUTOINCREMENT и продолжается после наибольшего id. В SQLite нет последовательностей, поэтому они попадают в отчет.

А хранимые процедуры и триггеры?

Они перечислены в отчете по имени и не конвертируются, потому что каждая база данных пишет их на своем языке.

На каких версиях SQLite загружается скрипт?

SQLite 3.31 и новее. Каждый тестовый дамп загружается на 3.31 и 3.54 и останавливается на первой ошибке, если что-то пойдет не так.