Две базы — две разные философии
И SQLite, и PostgreSQL говорят на SQL, хранят реляционные данные и оба могут стать движком для реального приложения. Но дальше начинаются принципиальные отличия SQLite и PostgreSQL — они создавались под совершенно разные задачи.
- SQLite — это библиотека. Она работает прямо внутри процесса вашего приложения и читает обычный файл
.dbс диска. Никакого сервера, портов и настройки пользователей. - PostgreSQL — это сервер. Он запускается отдельным процессом, слушает сетевой порт, а приложение подключается к нему как клиент.
Практически все остальные различия — конкурентная запись, развёртывание, строгость типов, производительность — растут именно из этого архитектурного разделения. Держите его в голове по ходу статьи.
Архитектура: встроенная библиотека vs клиент-сервер
Открыть базу SQLite — это буквально открыть файл:
Никакого демона запускать не нужно, никакой pg_hba.conf править не приходится, и порт открывать тоже не надо. Приложение просто подгружает библиотеку SQLite, открывает notes.db — и запросы поехали. Деплой сводится к «скопируй файл».
С Postgres всё устроено иначе:
# Запустите сервер (один раз, от имени администратора):
sudo systemctl start postgresql
# Затем подключитесь из вашего приложения:
psql -h localhost -U alice -d mydb
Ваше приложение общается с отдельным процессом — обычно по TCP, иногда через Unix-сокет. Этот дополнительный слой стоит вам времени на настройку и одного round-trip соединения на каждый запрос, но взамен вы получаете доступ по сети, многопользовательскую аутентификацию и настоящую конкурентную запись.
Конкурентность — главный аргумент
Чаще всего именно этот пункт ставит точку в споре. SQLite сериализует записи: в любой момент времени блокировку на файл базы держит только один писатель, а остальные ждут своей очереди. Чтение может идти параллельно (особенно в WAL-режиме), а вот запись — строго по одному.
Postgres использует MVCC (multi-version concurrency control) и блокировки на уровне строк. Десятки транзакций могут писать в разные строки одновременно, не мешая друг другу.
На практике это выглядит так:
- Блог, где 50 читателей в секунду и один автор, который изредка что-то публикует? SQLite справится.
- Оформление заказа в интернет-магазине, где сотни пользователей одновременно списывают товар со склада? Только Postgres.
- Локальный кэш в мобильном приложении? SQLite, без вариантов.
- Многотенантный SaaS-бэкенд с десятками фоновых воркеров? Postgres.
Режим WAL (PRAGMA journal_mode = WAL;) заметно улучшает ситуацию с конкурентной записью в SQLite — читатели больше не блокируют писателей. Но правило «один писатель за раз» он не отменяет.
Типизация: вольная против строгой
Postgres строгий. Столбец, объявленный как INTEGER, не примет строку — и точка:
-- Postgres
CREATE TABLE t (n INTEGER);
INSERT INTO t (n) VALUES ('не число');
-- ОШИБКА: некорректный синтаксис ввода для типа integer
SQLite по умолчанию работает с так называемым type affinity — это скорее рекомендация, чем строгое правило. Поэтому такой INSERT спокойно проходит:
Human
Строка преспокойно лежит в колонке INTEGER — SQLite сохранил её как текст. Такая гибкость заложена в движок намеренно: для быстрых прототипов это удобно, а вот для схем, которым жить годами, — мина замедленного действия.
В свежих версиях SQLite (3.37+) появились таблицы STRICT — они ведут себя ближе к Postgres:
Если вы начинаете новый проект на SQLite — включайте STRICT. Это сразу убирает целый класс сюрпризов вроде «почему у меня в числовой колонке лежит строка».
Возможности: что есть в каждой СУБД
В PostgreSQL почти всего больше: типы данных (массивы, диапазоны, геометрические, сетевые, пользовательские enum'ы), процедурные языки (PL/pgSQL, PL/Python), полнотекстовый поиск с ранжированием, материализованные представления, партиционирование таблиц, репликация, ролевая модель безопасности, а ещё богатая экосистема расширений (PostGIS, TimescaleDB, pgvector).
SQLite — это про основы плюс несколько приятных фишек под свой масштаб: функции для JSON, полнотекстовый поиск через FTS5, R-Tree индексы, оконные функции, CTE, вычисляемые колонки. Чего здесь нет — так это всего, что подразумевает сервер: пользователей, ролей, репликации, сетевого доступа.
Простая шпаргалка для выбора:
- Нужны GIS, векторный поиск или репликация? Берите Postgres.
- Нужно встроить базу прямо в iOS-приложение? SQLite.
- Нужно и то и другое? Многие команды разрабатывают и тестируют на SQLite, а в продакшене разворачивают Postgres — но такой микс может больно укусить на различиях в синтаксисе (об этом ниже).
Различия в синтаксисе, с которыми вы реально столкнётесь
Большая часть повседневного SQL у обеих СУБД совпадает. Расхождения собираются вокруг схемы, типов и нескольких встроенных функций:
-- Автоинкрементный первичный ключ
-- SQLite:
CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT);
-- Postgres:
CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT);
-- или, в современном Postgres:
CREATE TABLE users (id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT);
-- Текущая временная метка
-- SQLite: CURRENT_TIMESTAMP (возвращает текст)
-- Postgres: NOW() (возвращает timestamp)
-- Логический тип
-- SQLite: настоящего BOOLEAN нет; используйте INTEGER 0/1
-- Postgres: BOOLEAN со значениями TRUE/FALSE
Если разрабатываешь на SQLite, а деплоишь на Postgres, держи между собой и сырым SQL какую-нибудь ORM или инструмент миграций — иначе все эти различия неизбежно протекут в код приложения.
Производительность — без прикрас
«Быстрее» — вопрос постановки задачи. Если у тебя один процесс читает и делает небольшие записи, SQLite обогнать сложно: нет ни сетевого хопа, ни разбора протокола, ни клиентских подключений. На бенчмарках с одним клиентом и простыми запросами SQLite нередко опережает Postgres.
А вот когда появляются конкурентные писатели, большие датасеты с параллельным выполнением запросов или сложные планы, где раскрывается зрелый планировщик Postgres, — тут уже впереди Postgres. К тому же Postgres умеет вертикально масштабироваться (больше ядер, мощнее машина) так, как SQLite просто не задумывался.
Если коротко и честно: SQLite быстр там, где он на своём месте. Postgres быстр там, где он на своём месте. Выбирай по характеру нагрузки, а не по громким заголовкам бенчмарков.
Что выбрать: sqlite или postgresql — короткий гайд
Бери SQLite, когда:
- База живёт рядом с одним приложением — десктоп, мобильное, встроенное устройство, CLI-утилита.
- Записи идут из одного процесса или небольшого их числа.
- Хочется деплой без какой-либо конфигурации.
- Ты прототипируешь и думать хочется про схему, а не про инфраструктуру.
Бери Postgres, когда:
- В базу пишут несколько серверов приложений или воркеров.
- Нужен сетевой доступ для множества клиентов.
- Нужны продвинутые штуки: роли, репликация, GIS, кастомные типы, хранимые процедуры.
- База — это центральное надёжное хранилище продакшен-сервиса.
Типичный путь такой: стартуешь небольшой проект на SQLite, а на Postgres переезжаешь тогда (и если), когда профиль трафика этого реально потребует. Миграция с sqlite на postgresql — операция небесплатная, но хорошо изученная, и большинству проектов она вообще не понадобится.
Дальше: когда SQLite — правильный выбор
Сравнение выше даёт картину компромиссов. На следующей странице разберём положительную сторону вопроса подробнее — те сценарии, где SQLite не просто сойдёт, а действительно лучший инструмент, и тревожные звоночки, по которым понятно: ты из него вырос.
Часто задаваемые вопросы
В чём главное отличие SQLite от PostgreSQL?
SQLite — встраиваемая библиотека, которая работает с одним файлом прямо внутри процесса вашего приложения. PostgreSQL — это отдельный сервер, к которому подключаются по сети. Из этой одной архитектурной разницы вытекает практически всё остальное: конкурентность, способ деплоя, система типов и инструментарий.
SQLite быстрее, чем PostgreSQL?
Для чтения и небольших записей в рамках одного процесса — часто да: нет ни сетевых запросов, ни накладных расходов на клиент-серверный протокол. Но как только появляется много клиентов, которые одновременно пишут, PostgreSQL вырывается вперёд за счёт построчных блокировок и MVCC. «Быстрее» зависит не от движка, а от характера нагрузки.
Можно ли использовать SQLite в продакшене?
Да, если нагрузка подходящая. SQLite спокойно тянет сайты, десктопные приложения и встраиваемые устройства в проде. Граница — это конкурентная запись: если множество процессов должны писать одновременно, PostgreSQL делает это из коробки, а SQLite сериализует записи. Режим WAL немного помогает, но не снимает ограничение полностью.
Как мигрировать с SQLite на PostgreSQL?
Сначала выгрузите схему и данные через sqlite3 mydb.db .dump, потом подправьте SQL: AUTOINCREMENT меняется на SERIAL или GENERATED AS IDENTITY, имена типов другие, плюс надо вычистить специфические для SQLite вольности вроде «нестрогой» типизации. Большую часть рутины автоматизирует pgloader. Всё, что завязано на гибкие типы SQLite, скорее всего придётся переписать.