SQLite
| Тип | встраиваемая реляционная СУБД |
|---|---|
| Автор | Д. Ричард Хипп |
| Первый выпуск | август 2000 |
| Язык | C |
| Лицензия | общественное достояние (public domain) |
| Хранение | одна база — один кроссплатформенный файл |
| Транзакции | ACID, режимы журнала отката и WAL |
| Распространённость | более триллиона баз данных в эксплуатации |
SQLite — реляционная СУБД, которая работает не как отдельный сервер, а как библиотека внутри приложения. Вся база данных — таблицы, индексы, представления — хранится в одном обычном файле, который можно скопировать, отправить по почте или положить в репозиторий. SQLite поддерживает почти полный SQL и полноценные транзакции ACID, не требует установки, настройки и администрирования.[1]
По оценке разработчиков, SQLite — самая распространённая база данных в мире: она есть в каждом смартфоне на Android и iOS, во всех основных браузерах, в macOS и Windows, в автомобилях, самолётах и телевизорах; одновременно используется более триллиона баз SQLite.[2]
История
Д. Ричард Хипп начал разработку весной 2000 года, работая по контракту с General Dynamics над программой для эсминцев ВМС США: система на базе Informix переставала работать, когда сервер базы данных был недоступен. Хипп решил сделать базу данных, которой не нужен сервер вовсе. Первая версия вышла в августе 2000 года. Код передан в общественное достояние — его можно использовать без каких-либо лицензионных условий. Проект развивает небольшая команда, финансируемая консорциумом компаний; код покрыт тестами, объём которых в сотни раз превышает объём самой библиотеки. Библиотека Конгресса США рекомендует SQLite как формат долговременного хранения данных.[6]
Использование
sqlite3 app.db
CREATE TABLE notes (
id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
body TEXT,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
) STRICT;
INSERT INTO notes (title, body) VALUES ('Купить', 'молоко');
SELECT * FROM notes WHERE title LIKE 'Куп%';
.tables
.schema notes
В Python модуль sqlite3 входит в стандартную библиотеку:
import sqlite3
with sqlite3.connect("app.db") as conn:
conn.execute("PRAGMA journal_mode=WAL")
conn.execute("INSERT INTO notes (title, body) VALUES (?, ?)", ("Идея", "написать статью"))
for row in conn.execute("SELECT id, title FROM notes ORDER BY id DESC LIMIT 5"):
print(row)
Параметры подставляются через ?, а не склейкой строк — это защищает от SQL-инъекций.
Особенности
- Динамическая типизация. Тип связан со значением, а не со столбцом: в столбец
INTEGERможно записать строку. С версии 3.37 (2021) таблицыSTRICTпроверяют типы строго.[5] - Одна запись за раз. Читать базу могут многие процессы одновременно, но записывающая транзакция в каждый момент одна. В режиме WAL читатели не блокируют писателя и наоборот, что резко повышает конкурентность.[4]
- Устройство хранения. Таблицы и индексы — B-деревья внутри файла; формат файла стабилен и кроссплатформен с 2004 года.
- Расширения. Полнотекстовый поиск FTS5, функции JSON, R-деревья для геоданных, векторный поиск через сторонние расширения (sqlite-vec).
- Ограничения SQL. Изменение схемы (
ALTER TABLE) ограничено, нет хранимых процедур и управления пользователями — всё это обычно не нужно встраиваемой базе.
Когда подходит
Сами разработчики формулируют: SQLite конкурирует не с клиент-серверными СУБД, а с функцией fopen().[3]
| Подходит | Лучше клиент-серверная СУБД |
|---|---|
| мобильные и настольные приложения | много серверов приложений пишут в одну базу |
| встраиваемые устройства и IoT | высокая конкурентность записи |
| формат файлов приложения | база больше нескольких терабайт |
| сайты с умеренной нагрузкой на одном сервере | нужны тонкие права доступа и сетевые подключения |
| тесты, прототипы, анализ данных, кэши | репликация и отказоустойчивость средствами СУБД |
Сайт с сотнями тысяч посещений в день вполне может работать на SQLite, если записи не слишком часты, а приложение работает на одном сервере.
SQLite на сервере
В 2020-х SQLite стали активнее использовать в серверных приложениях: благодаря отсутствию сетевых задержек простые запросы выполняются за микросекунды. Экосистема закрывает недостающее:
- Litestream непрерывно копирует изменения базы в объектное хранилище S3 для восстановления на момент времени;[7]
- LiteFS и libSQL/Turso добавляют репликацию на несколько узлов;
- фреймворки вроде Rails 8 предлагают SQLite как вариант для продакшена.
Рекомендуемые настройки для сервера: режим WAL, PRAGMA busy_timeout (ждать вместо мгновенной ошибки при блокировке), PRAGMA synchronous=NORMAL в режиме WAL, PRAGMA foreign_keys=ON — проверка внешних ключей по умолчанию выключена.
Сравнение с PostgreSQL
PostgreSQL — полноценный сервер с богатой системой типов, параллельной записью, ролями, репликацией и расширениями; SQLite — минимализм и нулевое администрирование. Частая практика — SQLite для разработки и тестов, PostgreSQL в продакшене, — но различия в диалектах SQL и типизации иногда дают ошибки, которые проявляются только в продакшене. Надёжнее использовать одну и ту же СУБД во всех окружениях.