← На главную

Прагма SQLite edition 2026 включит все правильные настройки разом

15.07.2026 22:42 · hackernews

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

Первая: внешние ключи (FOREIGN KEY) по умолчанию игнорируются. В любом другом RDBMS ты не сможешь создать запись без валидного пользователя или удалить пользователя, не удалив его посты. В SQLite такой запрос просто пройдёт. Усугубляется это тем, что SQLite любит переиспользовать ROWID. Если Боб создал аккаунт, написал пост, потом удалился, а Алиса зарегистрировалась — она получит тот же ID, что был у Боба. И унаследует его старый пост. Без ошибок, всё выглядит нормально. Лечится прагмой: PRAGMA foreign_keys = ON;. Если бы она была включена, DELETE провалился бы с ошибкой.

Вторая: колонки могут хранить что угодно. Типизация в SQLite «гибкая». Если колонка объявлена как INTEGER, ты всё равно можешь записать туда текст — он просто останется текстом, если его нельзя преобразовать в число. Автор вспоминает случай, когда в код случайно писали строки '1' и '0' вместо чисел 1 и 0. Разбираться было весело. Решение есть — строгие таблицы (STRICT). Но нет глобального переключателя, нужно писать STRICT вручную для каждой таблицы. Критики говорят, что это ломает возможность задавать кастомные имена типов вроде DATETIME или COLOR. Автор предлагает добавить CREATE DOMAIN по стандарту SQL99 — это решило бы проблему и с типами, и с проверками.

Третья: SQLITE_BUSY при конкурентной записи. Несколько читателей работать могут, но пишет только один. Если два процесса пытаются записать одновременно, второй сразу получает ошибку, а не ждёт. Автор писал ретрай-лупы, чтобы это обойти. Лечится прагмой PRAGMA busy_timeout = 5000; — тогда SQLite будет пытаться захватить блокировку до 5 секунд.

Четвёртая: производительность. По умолчанию выключен Write-Ahead Log (WAL). Включение PRAGMA journal_mode = WAL; с PRAGMA synchronous = NORMAL; даёт огромный прирост скорости записи без риска повредить данные.

Автор предлагает решение: сделать «издания» (editions) по аналогии с Rust. Достаточно одной прагмы вроде PRAGMA edition = 2026;, чтобы разом включить все правильные настройки: foreign_keys, busy_timeout, WAL, synchronous = NORMAL и строгие таблицы по умолчанию. И чтобы со временем можно было выпускать новые издания — например, edition = 2034 могло бы включить WAL2. Это сохранит обратную совместимость, но позволит двигаться дальше.

Читать оригинал →