SQLite

Материал из llmdocs — справочник разработчика
Портал: Базы данных
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 и типизации иногда дают ошибки, которые проявляются только в продакшене. Надёжнее использовать одну и ту же СУБД во всех окружениях.

См. также

Источники

  1. SQLite — About SQLite
  2. SQLite — Most Widely Deployed and Used Database Engine
  3. SQLite — Appropriate Uses For SQLite
  4. SQLite — Write-Ahead Logging
  5. SQLite — STRICT Tables
  6. SQLite — Recommended Storage Format (Library of Congress)
  7. Litestream