SQLite
SQLite
SQLite — это встраиваемая (embedded) реляционная СУБД, которая живёт внутри твоей программы как обычная библиотека и хранит всю базу данных в одном файле на диске. Без отдельного серверного процесса, без сети, без администрирования — просто файл и SQL.
История
2000 год, США, D. Richard Hipp (Дуайн Ричард Хипп). Работает подрядчиком на General Dynamics по контракту с ВМС США — делает управляющий софт для эсминцев. Задача: программа не должна падать, если под ней внезапно упала база данных. Решение прямолинейное: убрать саму идею внешней базы. Хипп пишет маленькую библиотеку на C, которая читает и пишет SQL прямо в файл. Никакого сервера — некому падать. Первую публичную версию SQLite 1.0 выпускает в августе 2000 года и сразу отправляет в public domain — то есть отказывается от авторских прав вообще. Это одна из очень немногих серьёзных программ в мире с таким статусом.
2004 — SQLite 3. Полная переработка формата файла. Всё, что мы сегодня называем «SQLite», — это ветка 3.x. Формат стабилен более 20 лет: файл, созданный в 2004 году, откроется в свежей версии, и наоборот. Разработчики публично обещали держать обратную совместимость минимум до 2050 года.
2010 — WAL (Write-Ahead Logging). Появился новый режим журналирования. До этого при записи блокировалась вся база — читатели ждали. С WAL читатели больше не ждут писателя, а писатель не ждёт читателей. Радикально ускорило SQLite в приложениях с одновременным чтением и записью — про WAL подробнее в разделе «Как это работает».
2018 — SQLite Consortium. Небольшой закрытый клуб компаний, которые платят за то, чтобы иметь приоритетную линию поддержки и влиять на roadmap: Adobe, Bentley Systems, Bloomberg, Expensify, Mozilla и другие. При этом сам код по-прежнему public domain, и никто не может его «приватизировать».
Текущий статус (2026). SQLite развивают три инженера в маленькой компании Hwaci в Северной Каролине во главе с самим Хиппом. Актуальная линия — SQLite 3.4x. Тестовое покрытие — сотни тысяч тестов, миллиарды прогонов, показатель покрытия кода около 100% по MC/DC (Modified Condition / Decision Coverage — самый жёсткий стандарт, применяемый в авиации). Это, вероятно, самая тщательно протестированная кодовая база в мире среди свободно доступных.
Что это такое
SQLite — это библиотека размером примерно 700 килобайт, которую твоя программа линкует как обычный код. Внутри — SQL-движок: парсер, оптимизатор, виртуальная машина, работающая с B-tree на диске. Ты вызываешь функцию sqlite3_exec(db, "SELECT ..."), она сама читает нужные страницы из файла и возвращает результат. Никакого TCP-соединения, никаких настроек порта, никакого systemctl start.
SQLite vs PostgreSQL (или MySQL). PostgreSQL — это отдельный серверный процесс (обычно на UNIX-сокете или порту 5432), к которому клиенты подключаются по сети. У него есть роли, аутентификация, репликация, отдельные конфиги (postgresql.conf, pg_hba.conf), администратор. SQLite всего этого лишён по дизайну: одна библиотека, один файл, один процесс, который её использует. PostgreSQL нужен, когда с базой работают одновременно сотни клиентов с разных машин. SQLite нужен, когда база встроена в одну программу и живёт вместе с ней.
SQLite vs файл JSON/CSV. Многие начинающие пишут: «зачем мне БД, я просто буду хранить в JSON». Пока файл маленький — работает. Но: чтобы найти одну запись из миллиона, JSON нужно распарсить целиком; при аварийной записи (пропало питание в момент write) — файл превращается в мусор; двум процессам параллельно писать в него нельзя. SQLite решает всё это из коробки: индексы, транзакции с ACID-гарантиями (о них ниже), блокировки. И при этом остаётся одним файлом, который ты можешь скопировать cp и переслать по почте.
«Самая распространённая БД в мире». Не преувеличение, а официальное самоопределение с sqlite.org. Дословно: «SQLite is likely used more than all other database engines combined» — «SQLite, вероятно, используется чаще всех остальных СУБД вместе взятых». Основание: она встроена во все Android- и iOS-смартфоны (каждое приложение хранит свои данные в SQLite), во все основные браузеры (Chrome, Firefox, Safari — история, закладки, cookies), в macOS, Windows 10+, множество мессенджеров (iMessage, WhatsApp — переписка лежит в SQLite-файлах), в бортовые компьютеры Airbus A350, в саму систему сборки firmware в самолётах. Общее число активных инсталляций — по оценке самого проекта — измеряется триллионами.
Аналогии из жизни
Тетрадка вместо офиса.
PostgreSQL — это офис с секретарём, регламентом входа-выхода, ключом-картой и системой прав. Ты приходишь, показываешь пропуск, тебе выдают документ. SQLite — это тетрадка у тебя в кармане. Открыл, записал, закрыл, положил обратно. Никакой бюрократии.
Где ломается: если в этой тетрадке одновременно должны писать двести человек — офис таки нужен. Тетрадку не размножить; и хотя SQLite умеет много читателей одновременно, писатель в конкретный момент времени только один. Как только конкурентная запись становится массовой — аналогия ломается, и это буквально основной сигнал «пора на PostgreSQL».
Zip-архив с документами.
Ты хранишь проект в одном .zip-файле: перекинул на флешку — перекинулся весь проект целиком, никаких зависимостей. База SQLite — такой же самодостаточный «архив»: mydata.db содержит всю схему, все таблицы, все индексы; хочешь бэкап — просто cp mydata.db backup.db.
Где ломается: zip — статичен, ты его целиком распаковываешь и потом целиком собираешь заново. SQLite-файл живой: ты открываешь его как БД и читаешь/пишешь конкретные страницы, не трогая остальное. Ещё: если во время cp идёт активная запись, ты можешь скопировать неконсистентный снимок — для «горячего» бэкапа надо использовать команду .backup в CLI или sqlite3 backup API, а не голый cp.
Микроволновка vs ресторанная кухня.
Микроволновка — включил в розетку и грей. Она у каждого дома. Она НЕ приготовит стейк на 100 гостей — не для этого. Ресторанная кухня приготовит, но её нужно спроектировать, нанять поваров, платить аренду. SQLite — микроволновка мира БД: включаешь и она работает.
Где ломается: микроволновкой нельзя пожарить, а SQLite при этом делает почти всё, что делают «большие» СУБД: транзакции, индексы, VIEW, триггеры, оконные функции, JSON, полнотекстовый поиск (модуль FTS5). Так что аналогия недооценивает SQLite — по функциональности она ближе к «настоящей плите на одного», просто без официантов и метрдотеля.
Как это работает
Файл = база. Вся база данных — это один файл, обычно с расширением .db, .sqlite или .sqlite3 (расширение любое, движок определяет тип по «магическому» началу файла — первые 16 байт всегда SQLite format 3\0). Внутри файл разбит на страницы одинакового размера, по умолчанию 4096 байт (настраивается от 512 до 65536).
B-tree. Каждая таблица — это B-tree (сбалансированное дерево страниц), хранящееся прямо в файле. Индекс — тоже B-tree, только ключ там не rowid, а значение проиндексированной колонки. Когда ты пишешь SELECT * FROM users WHERE email='...', оптимизатор смотрит: есть индекс по email — идёт по нему, нашёл rowid, за одну-две страницы достал строку из основной таблицы. Нет индекса — линейный проход по всем страницам таблицы. Ровно та же логика, что в «больших» СУБД.
Транзакции и ACID. SQLite полностью реализует ACID (Atomicity, Consistency, Isolation, Durability — атомарность, согласованность, изоляция, долговечность). Это значит: либо транзакция применилась целиком, либо не применилась вовсе; после COMMIT данные гарантированно на диске (в режиме synchronous=FULL, который по умолчанию); одновременные транзакции видят согласованную картину. Если посреди транзакции упало питание — при следующем открытии SQLite откатит незавершённое.
Rollback journal vs WAL. Есть два основных режима журналирования, определяющих, как обеспечивается atomicity.
Классический — rollback journal (журнал отката). Перед изменением страниц в основном файле SQLite копирует их «как было» в отдельный файл mydata.db-journal. Если транзакция успешна — журнал удаляется. Если упало — при открытии SQLite видит журнал, восстанавливает старые страницы и как будто ничего не было. Минус: во время записи вся база блокируется для читателей.
Современный (с 2010 года) — WAL, Write-Ahead Log. Всё наоборот: новые данные пишутся в отдельный файл mydata.db-wal, а основной файл остаётся нетронутым, пока не произойдёт checkpoint (перенос накопленных изменений из WAL в основной файл). Читатели работают со старой версией из основного файла + актуальной поверх из WAL и не блокируют писателя. Писатель тоже не блокирует читателей. Именно WAL сделал SQLite пригодным для приложений, где чтения и записи идут одновременно (мобильные приложения, встроенные системы).
Один писатель за раз. Даже в WAL-режиме одновременно писать в SQLite может только один поток/процесс. Если второй пришёл — он ждёт. Это фундаментальное ограничение: при высокой конкурентной записи SQLite упирается в этот потолок. Практически: до нескольких тысяч записей в секунду с одного писателя — не проблема, дальше начинается очередь.
Flexible typing (гибкая типизация). Одна из странностей SQLite. В большинстве СУБД тип колонки — жёсткое ограничение: объявил INTEGER — букву туда не запишешь. В SQLite до недавнего времени типы были рекомендательными: колонка объявлена INTEGER, но реально в неё можно было записать строку — движок пробовал сконвертировать, не смог — запоминал как есть. Это называется «type affinity» (сродство типа). С версии 3.37 (2021) появились STRICT-таблицы — если объявить CREATE TABLE ... STRICT, будет как в обычной СУБД: строго по типу. Но по умолчанию — всё ещё гибко. Плюс: SQLite прощает грязные данные. Минус: удивляешься, когда в поле «сумма» находишь "abc".
Мини-схема того, что лежит на диске при активной работе:
mydata.db ← основной файл: заголовок + страницы (B-tree таблиц и индексов)
mydata.db-wal ← write-ahead log (в WAL-режиме)
mydata.db-shm ← shared memory, координация между процессами
mydata.db-journal ← rollback journal (только в классическом режиме)
Где встречается в обычной жизни
- Твой смартфон. На iPhone и Android почти каждое приложение хранит свои данные в SQLite-файле в своей «песочнице». Открой на Mac
~/Library/Messages/chat.db— это переписка iMessage, лежит в SQLite. WhatsApp —msgstore.db. Telegram — тоже SQLite для локального кэша. - Браузер. Firefox:
places.sqlite— история,cookies.sqlite,formhistory.sqlite. Chrome:History,Cookies,Login Data— все без расширения, но внутри SQLite. - Настройки macOS/Windows. Многие системные компоненты хранят состояние в SQLite-файлах — например, Spotlight, iCloud, Photos.app.
- Плагины IDE и редакторов. VS Code хранит историю и настройки расширений в SQLite. JetBrains IDE — тоже часто.
- Игры. Многие однопользовательские игры сохраняют прогресс в SQLite: удобно, атомарно, не портится при вылете.
Где встречается в IT и бизнесе
- Мобильная разработка. Стандарт де-факто для локального хранилища на iOS (через Core Data или GRDB) и Android (через Room или прямой API). Оффлайн-first приложения — синхронизируются с сервером, но между синхронизациями работают с локальной SQLite.
- Прошивки и IoT. Роутеры, «умные» колонки, автомобильная электроника, часть авиационного бортового ПО (Airbus A350). Компактность, отсутствие сервера и жёсткий ACID делают SQLite идеальной для «прошью и забуду».
- Аналитика и разовые выгрузки. Классический сценарий: свалил в SQLite CSV-выгрузки из разных источников, написал
SELECT ... JOIN ...и получил отчёт. Быстрее, чем Excel; проще, чем PostgreSQL; удобнее, чем pandas для сложных сравнений. - Тесты. В веб-приложениях (Django, Rails, Laravel) для юнит-тестов часто используют SQLite вместо продакшн-БД — тесты запускаются в разы быстрее, потому что база создаётся в памяти (
:memory:). - Кэш и очереди для маленьких сервисов. Простые фоновые задачи, локальный кэш, лёгкие бэкенды — SQLite позволяет обойтись без Redis и PostgreSQL, пока нагрузка не выросла.
SQLite как формат обмена данными
Хипп открыто продвигает идею, что SQLite — не только БД, но и формат файла общего назначения, альтернатива XML, JSON и ZIP. Аргумент: файл SQLite самодостаточен, содержит структуру и данные, поддерживается на всех платформах, из него легко читать выборочные части, не загружая всё в память. Многие приложения именно так и делают — например, файлы формата Anki (карточки для запоминания) внутри — SQLite; проекты Fossil (система контроля версий самого Хиппа) хранят весь репозиторий в SQLite-файле.
Кто пользуется
Быстрее перечислить, кто НЕ пользуется. Официальный список известных пользователей на sqlite.org:
- Apple — во всей экосистеме, от iOS до macOS.
- Google — Android, Chrome, часть внутренних инструментов.
- Microsoft — Windows 10/11, Skype, часть Office.
- Meta (Facebook, WhatsApp, Instagram) — локальные хранилища во всех мобильных клиентах.
- Airbus — бортовые системы A350.
- Adobe — часть продуктов (Photoshop, Lightroom для кэша).
- Bloomberg, Bentley, Expensify, Mozilla — члены SQLite Consortium.
Масштаб: по оценке самого проекта, число экземпляров SQLite «в дикой природе» — более триллиона, и это, вероятно, самая тиражируемая программа в истории.
Альтернативы и конкуренты
- DuckDB. Молодой (первый релиз 2019) «SQLite для аналитики»: тоже embedded, тоже один файл, но колоночное хранение и заточен под OLAP-запросы над большими объёмами. Плюсы: в разы быстрее SQLite на аналитических запросах, отличная работа с Parquet и pandas. Минусы: не для транзакционной работы, менее зрелый.
- PostgreSQL. Плюсы: настоящая многопользовательская СУБД, богатейший SQL-диалект, репликация, JSONB, полнотекстовый поиск на высоком уровне, огромная экосистема расширений. Минусы: нужен отдельный сервер, администрирование, ресурсы; избыточен для встраивания в одиночное приложение.
- MySQL / MariaDB. Плюсы: широко распространены, простая репликация, много готовых хостингов. Минусы: тот же класс, что PostgreSQL, — не встраиваются; строгость и семантика уступают PostgreSQL.
- LevelDB / RocksDB. Embedded, но key-value (без SQL), от Google и Meta соответственно. Плюсы: очень быстрые на записи, используются в блокчейнах и очередях. Минусы: нет SQL, нет вторичных индексов, нужно самому строить запросы кодом.
Когда НЕ стоит использовать
- Много одновременных писателей с разных машин. SQLite — библиотека в одном процессе; чтобы несколько машин писали в один файл, придётся класть его на сетевую файловую систему (NFS, SMB), а официальная документация прямо предупреждает: не делай так. Блокировки на сетевых ФС работают ненадёжно, файл легко повредить. Нужно много писателей — берёшь PostgreSQL или MySQL.
- Данные объёмом десятки терабайт с интенсивной записью. Формально SQLite поддерживает файлы до 281 терабайта (лимит из документации), но практически на таких объёмах любой запрос упрётся в диск и потоки. Это уже задачи для распределённых систем — ClickHouse, Postgres с шардированием, Cassandra.
- Сценарий с ролями и правами. SQLite не знает, кто ты. Все, у кого есть доступ к файлу на уровне ОС, могут делать с ним что угодно. Нужна авторизация на уровне БД (роли, GRANT/REVOKE) — только клиент-серверная СУБД.
Связанные понятия
- ACID — набор гарантий транзакций (атомарность, согласованность, изоляция, долговечность), которые полностью выполняет SQLite.
- WAL (Write-Ahead Log) — режим журналирования, при котором новые изменения сначала пишутся в отдельный файл, а читатели не блокируют писателя.
- B-tree — сбалансированное дерево, стандартная структура данных для индексов и таблиц во всех классических реляционных СУБД.
- SQL — декларативный язык запросов; SQLite поддерживает большую часть стандарта SQL-92 плюс расширения.
- Embedded database (встраиваемая БД) — класс СУБД, которые работают внутри процесса приложения без отдельного сервера; SQLite, DuckDB, LevelDB.
- ORM (Object-Relational Mapping) — библиотека, которая транслирует объекты языка программирования в SQL-запросы; поверх SQLite часто используют SQLAlchemy (Python), GRDB (Swift), Room (Android).
Литература и источники
- Официальная документация — sqlite.org/docs.html (en). Написано лично Хиппом, суховато, но исчерпывающе. Обязательные страницы: «About SQLite», «When To Use SQLite», «WAL», «File Format».
- «The Definitive Guide to SQLite» — Grant Allen, Mike Owens, 2010, Apress, en. Классический учебник, отчасти устарел по деталям API, но по концепциям — актуален.
- «Using SQLite» — Jay A. Kreibich, 2010, O'Reilly, en. Более практичный компаньон к предыдущей книге.
- Wikipedia — статьи «SQLite» на русском и английском. Хорошая отправная точка по истории, форматам и статусу.
- Блог Хиппа и записи докладов — на sqlite.org есть раздел с текстами его выступлений (например, «SQLite: Past, Present, and Future»). Живой стиль, много контекста, почему что сделано именно так.
- Исходный код — sqlite.org/src (Fossil-репозиторий). Весь код в открытом доступе, около 150 тысяч строк C.
Где встретилось у меня
Вчера при аудите лидов внутреннего CRM-проекта пришлось лазить в две SQLite-базы на VPS: делал выгрузки, сверял с приёмкой колл-центра, дедуплицировал записи. Удобно ровно тем, что «база» — это один файл, который можно scp себе на Mac и там спокойно ковырять sqlite3 в терминале, не боясь уронить продакшн.
Краткое резюме
- SQLite — встраиваемая (embedded) реляционная СУБД в виде маленькой C-библиотеки; вся база живёт в одном файле, серверного процесса нет.
- Придумал D. Richard Hipp в 2000 году, для управляющего софта эсминцев ВМС США; код в public domain до сих пор.
- Даёт полный ACID, поддерживает большую часть SQL, работает быстро; в режиме WAL читатели не блокируют писателя.
- Фундаментальное ограничение — один писатель одновременно; при массовой конкурентной записи или доступе с многих машин пора на PostgreSQL/MySQL.
- Вероятно, самая распространённая СУБД в мире: смартфоны, браузеры, мессенджеры, бортовые системы; счёт активных инсталляций — на триллионы.