Типы баз данных: реляционные, NoSQL, колоночные и другие
Типы баз данных: реляционные, NoSQL, колоночные, графовые и другие. Чем SQL отличается от NoSQL и где аналитик встречает каждую базу.
Содержание статьи
Первая неделя на новой работе. Разработчик объясняет устройство продукта: «Заказы лежат в Postgres, корзина — в Redis, логи ищем в Elasticsearch, а отчёты строим в ClickHouse». Вам нужно посчитать выручку по каналам, и первый вопрос — куда вообще писать запрос. Базы данных устроены по-разному, потому что решают разные задачи. Ниже — какие бывают типы баз данных, как каждый хранит данные, где аналитик с ним встречается и где работает SQL.
Коротко
- База данных хранит данные, СУБД — программа, которая их записывает, ищет и отдаёт по запросу.
- Реляционные базы хранят таблицы со связями и понимают SQL. Нереляционные (NoSQL) хранят пары «ключ — значение», документы, графы или широкие строки и чаще имеют свой язык запросов.
- Базы для продукта (OLTP) обычно хранят данные строками, аналитические (OLAP) — столбцами.
- Типичный путь данных для аналитика: рабочая база продукта → реплика → хранилище данных → BI.
- SQL встречается далеко за пределами «классических» реляционных баз: в колоночных хранилищах, во встраиваемых движках, в SQL-похожих языках NoSQL-систем.
Что такое база данных и СУБД
База данных — это организованный набор данных, который хранится так, чтобы его можно было надёжно записывать, быстро находить и одновременно читать многим пользователям. Работой с ней управляет СУБД, система управления базами данных: она принимает запросы, следит за целостностью, пишет данные на диск и восстанавливает их после сбоя.
В разговоре эти слова смешивают: «наша база — PostgreSQL». Строго говоря, PostgreSQL — это СУБД, а база — конкретный набор таблиц внутри неё. Для выбора инструмента важнее другое: какую модель данных СУБД поддерживает и под какие запросы она оптимизирована. От этого и зависит тип базы.
Какие бывают базы данных: классификация
Классификаций много, но на практике базы различают по модели данных и по основной нагрузке. Таблица ниже покрывает то, что встречается в продуктовых компаниях. Одна система может попадать в несколько строк: PostgreSQL с расширениями умеет и временные ряды, и векторы, и JSON-документы.
| Тип | Как хранит данные | Примеры | Типичная задача | Как встречает аналитик |
|---|---|---|---|---|
| Реляционная | таблицы с фиксированными колонками и связями через ключи | PostgreSQL, MySQL | заказы, пользователи, оплаты — всё, где нужны транзакции | реплика рабочей базы, выгрузки, первые отчёты |
| Ключ — значение | пары «ключ → значение», часто в памяти | Redis | кэш, сессии, счётчики, очереди | почти никогда напрямую; данные оттуда редко доходят до хранилища |
| Документная | документы в формате, близком к JSON, со вложенными полями | MongoDB | профили, каталоги, настройки с меняющейся структурой | выгрузка в хранилище, где вложенные поля разворачивают в колонки |
| Колоночная аналитическая | таблицы, но каждая колонка хранится отдельно и сжимается | ClickHouse, BigQuery, Snowflake | агрегаты по миллионам и миллиардам строк | основное рабочее место: хранилище и витрины |
| Широкие колонки (wide-column) | строки, распределённые по узлам кластера по ключу партиции | Cassandra | много записей с предсказуемыми запросами по ключу | через выгрузку; напрямую агрегировать неудобно |
| Графовая | узлы и связи между ними | Neo4j | социальные связи, рекомендации, поиск мошеннических цепочек | редко; в отдельных задачах антифрода и рекомендаций |
| Временных рядов | значения, привязанные ко времени, с быстрой агрегацией по интервалам | TimescaleDB, InfluxDB, Prometheus | метрики серверов, датчики, мониторинг | технические метрики и графики нагрузки |
| Поисковая | обратный индекс: слово → документы, где оно встречается | Elasticsearch, OpenSearch | полнотекстовый поиск, логи | поиск по логам при разборе инцидентов |
| Векторная | числовые векторы и поиск ближайших соседей | pgvector, Qdrant, Milvus | поиск по смыслу, RAG, рекомендации | в проектах с языковыми моделями |
| Встраиваемая | база внутри приложения, обычно в одном файле, без сервера | SQLite, DuckDB | данные мобильного приложения, анализ файлов на ноутбуке | DuckDB — для CSV и Parquet локально; SQLite — в выгрузках из приложений |
Реляционные и нереляционные базы данных: в чём разница
Реляционная база раскладывает данные по таблицам и связывает их ключами. Пользователь 8 из учебной базы SQL-курса — это одна строка в users (канал organic, страна RU) и три строки в payments: три оплаты тарифа pro по 29 — 10 июня, 10 июля и 9 августа. Строки оплат ссылаются на пользователя через user_id, а собирает их вместе JOIN.
Документная база хранит того же пользователя одним документом, где оплаты вложены списком. Прочитать профиль целиком — одно обращение, без соединений. Посчитать выручку по месяцам по всем пользователям — наоборот, дольше: придётся пройти по каждому документу и достать вложенные значения.
Второе отличие — схема. В реляционной базе колонки и их типы объявлены заранее, и база не примет строку, которая им не соответствует. В документной базе поле может появиться, пропасть или поменять тип между документами. Схема при этом никуда не исчезает, она просто живёт в коде приложения. Аналитик узнаёт об этом, когда поле amount в половине документов оказывается строкой.
«NoSQL» — не одна технология, а зонтичное название всего нереляционного: ключ-значение, документов, графов, широких колонок. Расшифровывают его обычно как «not only SQL». Поэтому вопрос «SQL или NoSQL» точнее звучит так: какую модель данных и какие гарантии требует задача.
| Вопрос | Реляционная база | Типичная NoSQL-база |
|---|---|---|
| Где задана структура | в схеме базы: колонки и типы | чаще в коде приложения |
| Как связаны сущности | ключи и JOIN | вложение в документ или дублирование |
| Транзакции на несколько записей | стандартная возможность | зависит от системы, часто с ограничениями |
| Язык запросов | SQL | свой: команды, JSON-запросы, Cypher, CQL |
| Где удобна аналитика | на реплике или после выгрузки | почти всегда после выгрузки в хранилище |
select jsonb_pretty(jsonb_build_object(
'user_id', u.user_id,
'channel', u.channel,
'country', u.country,
'payments', (
select jsonb_agg(jsonb_build_object(
'paid_at', p.paid_at, 'amount', p.amount, 'plan', p.plan
) order by p.paid_at)
from payments as p
where p.user_id = u.user_id
)
))
from users as u
where u.user_id = 8;
-- {"user_id": 8, "channel": "organic", "country": "RU",
-- "payments": [{"paid_at": "2026-06-10", "amount": 29, "plan": "pro"},
-- {"paid_at": "2026-07-10", "amount": 29, "plan": "pro"},
-- {"paid_at": "2026-08-09", "amount": 29, "plan": "pro"}]}OLTP и OLAP: две разные работы
Внутри реляционного мира тоже есть деление — по нагрузке. OLTP-база обслуживает продукт: тысячи коротких операций в секунду, каждая читает или меняет несколько строк. Оплата прошла — добавилась одна строка в payments. Здесь важны транзакции и гарантии ACID.
OLAP-система отвечает на вопросы о продукте: один запрос проходит по всем оплатам за квартал и складывает суммы по каналам. Запросов меньше, зато каждый тяжёлый. Подробное сравнение — в статье про OLAP и OLTP, а про слои хранилища — в материале о DWH, витринах и data lake.
Строковое и колоночное хранение
Строковая база кладёт на диск запись целиком: все поля первого пользователя, затем все поля второго. Так устроены PostgreSQL и MySQL, и для OLTP это удобно — чтобы найти или обновить одну запись, достаточно одного места на диске.
Колоночная база хранит каждую колонку отдельно: все user_id подряд, все channel подряд. Запросу «сколько пользователей в каждом канале» нужна одна колонка из пяти, и остальные четыре можно не читать. Однотипные значения рядом ещё и хорошо сжимаются. Обратная сторона — вставка и изменение одной строки обходятся дороже: запись разложена по нескольким местам.
| Блок | Строковое хранение (PostgreSQL, MySQL) | Колоночное хранение (ClickHouse, DuckDB) |
|---|---|---|
| 1 | 1 · 2026-06-01 · partner · RU · desktop | user_id: 1, 2, 3 |
| 2 | 2 · 2026-06-01 · referral · RU · mobile | signup_date: 2026-06-01, 2026-06-01, 2026-06-01 |
| 3 | 3 · 2026-06-01 · partner · BY · mobile | channel: partner, referral, partner |
| 4 | — | country: RU, RU, BY |
| 5 | — | device: desktop, mobile, mobile |
В колоночном хранилище select * по большой таблице — самый дорогой вариант: он поднимает все колонки. Перечисляйте только нужные поля. В строковой базе дорого другое — полный проход по таблице без подходящего индекса.
Один SQL в двух разных движках
Модель хранения меняет скорость и цену запроса, но не его текст. Песочница SQL-курса работает на DuckDB — встраиваемой колоночной базе. Рабочие базы продуктов чаще живут в PostgreSQL. Запрос ниже выполняется в обоих без изменений и возвращает одинаковый результат.
Расхождения начинаются на функциях дат и строк, на приведении типов и на расширениях вроде QUALIFY, которые есть в одних движках и отсутствуют в других. Базовые select, join, group by переносятся между реляционными и колоночными системами почти без правок.
| channel | payments | revenue |
|---|---|---|
| organic | 566 | 14114 |
| referral | 384 | 9326 |
| partner | 198 | 4732 |
| paid_search | 103 | 2467 |
select
u.channel,
count(*) as payments,
sum(p.amount) as revenue
from payments as p
join users as u on u.user_id = p.user_id
group by u.channel
order by revenue desc;Где работает SQL
SQL давно вышел за пределы классических реляционных баз. ClickHouse, BigQuery и Snowflake — колоночные системы со своими диалектами SQL. DuckDB и SQLite — встраиваемые базы, которые тоже понимают SQL. TimescaleDB — расширение PostgreSQL, поэтому временные ряды в нём запрашивают обычным SQL, как и векторы в pgvector.
У нереляционных систем свои языки, иногда внешне похожие на SQL. В Cassandra это CQL: синтаксис напоминает SQL, но JOIN нет, а запрос удобно строить только от ключа партиции. У MongoDB свой язык запросов и конвейер агрегаций. Neo4j использует Cypher. Redis управляется командами вроде GET и SET. Elasticsearch принимает запросы в виде JSON, и у него есть SQL-интерфейс для простых выборок.
Для аналитика это значит простую вещь: SQL нужен почти всегда, но не везде он один и тот же. Прежде чем переносить запрос в новую систему, проверьте, как в её диалекте устроены даты, NULL и деление целых чисел.
Что обычно видит аналитик
В большинстве продуктовых компаний данные проходят похожий путь, даже если названия систем разные. Аналитик чаще всего работает на двух последних шагах, но полезно понимать все, чтобы знать, откуда берутся расхождения в цифрах.
Выбор, куда писать запрос, обычно сводится к компромиссу между свежестью и удобством. Реплика показывает данные почти в реальном времени, но таблицы там устроены под приложение: статусы закодированы числами, история изменений не хранится, а тяжёлый запрос может мешать другим читателям реплики. Хранилище отстаёт на время загрузки — от минут до суток, — зато в нём есть витрины с понятными колонками и история. Для ежедневных отчётов берите хранилище, для разбора «что случилось час назад» — реплику, предупредив разработчиков.
- Рабочая база продукта — PostgreSQL или MySQL. В неё пишет приложение; тяжёлые запросы сюда не отправляют, чтобы не замедлять оплаты и регистрации.
- Реплика — копия рабочей базы только для чтения. На ней можно смотреть свежие данные, но таблицы нормализованы и неудобны для отчётов.
- ETL или ELT — процессы, которые забирают данные из рабочих баз, логов и NoSQL-систем и загружают в хранилище. Здесь появляются задержки и первые расхождения.
- Хранилище данных (DWH) — ClickHouse, BigQuery, Snowflake, Greenplum или похожая система. Здесь лежат сырые слои и витрины, и здесь аналитик пишет большую часть запросов.
- BI — дашборды, которые читают витрины. Если цифра на дашборде расходится с продуктом, искать причину приходится по всей цепочке в обратном порядке.
Как выбрать тип базы данных
Аналитик редко выбирает базу для продукта, но часто — для своей задачи: где хранить витрину, куда сложить выгрузку, на чём собрать прототип отчёта. Выбор начинается не с названия системы, а с вопросов к задаче.
Есть и вопрос, которого нет в таблице: что уже работает в компании. Каждая новая база — это ещё один процесс загрузки, мониторинг, резервные копии и человек, который умеет её чинить. Витрина в уже существующем хранилище почти всегда дешевле, чем отдельная система под одну задачу, даже если та формально подходит лучше.
| Вопрос | Если ответ такой | Смотрите в сторону |
|---|---|---|
| Какой запрос типичный? | найти или изменить одну запись по ключу | реляционная или ключ-значение |
| Какой запрос типичный? | агрегировать миллионы строк по нескольким колонкам | колоночная аналитическая |
| Нужны транзакции на несколько записей? | да: деньги, остатки, статусы | реляционная |
| Насколько стабильна структура? | поля часто меняются и вложены | документная или JSON-колонки в реляционной |
| Важны связи сами по себе? | обход цепочек «друг друга друга» | графовая |
| Данные — измерения во времени? | метрики каждые несколько секунд | временных рядов |
| Нужен поиск по тексту? | полнотекстовый поиск с ранжированием | поисковая |
| Кто и где будет считать? | один человек на ноутбуке по файлам | встраиваемая: DuckDB |
Если сомневаетесь, начинайте с PostgreSQL: он закрывает транзакции, JSON и умеренную аналитику. Специализированная база оправдана, когда вы можете назвать запрос, который в PostgreSQL выполняется плохо, и показать это на своих данных.
Частые заблуждения о типах баз данных
- «NoSQL быстрее SQL». Быстрее бывает конкретная система на конкретном запросе. Redis отдаёт значение по ключу мгновенно, но не посчитает выручку по каналам.
- «В NoSQL нет схемы». Схема есть всегда, вопрос только в том, кто её проверяет: база или код приложения.
- «Колоночная база — это NoSQL». ClickHouse и BigQuery работают с таблицами и SQL. От PostgreSQL они отличаются способом хранения и нагрузкой, а не моделью данных.
- «Хранилище заменит рабочую базу». Колоночные системы плохо переносят частые обновления отдельных строк и не рассчитаны на транзакции продукта.
- «Нормализация устарела». Для OLTP она по-прежнему защищает от противоречивых данных. Денормализация уместна в витринах, где данные только читают.
Что читать дальше
Попробуйте запрос из раздела про два движка в песочнице курса: там он выполняется на колоночном DuckDB. Затем замените sum(p.amount) на count(distinct p.user_id) и посмотрите, сколько платящих пользователей приходит из каждого канала.
Материалы по теме
Что такое SQL простыми словами: реляционная база, таблицы и запросы
Что такое SQL и реляционная база данных: таблица, строка и колонка, первый запрос с результатом, JOIN, команды языка, СУБД и диалекты, что SQL умеет и чего не умеет.

Индексы в SQL: что это, как работают и когда помогают
Индексы в SQL: что это, как работает B-tree, составной, частичный индекс и индекс по выражению, когда индекс не помогает — на планах EXPLAIN ANALYZE.

ACID в базах данных: принципы транзакций и уровни изоляции
Что такое ACID-транзакции простыми словами: атомарность, согласованность, изоляция и долговечность на примерах перевода денег и оплаты подписки. BEGIN, COMMIT, ROLLBACK, уровни изоляции и аномалии в PostgreSQL с реальными выводами и что всё это значит для аналитика.