
Пропозиція для SQLite: одна прагма, щоб виправити чотири поганих типових налаштування
Автор блогу стверджує, що типові налаштування SQLite — вимкнені зовнішні ключі, відсутність строгої типізації, миттєві помилки SQLITE_BUSY і робота без WAL — має замінити прагма edition у стилі Rust.
SQLite є галузевим стандартом для локального зберігання даних і, на відміну від традиційного сервера баз даних, є RDBMS у вигляді бібліотеки, а не окремого процесу, що зберігає застосунки самодостатніми. Однак у дописі, опублікованому 15 липня, розробник Mort стверджує, що його типові налаштування неправильні, і що рушієві потрібен шлях розвитку без ламання старого програмного забезпечення.
Чотири налаштування, які автор хотів би змінити
Перше — обмеження зовнішніх ключів, які SQLite ігнорує, доки не виконати PRAGMA foreign_keys = ON. Автор каже, що це єдина відома йому RDBMS, яка не перевіряє їх типово, і що схильність SQLite повторно використовувати значення ROWID погіршує наслідки: висяче посилання може непомітно вказувати на неправильний рядок. У його прикладі допис, залишений видаленим користувачем, успадковує новий обліковий запис, який випадково отримує той самий ID.
Друге — типізація. Колонка, оголошена як INTEGER, використовує INTEGER affinity, тож схожий на число текст зберігається як число, а все інше — як є; тому колонка тривалості може містити рядок «Way too long, I mean come on». Це виправляють STRICT-таблиці — вставлення TEXT у колонку INTEGER дає помилку — але прагми, яка робить строгими всі таблиці, немає, тож ключове слово доводиться додавати вручну.
Третє — конкурентність: SQLite дозволяє багато читачів, але лише одного письменника, і типово другий процес, який намагається взяти блокування на запис, одразу отримує помилку SQLITE_BUSY. Автор віддає перевагу очікуванню блокування до тайм-ауту (PRAGMA busy_timeout = 5000) — налаштуванню, яке, за його словами, він додав лише після реальних збоїв.
Продуктивність і пропозиція edition
Четверте — продуктивність. Журнал випереджального запису типово вимкнено; увімкнення PRAGMA journal_mode = WAL різко прискорює записи в більшості випадків, а разом із PRAGMA synchronous = NORMAL дозволяє значно скоротити кількість синхронізацій із диском без ризику пошкодження даних. За деталями допис відсилає до статті Сільвена Керкура про оптимізацію SQLite для серверів.
Щоб виправити все це без порушення зворотної сумісності — звичного обґрунтування збереження поточних типових значень — автор пропонує одну суперпрагму: PRAGMA edition = 2026, яка буде псевдонімом для foreign_keys = ON, busy_timeout = 5000, journal_mode = WAL і synchronous = NORMAL, а STRICT-таблиці стануть типовим варіантом.
Ідею позичено з editions у Rust. Автор аргументує, що edition за роком кращий за щось на кшталт «use strict» у JavaScript, бо розумні типові налаштування змінюються з часом: якщо колись у головну гілку потрапить формат журналу на кшталт WAL2, PRAGMA edition = 2034 його увімкне. Читач у коментарі зауважує, що SQL 99 уже визначає псевдоніми типів через CREATE DOMAIN.
SiTech — веброзробка з підтримкою AI
Створюємо швидкі та сучасні сайти й інтегруємо AI у бізнес-процеси. Маєте проєкт чи запитання? Із задоволенням допоможемо.