DB Selection Framework — decision tree concept page. 6 dimensions (data model, scale, consistency, query patterns, ops maturity, cost) → engine pick. Maps workloads (e-commerce OLTP+search, real-time analytics, social graph, vector AI/RAG, global ACID, NoSQL antipattern) to engines (Postgres, MongoDB, Cassandra, DynamoDB, Spanner, ClickHouse, Pinecone, Neo4j, Redis, Elasticsearch). Includes ADR on NoSQL hype vs Postgres-достаточно. 6 scenarios.
Выбор БД — одно из самых дорогих архитектурных решений. Менять движок в проде, когда у тебя терабайты данных и сотни тысяч запросов в секунду — это годы работы, downtime-окна, dual-write fan-out, миграционные скрипты, которые ломаются на edge-кейсах. И всё это потому, что три года назад кто-то ткнул в Mongo «потому что schema-less».
Нужен framework. Не «какая БД лучшая» (нет такой), а какая БД лучше всего подходит под конкретный workload по 6 измерениям. Без хайпа, без cargo-cult, без копирования стека Netflix в команду из четырёх человек.
Ключевая идея: default = Postgres. NoSQL/specialized — только при измеримом блокере. Хайп-driven архитектура — главный источник техдолга в startup-стадии.
Шесть измерений, по которым оценивается workload и сравнивается с возможностями движка:
Слева — приложение и Decision Router — это абстракция твоего архитектурного решения. Снизу — шесть dimension-нод, по которым роутер «оценивает» workload. Справа — три ряда движков:
Edges от роутера к каждому движку — это возможные решения, не одновременные. Сценарии анимации показывают, как для конкретного workload роутер последовательно прогоняет dimension-проверки и приходит к выбору одного или нескольких движков. Polyglot persistence — норма, поэтому в сценариях часто выбирается не один движок, а связка (Postgres + Elasticsearch + Redis для e-commerce).
ADR на ноде app фиксирует главное правило: default = Postgres, NoSQL — только под измеримый blocker. Открой Architecture Decisions, чтобы увидеть полный контекст.
E-commerce: OLTP + search. Workload — orders, inventory, product catalog, full-text поиск. Dimension-проверки: модель реляционная + текстовые документы, consistency strong (деньги), запросы — точечные UPDATE плюс search, scale — до 10TB. Решение: Postgres для транзакционной части + Elasticsearch для поиска + Redis для сессий/корзины/rate-limit. Anti-pattern: пытаться сделать full-text через Postgres LIKE '%foo%' — sequential scan, медленно на 10M товаров.
Real-time analytics: ClickHouse. Дашборды, ad-hoc analytics, миллиарды событий в день. Query pattern — SUM/COUNT/GROUP BY поверх 100M+ строк, scale 10TB+, ingestion 100K/sec. Postgres отвергается: row-store читает все колонки запроса, в 10× медленнее columnar. Pick: ClickHouse — vectorized execution, columnar storage, sub-second aggregations на терабайтах. Managed-вариант (Yandex Cloud / Altinity) если в команде нет ClickHouse-DBA.
Social graph: Neo4j. Friend-of-friends recommendations, 3-6 hops через миллионы edges. В Postgres это recursive CTE с экспоненциальным взрывом: секунды до минут. Pick: Neo4j с index-free adjacency — каждый hop O(degree), FoF-query 50ms на графе 100M nodes / 1B edges. Cypher позволяет писать MATCH (u:User)-[:FRIEND*1..3]-(suggested) декларативно.
AI/RAG: vector similarity. Semantic search, RAG, рекомендации по embedding. Модель — 768/1536/3072-dim векторы с HNSW/IVF индексами, query — approximate KNN top-k за <100ms. До ~1M векторов хватает pgvector (проще ops, одна БД). Дальше — Pinecone/Qdrant: специализированный ANN engine, 100M+ scale, hybrid search (dense + sparse). Частые embedding-queries имеет смысл кешировать в Redis.
Global strong consistency: Spanner. Глобальные пользователи, финансовые транзакции, 3+ региона, zero data loss. Classic Postgres отвергается: async-репликация даёт окно split-brain при partition между регионами, нет глобальной транзакции. Pick: Spanner или CockroachDB — TrueTime/HLC clock-sync, Paxos quorum cross-region. Trade-off: write latency 100-300ms (round-trip Paxos между регионами) — это цена strict serializability. Альтернатива: если eventual consistency приемлема — Cassandra multi-DC, в 5-10× дешевле.
Anti-pattern: NoSQL hype. Стартап 10GB данных, 100 rps, сущности users/orders/products. Выбрали Mongo «потому что schema-less = scale». Через два года: пишут app-level FK checks, ловят eventual-баги, дубликаты заказов, миграция обратно на Postgres. Правильное решение для этого workload: managed Postgres (RDS/Supabase), zero ops, до целевого scale ещё 100× запас.
| Решение | Плюсы | Минусы | Когда выбирать |
|---|---|---|---|
| Postgres default | ACID, JOIN, FK, mature tooling, SQL skills везде, managed (RDS/Supabase) | single-node ~10TB ceiling, без шардинга не масштабируется глобально | До измеримого blocker |
| MongoDB | гибкая схема, горизонтальное масштабирование, агрегации | теряешь FK/JOIN/ACID (в полной мере), team пишет consistency-слой сама | Документная модель, NESTED-данные, тяжёлая denormalization |
| Cassandra | linear write scale, multi-DC из коробки, tunable consistency | сложный data modeling (query-first), нет JOIN, ops-burden | >100K writes/sec, append-heavy, time-series |
| DynamoDB | managed, infinite scale, predictable latency | vendor lock, дорого на больших объёмах, тяжёлый data modeling | AWS-native, точечные KV-lookup, serverless |
| Spanner / Cockroach | global ACID, automatic failover, SQL-совместимость | write latency 100-300ms, дорого, vendor lock (Spanner) | Multi-region strong, финансы, регуляторные требования |
| ClickHouse | sub-second aggregations на TB, columnar, дешёвое хранение | append-only мышление, мутации дорогие, не для OLTP | Real-time analytics, события, dashboards |
| Elasticsearch | full-text, fuzzy, faceted, aggregations | сложный ops, eventually consistent, дорого по памяти | Поиск, логи (см. ELK), faceted-фильтры |
| Neo4j | index-free adjacency, Cypher, традиционный graph-tooling | вертикальное масштабирование (community), дорогой Enterprise | Граф-traversal >2 hops, recommendations, fraud-graphs |
| Pinecone/Qdrant | spec ANN engine, 100M+ vectors, hybrid search | новый класс, vendor lock (Pinecone), доп. компонент в стеке | Vector similarity на >1M векторов |
| Redis | sub-ms latency, structures (sorted sets, streams), pub/sub | RAM-bound, persistence weaker, не source of truth | Cache, сессии, rate limit, leaderboards |
Главный trade-off: простота операций (один движок) vs точность fit-а (polyglot). Polyglot — норма для зрелых систем, но каждая дополнительная БД — это backup-pipeline, monitoring, on-call expertise, миграции. Не добавляй БД, пока существующая реально не упёрлась.
tsvector) лучше, но Elasticsearch объективно мощнее для фасетного поиска.