Выбор базы данных — одно из самых дорогих для изменения архитектурных решений. «Лучшей» базы не существует: SQLite, PostgreSQL, MySQL и NoSQL (на примере MongoDB) создавались под разные задачи. Ниже — как устроена каждая, где она сильна и слаба, сводная таблица и практические рекомендации, включая бэкапы.
SQLite: база данных в одном файле
SQLite — самая необычная из четырёх. Она не клиент-серверная: нет отдельного процесса СУБД, сетевого подключения, пользователей и прав. Вся база — один файл, который приложение читает напрямую через библиотеку.
Как работает SQLite
import sqlite3
# Файл создаётся автоматически
conn = sqlite3.connect('/data/myapp.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
cursor.execute('INSERT INTO users (name, email) VALUES (?, ?)',
('Алексей', 'alex@example.com'))
conn.commit()
SQLite поддерживает большую часть стандарта SQL, ACID-транзакции, триггеры и представления. Это полноценная реляционная база, просто встроенная в приложение. Подробнее — в статье что такое SQLite.
Производительность SQLite
На простых чтениях SQLite очень быстра: запрос выполняется в процессе приложения, без сети. Ограничение — запись: в каждый момент пишет только одно соединение. В режиме WAL читатели не блокируют писателя и наоборот, но писатель всё равно один.
Практические ограничения:
- запись из многих процессов одновременно выстраивается в очередь;
- база живёт на одной машине — горизонтально её не масштабировать;
- один запрос выполняется в одном потоке.
Когда SQLite — правильный выбор
SQLite работает на миллиардах устройств: она встроена в Android и iOS, в браузеры Chrome и Firefox, в Python.
Используйте SQLite для:
- мобильных и десктопных приложений;
- прототипов и MVP на одном сервере;
- тестов;
- CLI-утилит и инструментов;
- PocketBase и похожих бэкендов на SQLite;
- небольших сайтов и блогов.
Вокруг SQLite выросла экосистема для сетевых и распределённых сценариев: Cloudflare D1, Turso и libSQL, LiteFS, Litestream.
Когда пора переходить на PostgreSQL: когда в базу должны писать несколько серверов, когда очередь на запись начинает влиять на время ответа или когда нужны возможности, которых в SQLite нет.
PostgreSQL: стандарт де-факто для продакшна
PostgreSQL — одна из самых функциональных open-source СУБД. Под этим названием проект развивается с 1996 года, мажорные версии выходят ежегодно.
Архитектура PostgreSQL
PostgreSQL — клиент-серверная СУБД. Главный процесс (postmaster) принимает подключения и запускает отдельный процесс на каждого клиента. Надёжность обеспечивает журнал предзаписи (WAL), конкурентный доступ — MVCC.
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
attributes JSONB,
tags TEXT[],
price NUMERIC(10, 2),
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Фильтрация по JSONB
SELECT name, attributes->>'color' AS color
FROM products
WHERE attributes @> '{"category": "electronics"}'
AND price < 5000
ORDER BY created_at DESC;
-- Полнотекстовый поиск с русской морфологией
SELECT * FROM products
WHERE to_tsvector('russian', name) @@ plainto_tsquery('russian', 'ноутбук');
Возможности PostgreSQL
- JSONB — бинарный JSON с индексами (для многих задач заменяет документную БД);
- массивы, hstore, ltree, uuid, диапазонные типы;
- полнотекстовый поиск со словарями — для многих проектов без отдельного поискового движка;
- партиционирование таблиц;
- Row-Level Security (на ней построена авторизация в Supabase);
- потоковая и логическая репликация;
- расширения: PostGIS (геоданные), TimescaleDB (временные ряды), pgvector (векторный поиск);
- Foreign Data Wrappers — запросы к внешним источникам.
pgvector сделал PostgreSQL популярным выбором для AI-приложений: эмбеддинги хранятся и ищутся рядом с остальными данными, без отдельного векторного хранилища.
Производительность PostgreSQL
PostgreSQL хорошо справляется со сложными запросами: JOIN, агрегации, оконные функции, полнотекстовый поиск. Для тяжёлой аналитики по огромным таблицам он уступает колоночным базам вроде ClickHouse или DuckDB. При большом числе подключений нужен пулер (PgBouncer и т. п.), а чтение масштабируется репликами.
Когда выбирать PostgreSQL
PostgreSQL — разумный выбор по умолчанию для большинства новых серверных проектов:
- веб-приложения и API;
- SaaS с многопользовательским доступом;
- e-commerce и финансовые системы;
- геоданные (PostGIS);
- AI-приложения с векторным поиском (pgvector);
- проекты, которые могут сильно вырасти.
MySQL: проверенный ветеран веб-разработки
MySQL — один из самых распространённых серверов баз данных. На нём работают WordPress и множество CMS, его предлагает почти любой хостинг. MariaDB — форк MySQL со своими доработками.
Архитектура MySQL
MySQL использует подключаемые движки хранения. InnoDB — основной движок с транзакциями и ACID. MyISAM — устаревший движок без транзакций, для новых таблиц его не используйте.
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT,
author_id INT UNSIGNED,
published_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_author (author_id),
FULLTEXT INDEX ft_title_content (title, content)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
SELECT * FROM articles
WHERE MATCH(title, content) AGAINST ('база данных' IN BOOLEAN MODE);
Когда MySQL имеет смысл
- проект уже на MySQL — мигрировать ради миграции незачем;
- WordPress, Drupal, Laravel-проекты с MySQL по умолчанию;
- хостинг, где из коробки есть только MySQL;
- команда хорошо знает MySQL;
- нагрузка в основном на чтение и масштабируется репликами.
Для нового проекта без особых требований PostgreSQL обычно удобнее: богаче типы данных, ближе к стандарту SQL, больше расширений.
MySQL vs PostgreSQL: ключевые различия
| Параметр | MySQL | PostgreSQL | |---|---|---| | JSON | Тип JSON, индексы через генерируемые колонки | JSONB с GIN-индексами | | Полнотекстовый поиск | FULLTEXT-индексы | tsvector/tsquery, словари и морфология | | Расширения | Ограниченно | PostGIS, pgvector, TimescaleDB и др. | | Синтаксис | Больше отступлений от стандарта | Ближе к стандарту SQL | | Аналитические запросы | Слабее | Сильнее | | Репликация | Зрелая source/replica, Group Replication | Потоковая и логическая | | Лицензия | GPL + коммерческая (Oracle) | PostgreSQL License (свободная) |
NoSQL (MongoDB): документная база данных
MongoDB — самый известный представитель NoSQL, поэтому сравниваем его. Обо всех типах NoSQL — в статье что такое NoSQL, о самой MongoDB — в статье что такое MongoDB и когда её использовать.
Архитектура MongoDB
MongoDB хранит данные в BSON-документах (бинарный JSON) внутри коллекций. Жёсткой схемы нет: документы в одной коллекции могут иметь разные поля (при желании схему можно валидировать).
const db = client.db('myapp');
const users = db.collection('users');
await users.insertOne({
name: 'Алексей',
email: 'alex@example.com',
profile: {
age: 28,
city: 'Москва',
interests: ['программирование', 'кино']
},
orders: [
{ orderId: 'ORD-001', total: 2500, status: 'delivered' }
],
createdAt: new Date()
});
const result = await users.find({
'profile.city': 'Москва',
'profile.age': { $gte: 25, $lte: 35 }
}).sort({ createdAt: -1 }).limit(10).toArray();
const stats = await users.aggregate([
{ $match: { 'profile.city': 'Москва' } },
{ $group: { _id: '$profile.age', count: { $sum: 1 } } },
{ $sort: { count: -1 } }
]).toArray();
Когда MongoDB выигрывает
- Данные естественно вложенные: профиль со списками адресов, настроек и истории — в MongoDB один документ, в PostgreSQL несколько таблиц.
- Структура данных часто меняется: новое поле не требует
ALTER TABLE. - Нужно горизонтальное масштабирование шардингом из коробки.
Когда MongoDB проигрывает
- Сложные связи между сущностями: вместо
JOIN—$lookup, который сложнее писать и оптимизировать. - Транзакции между многими документами: поддерживаются с версии 4.0, но для финансовой логики реляционная модель обычно проще.
- Отчёты и аналитика: агрегационный pipeline многословнее, чем SQL с
GROUP BYи оконными функциями.
Сводная таблица
| Параметр | SQLite | PostgreSQL | MySQL | MongoDB |
|---|---|---|---|---|
| Тип | Встроенная | Клиент-серверная | Клиент-серверная | Клиент-серверная |
| Модель данных | Реляционная | Реляционная | Реляционная | Документная |
| Схема и типы | Гибкая типизация, STRICT-таблицы | Строгая | Строгая | Гибкая, валидация опционально |
| Масштабирование | Одна машина | Вертикальное + реплики | Вертикальное + реплики | Шардинг |
| Транзакции | ACID | ACID | ACID (InnoDB) | Атомарность документа; многодокументные транзакции с 4.0 |
| Конкурентная запись | Один писатель | Высокая (MVCC) | Высокая (InnoDB) | Высокая |
| JSON | JSON-функции | JSONB с индексами | Тип JSON | Нативно |
| Полнотекстовый поиск | FTS5 | Встроенный, со словарями | FULLTEXT | Текстовые индексы |
| Геоданные | SpatiaLite | PostGIS | Spatial-типы | Гео-индексы |
| Векторный поиск | Расширения (sqlite-vec) | pgvector | Тип VECTOR в новых версиях | В Atlas (Vector Search) |
| Лицензия | Public Domain | PostgreSQL License | GPL + коммерческая | SSPL |
| Бэкап | .backup, VACUUM INTO | pg_dump, физический бэкап + WAL | mysqldump, физические копии | mongodump, снимки дисков |
| Типичный выбор для | Embedded, MVP, edge | Большинства серверных задач | WordPress и MySQL-проектов | Документных данных с гибкой схемой |
Managed-версии PostgreSQL и MySQL есть и у крупных российских облаков.
Практические рекомендации
Используйте SQLite, если:
- это мобильное или десктопное приложение;
- один сервер, один процесс и предсказуемая запись;
- нужен быстрый прототип;
- используете PocketBase.
Используйте PostgreSQL, если:
- это новый серверный проект без особых требований к другой БД;
- нужны транзакции, сложные запросы, геоданные;
- строите AI-приложение с векторным поиском;
- хотите гибкость JSON внутри реляционной модели.
Используйте MySQL, если:
- проект уже на MySQL;
- это WordPress, Drupal или похожая CMS;
- хостинг предоставляет только MySQL.
Используйте MongoDB, если:
- данные документные и сильно вложенные;
- структура данных нестабильна;
- нужен горизонтальный шардинг.
Бэкап для каждой базы данных
У каждой СУБД свой инструмент для согласованной копии:
- SQLite —
.backupилиVACUUM INTO, а неcpживого файла: см. как сделать бэкап SQLite. - PostgreSQL —
pg_dump(логический дамп без остановки сервера) или физический бэкап с архивом WAL: см. pg_dump по cron в S3. - MySQL —
mysqldump --single-transactionдля InnoDB: см. mysqldump: автоматизация и ротация. - MongoDB —
mongodumpили снимки дисков.
Запускать бэкап по расписанию — задача cron, systemd-таймера или CI. Хранить готовые файлы с историей версий можно в dbsend: он принимает файлы SQLite и DuckDB, plain SQL-дампы PostgreSQL и MySQL, а остальные файлы — как произвольные, без разбора содержимого. dbsend не подключается к вашему серверу: дамп вы создаёте сами и загружаете через CLI.
SQLite — CLI сам делает согласованную копию через VACUUM INTO:
dbsend backup /data/database.db -d "$DBSEND_SQLITE_ID" -e sqlite
PostgreSQL (бэкап PostgreSQL в dbsend):
pg_dump --format=plain "$DATABASE_URL" > /tmp/postgres.sql
dbsend backup /tmp/postgres.sql -d "$DBSEND_POSTGRES_ID" -e postgresql_dump -l "nightly"
MySQL — пароль берётся из ~/.my.cnf с правами 600, а не из командной строки:
mysqldump --single-transaction --routines --triggers --events "$MYSQL_DATABASE" > /tmp/mysql.sql
dbsend backup /tmp/mysql.sql -d "$DBSEND_MYSQL_ID" -e mysql_dump -l "nightly"
Для MongoDB отдельного движка в dbsend нет. Архив mongodump можно хранить только как произвольный файл: dbsend проверит контрольную сумму, но не будет разбирать содержимое и строить diff.
mongodump --uri "$MONGODB_URI" --archive=/tmp/mongodb.archive --gzip
dbsend backup /tmp/mongodb.archive -d "$DBSEND_FILES_ID" -e generic_file
Частые вопросы
Что лучше для стартапа: SQLite или PostgreSQL?
Для стартапа на одном сервере SQLite (например, через PocketBase) работает хорошо и почти не требует DevOps. Когда понадобятся несколько серверов приложения, интенсивная конкурентная запись или возможности PostgreSQL — переходите. Переезд выполним, но не бесплатен: различаются типы данных, функции дат, автоинкремент и поведение при нарушении типов, поэтому схему и часть запросов придётся адаптировать.
Стоит ли использовать MySQL для нового проекта?
Если нет особых причин, PostgreSQL обычно удобнее: JSONB, массивы, расширения вроде pgvector и PostGIS, свободная лицензия. MySQL оправдан, если проект уже на нём, вы используете MySQL-ориентированную CMS или у команды глубокий опыт с MySQL.
Правда ли, что PostgreSQL медленнее MySQL?
Это представление сложилось давно и для современных версий в общем виде неверно. Результат зависит от нагрузки: на одних сценариях быстрее одна СУБД, на других — другая. Для большинства проектов важнее правильные индексы, запросы и настройки, чем выбор между этими двумя базами.
Можно ли держать SQLite и PostgreSQL на одном сервере?
Да, они не конфликтуют. Но если сервер PostgreSQL уже есть, обычно проще хранить все данные приложения в нём. SQLite на продакшне имеет смысл, когда она — единственная база приложения (как в PocketBase) или выполняет отдельную локальную роль (кэш, очередь, данные инструмента).
Когда MongoDB лучше PostgreSQL с JSONB?
MongoDB удобнее, если данные глубоко вложенные, структура постоянно меняется и нужен встроенный шардинг. PostgreSQL с JSONB лучше, если нужны транзакции между сущностями, данные частично реляционные и важны SQL-отчёты.
Что такое ACID и почему это важно?
ACID — четыре свойства надёжных транзакций: Atomicity (транзакция выполняется целиком или откатывается), Consistency (данные остаются в корректном состоянии), Isolation (параллельные транзакции не мешают друг другу), Durability (после COMMIT данные переживают сбой). SQLite, PostgreSQL и MySQL с InnoDB гарантируют ACID. В MongoDB атомарны операции над одним документом, а транзакции между документами доступны с версии 4.0.



