«SQL или NoSQL?» — частый вопрос при проектировании системы. Правильный ответ зависит от задачи. Разберём, когда что использовать, без религиозных споров.
Что такое SQL-базы
SQL (реляционные) базы данных хранят данные в таблицах с фиксированной схемой. Строгие отношения, транзакции, мощный язык запросов.
Примеры: PostgreSQL, MySQL, SQLite, Oracle, MS SQL Server
Сильные стороны:
- ACID-транзакции (атомарность, согласованность, изоляция, долговечность)
- Мощные JOIN для связанных данных
- Строгая схема — данные всегда валидны
- Зрелость — 50 лет опыта, огромная экосистема
- SQL — универсальный язык, знают все
Типы NoSQL баз данных
Документные (Document)
Хранят JSON/BSON-документы без фиксированной схемы.
MongoDB, CouchDB, Firestore
{
"_id": "user123",
"name": "Алиса",
"address": {
"city": "Москва",
"street": "Арбат 10"
},
"orders": [
{"amount": 1500, "date": "2026-03-01"},
{"amount": 3200, "date": "2026-03-15"}
]
}
Когда: гибкая или часто меняющаяся схема, вложенные данные, каталоги товаров.
Ключ-значение (Key-Value)
Простейшая модель: ключ → значение.
Redis, DynamoDB, Memcached
SET session:user123 '{"token": "abc", "expires": 1234567890}'
GET session:user123
SET product:42:views 1547 EX 3600
INCR product:42:views
Когда: кеш, сессии, счётчики, rate limiting, pub/sub. Redis — первый выбор для кеширования.
Колоночные (Column-Family)
Данные хранятся по столбцам, не по строкам. Оптимизированы для аналитических запросов.
Apache Cassandra, HBase, ClickHouse
Когда: IoT, логи, time-series, аналитика петабайт данных, запись миллионов событий в секунду.
Графовые (Graph)
Данные — узлы и рёбра. Оптимизированы для обхода связей.
Neo4j, Amazon Neptune
Когда: социальные сети, системы рекомендаций, граф зависимостей, fraud detection.
Сравнение: SQL vs NoSQL
| SQL | NoSQL | |
|---|---|---|
| Схема | Фиксированная | Гибкая / без схемы |
| Транзакции | ✅ ACID | Зависит (Redis: нет, MongoDB 4+: есть) |
| JOIN | ✅ Мощные | ❌ Обычно нет |
| Масштабирование | Вертикальное (+ read replicas) | Горизонтальное (шардинг) |
| Язык запросов | SQL (стандарт) | Специфичный для БД |
| Гибкость схемы | Низкая | Высокая |
| Консистентность | Сильная | Eventual consistency (часто) |
| Матurity | Очень высокая | Зависит от БД |
CAP-теорема
Распределённая система не может одновременно гарантировать все три:
- Consistency (согласованность) — все узлы видят одни данные
- Availability (доступность) — каждый запрос получает ответ
- Partition tolerance (устойчивость к разделению) — работает при сбоях сети
PostgreSQL: CP (консистентность + устойчивость к разделению) Cassandra: AP (доступность + устойчивость, eventual consistency) Redis: CP (при кластерном режиме)
Когда выбирать SQL (PostgreSQL)
✅ Транзакционные данные: финансы, заказы, инвентарь — нужна атомарность.
-- Перевод денег: или оба UPDATE прошли, или ни одного
BEGIN;
UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
COMMIT;
✅ Сложные отчёты: нужны JOIN многих таблиц, оконные функции, группировки.
✅ Фиксированная схема: данные структурированы, редко меняются.
✅ Стартапы и MVP: не знаете заранее паттерн запросов — SQL гибче.
✅ PostgreSQL + JSONB: получаете SQL + гибкость документной БД в одном месте.
Когда выбирать NoSQL
✅ Высокая нагрузка на запись (Redis/Cassandra):
Cassandra: 1 млн writes/sec на кластере без проблем
PostgreSQL: ~50-100k writes/sec на хорошем железе
✅ Кеш и сессии (Redis):
# Кеш результата тяжёлого SQL-запроса
cache.set('top_products', json.dumps(result), ex=3600)
✅ Документы с переменной структурой (MongoDB):
- Каталог товаров с разными атрибутами (ноутбук vs платье)
- Медицинские карты с произвольными полями
✅ Граф связей (Neo4j):
- «Друзья друзей» — в PostgreSQL нужны рекурсивные CTE + индексы
- В Neo4j:
MATCH (a)-[:FRIEND*2]->(b) RETURN b
PostgreSQL как «NoSQL»
Часто не нужно выбирать — PostgreSQL умеет многое:
-- JSONB: документная БД внутри PostgreSQL
CREATE TABLE products (
id SERIAL PRIMARY KEY,
data JSONB NOT NULL
);
INSERT INTO products (data) VALUES
('{"name": "Ноутбук", "specs": {"ram": 16, "storage": 512}, "tags": ["tech"]}');
-- GIN-индекс на JSONB
CREATE INDEX idx_products_data ON products USING gin(data);
-- Запрос как в MongoDB
SELECT data->>'name' FROM products WHERE data @> '{"specs": {"ram": 16}}';
-- Массивы
SELECT * FROM articles WHERE 'sql' = ANY(tags);
-- Граф через рекурсивный CTE (для небольших графов)
WITH RECURSIVE friends AS (
SELECT friend_id FROM relationships WHERE user_id = 42
UNION ALL
SELECT r.friend_id FROM relationships r
JOIN friends f ON f.friend_id = r.user_id
WHERE depth < 3
)
SELECT * FROM friends;
Типичная архитектура в 2026
Большинство компаний используют полиглот-персистентность:
PostgreSQL → основные данные, транзакции, аналитика
Redis → кеш, сессии, очереди, rate limiting
ClickHouse → аналитика событий (100M+ строк)
Elasticsearch → полнотекстовый поиск
S3 (объектное) → файлы, изображения, экспорт CSV
Итог: простое правило
Если не уверены — начните с PostgreSQL. Он покрывает 80% потребностей большинства продуктов. Добавляйте специализированные базы по мере роста и появления конкретных bottleneck.
| Задача | Выбор |
|---|---|
| Основные бизнес-данные | PostgreSQL |
| Кеш | Redis |
| Поиск по тексту | Elasticsearch |
| Аналитика событий | ClickHouse |
| Социальный граф | Neo4j |
| Файлы | S3 |