SQLite vs PostgreSQL vs MySQL vs NoSQL: сравнение баз данных

Обновлено:

Выбор базы данных — одно из самых дорогих для изменения архитектурных решений. «Лучшей» базы не существует: 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, если:

  • данные документные и сильно вложенные;
  • структура данных нестабильна;
  • нужен горизонтальный шардинг.

Бэкап для каждой базы данных

У каждой СУБД свой инструмент для согласованной копии:

Запускать бэкап по расписанию — задача 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.