SQL vs NoSQL: выбор
SQL (реляционные БД) хранят данные в таблицах со строгой схемой и поддерживают ACID-транзакции; NoSQL (документные, ключ-значение, колоночные, графовые) жертвуют жёсткостью схемы ради гибкости и горизонтального масштабирования.
Зачем нужно
Неправильный выбор базы данных в начале проекта — дорогостоящая ошибка. SQL гарантирует целостность данных через внешние ключи и транзакции, но менее гибок при изменении схемы. NoSQL лучше справляется с документами произвольной формы и большими объёмами, но сложнее в обеспечении консистентности. Понимание компромиссов позволяет сделать правильный выбор с первого раза.
Где используется
- SQL — финансовые системы, ERP, интернет-магазины (заказы, инвентарь), любые системы с отношениями между сущностями
- MongoDB — CMS, профили пользователей с переменными атрибутами, прототипы
- Redis — кеш, сессии, rate-limiting, очереди
- Elasticsearch — полнотекстовый поиск, логи, аналитика
Основной контент
Сравнительная таблица
| Критерий | SQL (PostgreSQL) | MongoDB | Redis |
|---|---|---|---|
| Модель данных | Таблицы | Документы (BSON/JSON) | Ключ-значение |
| Схема | Строгая | Гибкая | Нет |
| ACID | Полная | Частичная (с v4.0) | Нет |
| JOIN | Да | Через $lookup (медленно) |
Нет |
| Масштабирование | Вертикальное (Read Replicas) | Горизонтальное (Sharding) | Горизонтальное (Cluster) |
| Скорость чтения | Средняя | Высокая (без JOIN) | Очень высокая (in-memory) |
| Транзакции | Да | Только в replica set | Нет (MULTI/EXEC) |
| Миграции | Обязательны | Опциональны | — |
Когда выбирать SQL (PostgreSQL)
Выбирай SQL если:
✓ Данные взаимосвязаны (заказы → товары → пользователи)
✓ Нужны ACID-транзакции (финансы, инвентарь)
✓ Схема стабильна и хорошо известна
✓ Нужны сложные запросы (JOIN, агрегация, window functions)
✓ Целостность данных критична (внешние ключи)
-- SQL хорошо выражает связанные запросы
SELECT u.name, COUNT(o.id) as order_count, SUM(o.total) as total_spent
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.created_at > '2024-01-01'
GROUP BY u.id
HAVING COUNT(o.id) > 5
ORDER BY total_spent DESC;
Когда выбирать MongoDB
Выбирай MongoDB если:
✓ Документы с непредсказуемой структурой
✓ Часто меняющаяся схема (прототип, стартап)
✓ Вложенные данные хранятся вместе (пост + комментарии)
✓ Горизонтальное масштабирование с самого начала
✗ Нужны сложные JOIN
✗ Финансовые данные (строгие транзакции)
// MongoDB хорошо справляется с вложенными документами
{
_id: ObjectId('...'),
title: 'Product',
attributes: { // разные атрибуты для разных категорий
color: 'red',
size: 'XL',
material: 'cotton'
},
reviews: [ // встроенный массив отзывов
{ user: 'Alice', rating: 5, text: '...' }
]
}
Polyglot Persistence — несколько БД в одном приложении
Типичная архитектура:
PostgreSQL ← основные данные (заказы, пользователи, транзакции)
MongoDB ← контент (статьи, продукты с произвольными полями)
Redis ← кеш, сессии, rate-limiting
Elasticsearch ← полнотекстовый поиск
Node.js: подключение разных БД
// Один сервис может работать с несколькими БД
const { Pool } = require('pg'); // PostgreSQL — транзакции
const mongoose = require('mongoose'); // MongoDB — контент
const Redis = require('ioredis'); // Redis — кеш
// Правило: кешируй в Redis → читай из MongoDB/PostgreSQL
async function getProduct(id) {
const cached = await redis.get(`product:${id}`);
if (cached) return JSON.parse(cached);
const product = await db('products').where({ id }).first; // PostgreSQL
await redis.set(`product:${id}`, JSON.stringify(product), 'EX', 300);
return product;
}
Частые ошибки
- MongoDB для всего — начать с MongoDB ради простоты, потом обнаружить, что нужны JOIN и транзакции
- Хранить всё в одной БД — использовать PostgreSQL как очередь задач или как кеш: плохая идея
- Игнорировать индексы в NoSQL — MongoDB без индексов делает full collection scan; эффект как без индексов в SQL
- Преждевременный выбор "масштабируемой" NoSQL — 90% стартапов никогда не достигают масштаба, при котором PostgreSQL становится узким местом
Связанные темы
- _MOC Node.js
- PostgreSQL -- основы и pg
- MongoDB -- основы и Mongoose
- Redis -- кеширование
- ORM -- Prisma обзор