Back

Современные возможности SQLite, о которых вы могли не знать

Современные возможности SQLite, о которых вы могли не знать

Если вы до сих пор считаете SQLite легковесной базой данных, подходящей только для мобильных приложений или быстрых прототипов, то вы пропустили несколько лет содержательной разработки. SQLite активно поддерживается, обладает возможностями, сравнимыми с более тяжеловесными СУБД для многих задач, а теперь работает прямо в браузере. Вот что стоит знать.

Ключевые выводы

  • Хранилище JSONB предлагает компактный бинарный формат, который парсится быстрее текстового JSON, а JSON-выражения можно индексировать напрямую.
  • STRICT-таблицы привносят в SQLite реальный контроль типов, закрывая давний пробел по сравнению с такими СУБД, как PostgreSQL.
  • Конструкция RETURNING избавляет от необходимости делать дополнительный SELECT после операций INSERT, UPDATE или DELETE.
  • Официальная сборка SQLite WASM с персистентностью через OPFS делает браузерные базы данных практичным архитектурным решением.
  • Режим WAL улучшает параллелизм чтения/записи всего одной директивой PRAGMA.

Поддержка JSON и JSONB: больше, чем просто хранение текста

JSON-функции существуют в SQLite уже много лет, однако более свежее дополнение — поддержка JSONB, бинарного формата, который хранит документы более компактно и парсится быстрее, чем обычный текстовый JSON.

Когда вы используете jsonb() для хранения данных, SQLite избегает повторного парсинга текста при каждом чтении. Для нагрузок с преобладанием чтения и крупными JSON-полезными нагрузками это имеет значение.

CREATE TABLE events (
  id      INTEGER PRIMARY KEY,
  payload BLOB NOT NULL  -- store as JSONB
);

-- Insert using jsonb()
INSERT INTO events (payload)
VALUES (jsonb('{"user": {"id": 42}, "action": "login"}'));

-- Query with standard json_extract — works on JSONB columns too
SELECT json_extract(payload, '$.user.id') AS user_id
FROM events
WHERE json_extract(payload, '$.action') = 'login';

JSON-функции SQLite прозрачно принимают как текстовые JSON-значения, так и JSONB, поэтому вы можете продолжать использовать функции вроде json_extract() независимо от формата хранения.

Также можно индексировать JSON-выражения напрямую, что делает фильтрацию по вложенным полям быстрой без денормализации схемы:

CREATE INDEX idx_action ON events (json_extract(payload, '$.action'));

Когда использовать JSONB, а когда TEXT: используйте BLOB + jsonb(), если SQLite будет часто обрабатывать или запрашивать JSON-значение. Используйте TEXT, когда нужно сохранить исходную строку в точности в том виде, в каком она была вставлена.

⚠️ Замечание о версии: поддержка JSONB была добавлена в SQLite 3.45 (январь 2024). Перед использованием убедитесь в версии вашего рантайма.

STRICT-таблицы SQLite: реальный контроль типов

Гибкая типизация SQLite полезна, но может приводить к малозаметным ошибкам, когда столбец молча принимает значение неверного типа. STRICT-таблицы решают эту проблему, проверяя типы столбцов при вставке, аналогично поведению PostgreSQL.

CREATE TABLE users (
  id        INTEGER PRIMARY KEY,
  email     TEXT    NOT NULL,
  age       INTEGER NOT NULL
) STRICT;

Попробуйте вставить 'twenty-five' в столбец age, и SQLite отклонит операцию. STRICT-таблицы поддерживают пять разрешённых типов столбцов: INT, INTEGER, REAL, TEXT, BLOB, а также специальный тип ANY. Тип ANY возвращает столбец к обычной гибкой типизации SQLite, так что в одной таблице можно сочетать строгие и гибкие столбцы.

⚠️ Сначала проверьте версию: STRICT-таблицы требуют SQLite 3.37 или новее. Выполните SELECT sqlite_version();, чтобы убедиться.

Конструкция RETURNING: более чистые запросы на изменение данных

Если вам когда-либо приходилось вставлять строку и тут же запрашивать её, чтобы получить сгенерированный ID, то RETURNING устраняет этот лишний обход:

INSERT INTO orders (user_id, total)
VALUES (42, 99.99)
RETURNING id, created_at;

Это работает с INSERT, UPDATE и DELETE и особенно полезно в серверном JavaScript с библиотеками вроде better-sqlite3 или встроенного SQLite в Bun. RETURNING был добавлен в SQLite 3.35.

SQLite WASM: запуск SQLite прямо в браузере

Проект SQLite поставляет официальную сборку WebAssembly, которая запускает полноценный движок SQLite во вкладке браузера. В отличие от появившейся ранее sql.js, официальная сборка SQLite WASM поддерживает API Origin Private File System (OPFS) для постоянного файлового хранилища — это значит, что ваша база данных переживает обновления страницы без участия сервера.

Это открывает реальную архитектуру для фронтенд-разработки на SQLite:

  • Offline-first приложения, которые делают запросы локально, а синхронизируются позже
  • Клиентские инструменты аналитики или отчётности
  • Приложения на Electron и Tauri, которым нужна единая абстракция базы данных в разных окружениях
  • Браузерные инструменты разработчика с реальными возможностями выполнения запросов

OPFS описан на MDN как часть File System API, а гайд Google web.dev сообщает, что он поддерживается во всех основных браузерах. Некоторые конфигурации SQLite WASM на основе OPFS также требуют безопасного контекста (HTTPS), поддержки SharedArrayBuffer и соответствующих заголовков COOP/COEP — в зависимости от выбранной реализации VFS.

Режим WAL: лучший параллелизм без накладных расходов на настройку

Журналирование с упреждающей записью (write-ahead logging) позволяет читателям и писателям работать параллельно, не блокируя друг друга. Для приложений с одновременным чтением и записью, или там, где важна воспринимаемая задержка, режим WAL часто стоит включить:

PRAGMA journal_mode = WAL;

Эта единственная директива pragma может ощутимо улучшить производительность для local-first приложений, Electron-приложений и легковесных бэкенд-сервисов, где SQLite обрабатывает реальный трафик. Учтите, что режим WAL требует, чтобы файл базы данных находился на локальном диске — он ненадёжно работает поверх сетевых файловых систем.

Заключение

Современные возможности SQLite — JSONB, STRICT-таблицы, RETURNING, WASM с OPFS и режим WAL — в совокупности делают SQLite полноценным выбором для гораздо более широкого круга приложений, чем можно подумать исходя из его репутации. Проект активно развивается, и разрыв между SQLite и более тяжеловесными СУБД заметно сократился для нагрузок, не требующих масштабного параллелизма с несколькими писателями. Если вы давно не пересматривали возможности SQLite, сейчас самое время это сделать.

Часто задаваемые вопросы

Да, для многих типов нагрузок. SQLite хорошо справляется с трафиком, где преобладает чтение, и с малыми и средними объёмами записи, особенно при включённом режиме WAL. Лучше всего он работает для развёртываний на одном сервере или для local-first приложений. Для приложений, которым требуется несколько одновременных писателей на распределённых серверах, клиент-серверная СУБД вроде PostgreSQL по-прежнему остаётся более подходящим вариантом.

Выбирайте JSONB, когда SQLite будет часто обрабатывать или запрашивать JSON-значение, поскольку он избегает повторного парсинга при каждом чтении и хранит данные более компактно. Оставайтесь с TEXT, если вам нужно сохранить исходную строку в точности так, как она была записана, включая пробелы и порядок ключей — это важно для криптографических подписей или аудит-логов.

Нет. STRICT включается опционально для каждой таблицы, поэтому существующие таблицы продолжают использовать гибкую типизацию SQLite. Вы можете внедрять STRICT-таблицы в новых схемах или постепенно мигрировать конкретные таблицы. Просто убедитесь, что у вас SQLite 3.37 или новее, прежде чем добавлять ключевое слово STRICT в любую инструкцию CREATE TABLE.

Производительность близка, но не идентична. WASM-сборка работает медленнее нативного SQLite из-за накладных расходов WebAssembly и того, что доступ к файлам через OPFS менее прямой, чем нативный дисковый ввод-вывод. Для многих умеренных клиентских нагрузок разница приемлема, но крупные наборы данных и тяжёлые аналитические запросы всё ещё могут заметно замедляться.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay