Разбираем типы баз данных: реляционные, колоночные, документные, графовые, векторные, key‑value и другие. Плюсы, минусы и когда что выбирать.

Типы баз данных — это не «разные бренды», а разные подходы к хранению и чтению данных. Они появились потому, что одна и та же система редко одинаково хорошо справляется и с быстрыми точечными операциями (например, оформить заказ), и с тяжёлой аналитикой по миллиардам строк (например, посчитать выручку по регионам за год), и с поиском по смыслу текста.
Эта статья помогает выбрать хранилище под задачу: какие у вас данные, какие запросы вы делаете, как вы будете расти (объём и нагрузка) и сколько будет стоить эксплуатация (железо/облако, команда, администрирование, риски).
Схема — правила, по которым устроены данные (какие поля есть и каких они типов). В одних БД она строгая (обычно SQL), в других допускается гибкость (часто документные).
Транзакции — способ выполнить несколько изменений как одно целое: либо всё применилось, либо ничего. Это важно для денег, остатков, бронирований.
Индексы — «оглавление» для данных. Они ускоряют поиск и сортировку, но требуют места и замедляют запись (индекс тоже нужно обновлять).
Репликация — копирование данных на другие узлы. Нужна для отказоустойчивости и иногда для ускорения чтения.
Не ищите «лучшую базу данных». Правильнее мыслить сценариями:
Дальше разберём основные классы (SQL, колоночные, документные, графовые, векторные, key-value) и покажем, где каждый даёт максимум пользы — и какие компромиссы за это приходится платить.
OLTP и OLAP — это не «виды баз данных», а два класса нагрузок, которые по‑разному нагружают хранилище. Ошибка на этом уровне часто приводит к тому, что база «вроде бы подходит», но в реальности оказывается медленной или слишком дорогой.
OLTP (Online Transaction Processing) — это повседневные транзакции: оформление заказа, списание со склада, перевод денег, обновление профиля.
Типично для OLTP:
OLAP (Online Analytical Processing) — это отчёты и анализ: «выручка по дням», «топ товаров по регионам», «воронка по каналам».
Характерно для OLAP:
Для OLTP обычно критична латентность (p95/p99), потому что каждый запрос «на виду». Для OLAP чаще критичны стоимость и скорость больших запросов: сканы, джойны, агрегаты могут быть дорогими, но выполняются реже и часто пакетно.
Практичный ориентир: если типичный запрос — «найти/обновить сущность по ключу», вы ближе к OLTP. Если «посчитать/сравнить/свести по миллионам строк», вы ближе к OLAP.
Реляционные базы данных — лучший выбор, когда данные естественно раскладываются по таблицам и между ними есть чёткие связи. Типичные примеры: справочники (товары, контрагенты), заказы и позиции заказа, платежи, бухгалтерские проводки, биллинг, складской учёт.
SQL — универсальный язык работы с данными: его понимают разработчики, аналитики и большинство BI‑инструментов. Строгая схема (типы столбцов, обязательные поля) и ограничения помогают ловить ошибки на входе, до того как данные «разъедутся» по системе.
Когда нужна корректность (например, списать деньги и создать запись о платеже), нужны ACID‑гарантии: атомарность, согласованность, изоляция, долговечность. Уровни изоляции (например, Read Committed или Serializable) позволяют управлять тем, как параллельные операции влияют друг на друга — это напрямую связано с гонками, «двойными списаниями» и корректностью остатков.
Главные козыри SQL‑СУБД:
Самое сложное — горизонтальное масштабирование: шардинг часто требует аккуратного проектирования ключей и запросов. Эволюция схемы тоже может быть болезненной (особенно на больших таблицах).
Также данные со сложными иерархиями и «глубокими» связями иногда удобнее выражать в документных или графовых БД, чтобы не превращать модель в набор громоздких JOIN.
Колоночные базы данных хранят данные «по столбцам», а не «по строкам». Для аналитики это часто решающий плюс: когда вы считаете суммы, средние, распределения или строите отчёты, запросу обычно нужны 2–5 столбцов из широкой таблицы, а не вся строка целиком. Колонка читает и обрабатывает именно нужные столбцы — меньше I/O, меньше лишних данных в памяти, быстрее агрегации.
Колоночные БД выбирают там, где много «больших сканов» и группировок:
Три идеи, которые обычно дают прирост производительности:
Сжатие. В одном столбце значения часто похожи (например, «страна», «статус», «тип события»), поэтому их хорошо сжимать. С диска читается меньше байтов — запросы ускоряются.
Векторизация. Вместо обработки «по одной строке» движок работает блоками значений (пакетами), лучше используя CPU и кэш.
Партиционирование. Данные делятся на части (например, по дате). Тогда запрос «за последние 7 дней» не трогает старые партиции.
Колоночные БД обычно хуже справляются с частыми точечными обновлениями и высокой транзакционной нагрузкой (много мелких INSERT/UPDATE с жёсткими SLA). Там, где важны быстрые операции по одной записи и сложные транзакции, чаще выигрывают OLTP‑решения.
Распространённый подход — разделить контуры: OLTP обслуживает приложение, а колонночная БД — аналитику. Данные доставляют через репликацию или CDC (Change Data Capture), чтобы аналитика получала почти «живую» копию событий без нагрузки на боевую базу.
Документо-ориентированные базы данных хранят данные не в строках таблиц, а в «документах» — чаще всего в JSON (или близких форматах вроде BSON). Документ похож на объект в коде: в нём можно держать поля разного типа, вложенные структуры и массивы. Схема при этом гибкая: разные документы в одной коллекции могут иметь разные наборы полей.
Документный подход хорошо ложится на данные, которые естественно «собираются» вокруг одной сущности:
Вместо большого числа JOIN вы часто читаете один документ целиком — это ускоряет разработку и упрощает прикладной код.
Несмотря на «безтабличность», это не просто хранилище JSON. Обычно доступны фильтры по атрибутам, сортировки и агрегации, а также индексы по полям (включая вложенные). Например, можно индексировать user.email или элементы массива tags, чтобы поиск не превращался в полный скан.
Главный плюс — скорость развития модели: меньше миграций и проще добавлять новые поля по мере роста продукта.
Типичные риски:
Документные БД (например, MongoDB) часто выбирают, когда важны гибкость и быстрые изменения, а строгая нормализация не является приоритетом.
Графовая база данных хранит информацию как граф: есть вершины (объекты), рёбра (связи между объектами) и свойства (атрибуты и у вершин, и у рёбер). Аналогия: «пользователь» — вершина, «дружит» — ребро, «дата знакомства» — свойство ребра.
Графовые БД удобны, когда главный вопрос — «как объекты связаны» и «что находится рядом»:
В реляционной модели связи выражаются через внешние ключи и JOIN. Когда запрос требует много «переходов» (JOIN за JOIN’ом), он становится громоздким и часто дорогим по вычислениям. На больших наборах данных такие многократные соединения могут резко ухудшать время ответа — особенно если нужно пройти несколько уровней отношений и фильтровать по свойствам на каждом шаге.
Сильные стороны — это обходы графа (traversal), поиск соседей (k-hop), кратчайшие пути и другие алгоритмы, где важно быстро перемещаться по связям, а не сканировать таблицы.
Графовые БД сложнее масштабировать горизонтально: распределять данные так, чтобы «частые» связи не разрывали граф на разные узлы, непросто. Также придётся выбрать язык запросов и инструменты (например, Cypher, Gremlin, SPARQL) и убедиться, что экосистема подходит вашей команде и сценариям продакшена.
Векторные базы данных хранят не только «текст как текст», а его числовое представление — эмбеддинг. Эмбеддинги создают модели машинного обучения: они кодируют смысл фразы, абзаца, картинки или аудио в массив чисел. Поэтому вместо «найти слово X» можно искать «найти похожее по смыслу», даже если совпадений по словам нет.
Запрос тоже превращается в эмбеддинг. Дальше система ищет ближайшие векторы (обычно по косинусной близости или евклидовому расстоянию). Полный перебор дорогой, поэтому используют векторные индексы ANN (Approximate Nearest Neighbors): они ускоряют поиск, но могут слегка терять точность.
Компромисс простой: больше точности — больше времени/памяти; больше скорости — выше риск пропустить часть релевантных результатов. На практике это настраивают под SLA (например, 100–300 мс на поиск при приемлемом качестве).
Самые популярные применения: RAG (добавление найденных фрагментов в контекст LLM), поиск по корпоративным документам, мультимодальный поиск (текст ↔ изображение), а также дедупликация и поиск похожих объектов (товары, вакансии, обращения в поддержку).
Обычно сохраняют: (1) сам вектор, (2) метаданные для фильтров (язык, дата, права доступа, источник), (3) исходный текст/фрагмент или ссылку на него. Важно заранее решить, где будет «источник истины»: в векторной БД или в отдельном хранилище — чтобы обновления и доступы были предсказуемыми.
Векторные индексы не любят частых массовых обновлений: перестроение может быть дорогим. Качество нужно измерять: набор эталонных запросов, метрики (precision@k, recall@k), проверка «галлюцинаций» RAG и регулярная переоценка релевантности при смене модели эмбеддингов.
Key-value хранилище — минималистичная модель данных: ключ → значение. Ключ обычно строковый, а значение — что угодно (строка, JSON, бинарные данные). Схемы таблиц нет, связей между сущностями тоже: вы всегда обращаетесь к данным по ключу.
Сильная сторона key-value — быстрые операции чтения/записи по ключу при высокой конкуренции.
Типичные сценарии:
Key-value хорошо масштабируются, потому что запросы простые и предсказуемые: «дай значение по ключу» или «запиши значение по ключу». Это даёт низкую задержку, высокую пропускную способность и относительно простую модель масштабирования (например, по диапазонам/хешам ключей).
Основное ограничение — сложные выборки. Если нужно «найти всех пользователей из города X с подпиской Y» или сделать отчёт по многим полям, key-value быстро становится неудобным: придётся поддерживать дополнительные индексы вручную, дублировать данные или переносить аналитику в другую БД. «JOIN‑ов» по сути нет.
Важно заранее решить, это только кеш или источник истины:
Практическое правило: если потеря данных болезненна или требуется сложный поиск — используйте key-value как ускоритель рядом с основной БД, а не вместо неё.
Помимо «классических» SQL/NoSQL есть специализированные хранилища, которые выигрывают на конкретных типах нагрузок. Они не «лучше вообще», но часто дают заметную экономию времени и денег при правильном применении.
Wide-column БД (например, Cassandra, HBase) хранят данные в виде строк с очень большим числом разреженных колонок, сгруппированных в «семейства». Это не то же самое, что колоночная аналитика: аналитические колоночные БД оптимизированы под массовые сканы и агрегации, а wide-column — под быстрые чтения/записи по ключу и предсказуемые запросы.
Ключевая идея: вы заранее проектируете таблицы под конкретные паттерны доступа (часто «денормализуете»), получая высокую доступность и горизонтальное масштабирование ценой слабой поддержки произвольных запросов.
Time-series решения (InfluxDB, Prometheus-стиль хранения, TimescaleDB и др.) заточены под метрики и события во времени: много точек, постоянная запись, типовые запросы «за последние 15 минут/7 дней».
Обычно есть:
Полнотекстовые движки (Elasticsearch/OpenSearch/Solr) строят инвертированный индекс: вместо «где встречается слово» поиск становится быстрым. Они сильны в:
При этом они чаще выступают поисковым слоем, а не единственным «источником истины».
Event store и журналы (Kafka/Pulsar, EventStoreDB) хранят неизменяемую последовательность событий. Концептуально это позволяет считать события первичными, а «текущие состояния» — производными представлениями, которые можно пересобрать.
Добавляйте специализированное хранилище, если:
Если сомневаетесь, начните с минимальной схемы «основная БД + специализированный слой» и заранее определите границы ответственности данных.
Когда база данных распределена по нескольким узлам или дата-центрам, неизбежно возникает выбор между тремя желаниями: чтобы данные везде были одинаковыми (консистентность), чтобы система отвечала всегда (доступность) и чтобы она продолжала работать при сетевых разрывах между узлами (устойчивость к разделению сети). CAP‑идея проста: при реальных сетевых сбоях нельзя гарантировать одновременно «идеальную одинаковость» и «ответ всегда».
Сильная согласованность означает: после успешной записи любой следующий запрос видит новое значение. Для пользователя это выглядит как «система помнит прямо сейчас» — критично для денег, остатков, статусов заказов.
Итоговая (eventual) согласованность допускает задержку: запись разойдётся по репликам не мгновенно, и часть пользователей некоторое время увидит старые данные. Это часто нормально для ленты, счётчиков просмотров, рекомендаций, метрик.
Чтобы приблизиться к сильной согласованности, системы используют репликацию с подтверждениями от нескольких узлов (кворум). Чем больше узлов должны подтвердить запись, тем выше задержка и тем больше шансов получить ошибку при проблемах сети — зато меньше риск прочитать устаревшее.
Транзакции уровня «всё или ничего» становятся сложнее, когда данные на разных узлах. Двухфазный коммит и похожие механизмы добавляют ожидание и точки отказа, поэтому многие продукты ограничивают кросс‑шардовые транзакции или предлагают упрощённые модели.
Спросите себя: что будет хуже — редкое «не отвечает» или редкое «показали старое»? Для платежей и заказов чаще выбирают консистентность; для ленты/метрик — доступность и скорость. Этот ответ затем определяет тип хранилища, настройки репликации и ожидания от SLA (см. также /blog/kak-vybrat-bazu-dannyh).
Производительность базы данных почти всегда упирается в три вещи: как вы ищете данные (индексы), как распределяете нагрузку (партиционирование/шардинг) и сколько стоит хранить «всё это» годами. Хорошая новость: большинство проблем предсказуемы и решаются правильными базовыми решениями.
B-tree — универсальный выбор для диапазонов и сортировок (даты, цены, ORDER BY). Хеш‑индексы полезны для точного равенства по ключу, но часто хуже подходят для диапазонов.
Инвертированный индекс нужен для полнотекстового поиска (слова, токены, фильтры по тексту). В графовых БД индексируют идентификаторы и свойства узлов/рёбер, но скорость часто определяет сама модель связей.
Для векторных БД важен ANN‑индекс (Approximate Nearest Neighbor): он ускоряет семантический поиск, но даёт компромисс между точностью, памятью и скоростью.
Партиционирование делит данные внутри одной системы (часто по времени), шардирование — распределяет по узлам. Ключ выбирают так, чтобы:
Типичный анти‑пример — шардировать по признаку, который почти всегда одинаковый (например, один «tenant» или один регион): получится перекос.
Симптомы простые: один шард/партиция перегружены, p95/p99 задержек растут, очередь запросов увеличивается, а остальные узлы простаивают. Лечат «солеванием» ключей, переразбиением, кэшированием и пересмотром схемы доступа.
Сжатие снижает цену хранения и ускоряет сканы в колоночных БД, но может удорожать запись. TTL помогает автоматически удалять устаревшее. Для больших объёмов полезны горячие/холодные уровни: быстрые диски для свежих данных, более дешёвые — для архива.
Минимальный набор: QPS, p50/p95/p99 латентности, ошибки, cache hit ratio, время/частота компакции, размер индексов, задержка репликации, распределение нагрузки по шардам, «тяжёлые» запросы и блокировки. Это позволяет ловить деградации до того, как их заметят пользователи.
Выбор между «одной базой на всё» и несколькими специализированными хранилищами — это не про моду, а про границы ответственности и цену сопровождения.
Монолитной системе часто достаточно одной SQL‑БД: единые транзакции, понятная модель данных, меньше движущихся частей.
Но по мере роста появляются симптомы: тяжёлые отчёты мешают транзакциям, разные команды спорят за схему, а изменения требуют координации.
В микросервисах логично делить данные по доменам: «платежи», «каталог», «пользователи» — у каждого свой владелец и своя схема.
Polyglot persistence — это когда вы осознанно берёте 2–3 подходящих хранилища под разные нагрузки, а не разводите «зоопарк из 10». Цель — изоляция задач (транзакции, аналитика, поиск), а не коллекция технологий.
Чтобы данные не расползались, заранее выберите паттерн интеграции:
Частая практичная комбинация: OLTP в SQL (заказы/оплаты) + колоночная БД для аналитики + full‑text для поиска по тексту + векторное хранилище для семантического поиска.
Чтобы удержать сложность, договоритесь о правилах: контракт данных (что и в каком виде публикуется), версионирование схем, один владелец домена и понятные SLA на обновление витрин.
Даже хороший теоретический выбор БД легко «сломать» реализацией: не теми индексами, неудачным ключом шардинга или смешением OLTP и отчётов в одном контуре. Поэтому полезно как можно раньше собрать небольшой вертикальный срез приложения и прогнать его под реальным профилем запросов.
Если вы делаете прототип или пилот, TakProsto.AI может ускорить этот этап: на платформе можно в формате чата собрать веб‑интерфейс, серверную часть и схему хранения, быстро накидать ключевые запросы и посмотреть, где возникают блокировки, «тяжёлые» SELECT и проблемы с индексами. Типичный стек при этом — React на фронтенде и Go + PostgreSQL на бэкенде, а при необходимости проект можно разложить по сервисам, подключить дополнительные хранилища и выгрузить исходники. Важно и то, что TakProsto.AI работает на серверах в России и использует локализованные/opensource‑модели, не отправляя данные за пределы страны — это удобно для проектов с требованиями к размещению данных.
Выбор БД — это не «какая лучше», а «какая закроет ваши запросы и ограничения». Ниже — порядок действий, который помогает не переплачивать и не упереться в потолок через полгода.
Сформулируйте ответы в одном документе:
Не полагайтесь на синтетику. Возьмите срез прод‑данных (с обезличиванием), воспроизведите профиль запросов и параллельность. Смотрите не только среднее время, но и хвосты, размер индексов, скорость бэкапов и восстановления.
Оцените заранее: объём переноса, совместимость типов и транзакций, простои. Заложите план двойной записи или репликации на время переезда и обязательный план отката.
Проверьте: роли и минимальные права, аудит, шифрование, управление ключами, регулярные резервные копии и (обязательно) тест восстановления.
Ограничьте выбор до 1–2 кандидатов и проведите короткий пилот на реальной нагрузке — это обычно быстрее и надёжнее любых «вечных» споров о технологиях.
Тип БД выбирают не по названию, а по профилю нагрузки:
Если большинство запросов — «найти/обновить по ключу», вы ближе к OLTP; если «посчитать по миллионам строк» — к OLAP.
OLTP — это транзакции в приложении: частые INSERT/UPDATE, чтение по ключу, строгая корректность (ACID), важны p95/p99 задержек.
OLAP — аналитика: много GROUP BY, фильтров по периодам, сканы больших таблиц, важнее стоимость и скорость выполнения тяжёлых запросов.
Практика: не пытайтесь «всё делать в одной базе», если отчёты мешают транзакциям — лучше разделять контуры.
SQL‑БД обычно лучший выбор, когда нужны:
JOIN;Если у вас «источник истины» и много бизнес‑правил — чаще всего стартуйте с SQL.
Колоночные БД хранят данные по столбцам, поэтому аналитические запросы читают только нужные колонки и меньше гоняют диском/памятью.
Они особенно полезны для:
Но для частых точечных обновлений и строгих OLTP‑SLA они обычно хуже: запись и изменения «по одной строке» могут быть дорогими.
Документные БД удобны, когда данные естественно собираются вокруг одной сущности и схема часто меняется:
Полезный приём: проектируйте документы под частые чтения «одним запросом», но следите за рисками дублирования и сложных связей «многие‑ко‑многим».
Графовая БД выигрывает, когда главный вопрос — связи и переходы по ним:
В SQL такие задачи часто превращаются в цепочку тяжёлых JOIN. В графе это обычно естественнее и быстрее, но горизонтальное масштабирование и эксплуатация могут быть сложнее.
Векторная БД хранит эмбеддинги и ищет ближайшие по расстоянию — это даёт поиск «по смыслу», а не по совпадению слов.
Чаще всего её берут для:
Важно: качество зависит от модели эмбеддингов и настроек ANN‑индекса, поэтому тестируйте на эталонных запросах (например, precision@k/recall@k).
Key-value подходит, когда доступ почти всегда по ключу и нужна максимальная скорость:
Как «источник истины» key-value используют осторожно: сложные выборки и отчёты там неудобны, а индексы/поиск часто приходится строить вручную или выносить в другую систему.
В распределённых системах при сбоях сети приходится выбирать между консистентностью и доступностью (CAP‑идея).
Практический критерий:
Заранее зафиксируйте ожидания в SLA и настройках репликации, чтобы не удивляться задержкам и конфликтам данных.
Частая рабочая схема:
Чтобы это не превратилось в «зоопарк», заранее определите:
В качестве ориентира полезен чек‑лист из статьи (см. также /blog/kak-vybrat-bazu-dannyh).