Привет, хабр!
Меня зовут Кирилл, и на протяжении последних двух лет я мечтал научиться проходить System Design интервью. Но только недавно взялся за дело всерьёз.
Изучив различные хранилища данных, я наконец-то смог систематизировать свои знания. И хочу поделиться этой структурой с вами, чтобы рассказать, какие бывают хранилища данных и в каких случаях их лучше всего использовать.

SQL и RDBMS
Когда каждый из нас начинает изучать программирование, он учит циклы, операторы ветвления, и когда дело доходит до баз данных, мы изучаем SQL и реляционные СУБД (RDBMS). PostgreSQL, MS SQL Server, MySQL — это всё они, наши старые добрые реляционные базы данных.
SQL-хранилища относятся к классу систем OLTP (Online Transactional Processing — обработка транзакций в реальном времени). Такие базы данных идеально подходят для операций, требующих строгой консистентности и транзакционности: банковские системы, платформы для бронирования билетов, интернет-магазины (учёт заказов, профили пользователей) и так далее. Они гарантируют нам ACID (Atomicity, Consistency, Isolation, Durability).
Если у вас небольшое приложение с невысокой нагрузкой, то просто используйте SQL-хранилище и не парьтесь. Это надёжное, проверенное временем решение.
Но как только возникает большая нагрузка — например, тысячи или десятки тысяч запросов в секунду, то ваша SQL-база может захлебнуться. Реляционная база данных плохо масштабируется горизонтально. Тогда-то и приходят на помощь другие классы хранилищ.
NoSQL
Для определённых задач запросы в SQL-хранилища могут требовать слишком много времени или ресурсов. Например, поиск всех друзей друзей в социальной сети превращается в дорогостоящий рекурсивный JOIN. Именно для таких специфичных кейсов и были придуманы NoSQL-решения.
NoSQL (Not Only SQL) — это широкий класс систем управления базами данных, которые не являются реляционными. Они не требуют жёсткой схемы данных, как правило, лучше масштабируются горизонтально и оптимизированы под конкретные типы нагрузки.
NoSQL-системы часто жертвуют строгой согласованностью (Strong Consistency) ради масштабируемости, предлагая Eventual Consistency, когда данные согласуются между узлами с некоторой задержкой.
Важно понимать: NoSQL — это не синоним OLAP (Online Analytical Processing — анализ данных в реальном времени). Некоторые NoSQL-базы отлично подходят для OLTP-нагрузок (например, Cassandra), другие — для аналитики (OLAP), а третьи вообще не вписываются в эту классификацию.
Давайте разберёмся в их многообразии.
Key-Value хранилища и кэши
Key-Value хранилища — тип нереляционной базы данных, которая хранит данные в виде пар «ключ — значение». Некоторые хранилища типа ключ-значние часто используются в качестве кэша.
Кэш — это высокоскоростное хранилище, которое держит данные в оперативной памяти (RAM) для максимально быстрого доступа к ним. Его основная задача — быстро возвращать значение по ключу, что активно применяется, когда нужно оптимизировать доступ к более медленной, основной базе данных.
Например, чтобы ускорить получение информации о популярном посте на Хабре, можно сохранить уже готовую HTML-страницу или JSON с данными этого поста в кэше по ключу (ID поста). При следующем запросе мы мгновенно достанем его из кэша по ключу, не нагружая основную базу данных. Самые распространённые кэши — это Redis и Memcached.
Redis хранит данные в оперативной памяти, но при этом обеспечивает персистентность (сохранность данных после перезагрузки) за счёт двух механизмов: снэпшотов (RDB), когда он периодически сохраняет всё состояние на диск, или AOF (Append-Only File), когда он логгирует на диск каждую операцию записи. Эти механизмы работают независимо и могут использоваться по отдельности или вместе для обеспечения разной степени надёжности и удобства восстановления данных.
Примеры использования кэша:
Кэширование результатов часто выполняемых запросов к базе данных для ускорения доступа к данным.
Хранение сессий пользователей в веб-приложениях для уменьшения нагрузки на основную базу данных.
Wide-Columnlar
А что делать, если нам нужно очень-очень много писать? Например, сообщения в онлайн-мессенджере или данные с IoT-устройств? Тут обычная реляционная база данных не справится с нагрузкой на запись.
Здесь на помощь подходит вид хранилища под названием "широкие колонки" (Wide-Column). Самым популярным представителем является Cassandra, которую изначально разработали в Facebook для поиска по входящим сообщениям. Форк Cassandra также активно используется для реализации ленты новостей и сообщений в социальной сети Одноклассники.
Cassandra строится на основе LSM-дерева (Log-structured merge-tree). Если просто, все операции записи сначала попадают в быструю структуру в памяти (Memtable), а затем асинхронно сбрасываются на диск в виде неизменяемых файлов (SSTables). Это делает запись невероятно быстрой, так как нет необходимости искать нужную ячейку на диске и перезаписывать её. Чтение может быть медленнее, но для write-heavy (когда запись происходит чаще, чем чтение) нагрузок это идеальное решение.
Ключевой особенностью Cassandra является её линейная масштабируемость: чтобы увеличить мощность, просто добавьте новые узлы в кластер. Данные распределяются (шардируются) между узлами на основе Partition Key (ключа партиции). Все строки с одинаковым Partition Key гарантированно хранятся на одном узле, что обеспечивает быстрый доступ к связанным данным в рамках партиции.
Примеры использования Wide-Columnlar (широких колонок):
Хранение постов пользователей в социальных сетях, и их распространение для миллионов пользователей с преимущественно записью.
Обработка данных с IoT-устройств, генерирующих большие объёмы данных в реальном времени.
Columlar
Колоночные базы данных — это хранилища, которые физически хранят данные по колонкам, а не по строкам. Самый известный представитель — ClickHouse от Яндекса.
В отличие от традиционных БД, где все значения одной строки (например, ID, Имя, Фамилия, Возраст) лежат на диске рядом, в колоночных базах рядом лежат все значения одной колонки (все ID, затем все Имена, все Фамилии). Это даёт два преимущества:
Фантастическое сжатие данных, так как данные одного типа (например, числа) сжимаются гораздо лучше, чем разнородные.
Высокая скорость аналитических запросов. Если вам нужно посчитать средний возраст пользователей (
SELECT AVG(age) FROM users
), база прочитает с диска только одну колонкуage
, а не всю таблицу.
Колоночные базы данных — это идеальный представитель OLAP-систем, где скорость анализа огромных объемов данных критична. Использование ключа сортировки (ORDER BY
) в ClickHouse — это не просто рекомендация, а фундамент производительности. Он определяет, в каком физическом порядке данные будут лежать на диске. Это важно, потому что:
На основе этого ключа автоматически строится первичный индекс — главный помощник при поиске.
Когда вы фильтруете данные по столбцам, входящим в
ORDER BY
(например,WHERE date = '2023-10-01' AND user_id = 123
), ClickHouse может мгновенно найти нужные "куски" данных на диске, пропуская всё остальное. Без правильногоORDER BY
ему пришлось бы перебирать всё — а это очень медленно на петабайтах.
Примеры использования колоночных баз данных:
Аналитика продаж в ритейле, где требуется агрегирование данных по большим объёмам транзакций.
Логирование и анализ системных событий в крупных распределённых системах.
Документные базы данных
Документные базы данных — это вид NoSQL-хранилищ, которые хранят данные в виде документов, обычно в формате JSON или его бинарном аналоге BSON. Самый популярный представитель — это MongoDB.
Внутренне это выглядит так: каждый документ — это самодостаточная структура со своими полями и значениями (обычно JSON-объект), которая может иметь вложенные документы и массивы. Это очень удобно для программистов, так как структура документа в базе часто напрямую соответствует объекту в коде. Данные хранятся в коллекциях (аналог таблиц в SQL). Для быстрого поиска MongoDB позволяет создавать индексы по любым полям документа, даже по вложенным. Это избавляет от необходимости делать JOIN
и позволяет быстро получать всю связанную информацию одним запросом.
Примеры использования документоориентированных БД:
Хранение профилей пользователей в социальных сетях со сложной и изменяемой структурой данных.
Управление конфигурациями устройств, где каждый документ может представлять собой конфигурацию конкретного устройства.
Графовые базы данных
Графовая база данных — это система, созданная для хранения данных в виде графа, состоящего из вершин (узлов) и рёбер (связей).
Тут же возникает вопрос: а зачем? В каком случае она может понадобиться? А я вам скажу: она нужна в одном простом случае — когда нужно быстро и эффективно работать со связями между сущностями. Например, при проектировании социальной сети в графовой базе данных вы можете хранить информацию о друзьях или подписках на группы. Запрос вида «найти всех друзей моих друзей, которые живут в Москве» выполнится в графовой базе данных разы быстрее, чем в SQL.
Также графовые базы данных незаменимы в задачах построения рекомендательных систем, поиска мошеннических схем и анализа сложных сетей (например, логистических или телекоммуникационных).
Самый известный представитель — Neo4j .
Под капотом графовые базы данных хранят узлы и рёбра как основные сущности. Вместо того чтобы вычислять связи через JOIN-операции, они хранят прямые указатели от одной вершины к другой (через списки смежности). Благодаря этому обход графа — это просто переход по указателям в памяти или на диске, что невероятно быстро.
Примеры использования графовых БД:
Моделирование и анализ социальных графов для выявления сообществ и рекомендаций.
Обнаружение мошеннических схем в финансовых транзакциях путём анализа связей между участниками.
Поисковые движки
Инвертированный индекс — это структура данных, которая хранит отображение из контента (например, слов) в его расположение в документе или наборе документов. Соответственно, базы данных, которые строятся на этом принципе, — это поисковые движки.
Самый известный представитель — Elasticsearch. Без баз данных на основе инвертированных индексов просто невозможно построить ни один современный поиск (текстовый, по логам, по каталогу товаров).
Внутренне такие хранилища строятся следующим образом: для каждого слова (терма) в документе создаётся запись в индексе, которая указывает на все документы, где это слово встречается. Когда вы делаете поисковый запрос, движок мгновенно находит все документы по нужным словам, а затем ранжирует их по релевантности.
Примеры использования инвертированных индексов:
Реализация полнотекстового поиска по каталогу товаров в интернет-магазине.
Анализ логов серверов для выявления аномалий и ошибок.
Time Series Database
TSDB (Time Series Database) — это специализированное хранилище, заточенное под данные, где временная метка — главный ключ. Хотя они часто ассоциируются с метриками серверов, их применение гораздо шире: любые потоки событий или измерений, строго привязанных ко времени, от финансовых котировок до действий пользователей в приложении. Самый распространённый представитель TSDB — InfluxDB.
Внутреннее устройство TSDB оптимизировано для работы с временными рядами. Данные физически группируются и сжимаются по времени. Используются специальные алгоритмы сжатия, которые отлично работают на монотонно растущих временных метках и значениях. Это позволяет эффективно хранить огромные объёмы данных и очень быстро выполнять запросы по временным диапазонам.
Примеры использования БД временных рядов:
Хранение данных о финансовых тиках на бирже.
Хранение метрик мониторинга.
NewSQL
NewSQL — это класс современных распределённых реляционных баз данных, которые стремятся объединить лучшее из двух миров: горизонтальную масштабируемость NoSQL-систем с полными ACID-гарантиями традиционных SQL-баз. По сути, это попытка преодолеть главный недостаток классических реляционных СУБД: сложность масштабирования OLTP-нагрузок без потери транзакций и строгой консистентности.
Самые известные представители — YDB (Yandex Database) и CockroachDB.
Такой вид хранилищ используется для высоконагруженных OLTP-систем, которые требуют и строгой консистентности, и горизонтального масштабирования. Они часто совмещают в себе плюсы OLTP и OLAP, что называется HTAP (Hybrid Transactional/Analytical Processing — гибридная транзакционная/аналитическая обработка).
NewSQL является мощным инструментом для очень специфичных задач, когда нужны транзакции для больших данных и возможность горизонтального масштабирования. Но для большинства проектов проверенные PostgreSQL, MySQL остаются проще, дешевле и надежнее. Это не замена, а специализированное решение для тех, кто "перерос" классические БД.
Примеры использования NewSQL:
Высоконагруженные e-commerce платформы, требующие строгой консистентности и масштабируемости.
Финансовые системы, обрабатывающие большое количество транзакций в реальном времени.
Смежные технологии и системы хранения
Есть отдельные инструменты, которые не всегда являются базами данных в классическом понимании, но используются для хранения или обработки данных.
Системы обработки больших данных
Есть отдельные фреймворки, предназначенные для распределённой обработки огромных объёмов данных (петабайты данных). К таким системам относятся Hadoop (с его файловой системой HDFS), Spark и YTsaurus. Они не являются базами данных для вашего приложения, а скорее платформой для batch или stream-обработки данных в аналитических целях.
Примеры использования систем обработки больших данных:
Анализ данных о поведении пользователей в крупных онлайн-сервисах для улучшения пользовательского опыта.
Обработка спутниковых данных для мониторинга климатических изменений.
S3 (Object Storage)
Объектное хранилище (S3 — Simple Storage Service) — это сервис для хранения файлов (объектов) в виде неструктурированных данных. Ключевое отличие от файловой системы в том, что у него плоская структура. Вы обращаетесь к объекту по уникальному ключу. S3 обеспечивает высочайшую надёжность, масштабируемость и низкую стоимость хранения. Идеально подходит для бэкапов, медиаконтента (видео, фото), статических данных сайта.
Примеры использования S3:
Хранение бэкапов данных для обеспечения их надёжности и доступности.
Хранение медиафайлов (видео, фото) для использования в контент-менеджменте.
CDN (Content Delivery Network)
CDN — это географически распределённая сеть серверов, которая кэширует контент (картинки, видео, статику) как можно ближе к конечным пользователям. Это не хранилище в прямом смысле, а слой доставки, который кардинально снижает задержку при загрузке контента для пользователей из разных уголков мира.
Примеры использования CDN:
Распределение статического контента (изображения, стили CSS, JavaScript-файлы) для ускорения загрузки веб-сайтов.
Доставка видеопотоков пользователям по всему миру с минимальной задержкой.
Некоторые кейсы
Также я написал небольшую подборку кейсов, которая позволит разобрать ещё больше примеров, какой тип хранилища лучше использовать и их преимущества.
Решаемая задача |
Требуемое хранилище |
Объяснение, почему выбрано хранилище |
Хранение профилей пользователей в социальной сети с сложной и изменяемой структурой данных |
Документная БД (MongoDB) |
Гибкость и возможность хранения сложных структур данных |
Запись данных с IoT-устройств, генерирующих большие объёмы данных в реальном времени |
Wide-Columnlar (Cassandra) |
Высокая пропускная способность на запись и горизонтальное масштабирование |
Аналитика продаж в ритейле, где требуется агрегирование данных по большим объёмам транзакций |
Колоночная БД (ClickHouse) |
Быстрая скорость аналитических запросов и эффективное сжатие данных |
Реализация полнотекстового поиска по каталогу товаров в интернет-магазине |
Поисковый движок (Elasticsearch) |
Быстрый поиск по ключевым словам и релевантность результатов |
Хранение метрик мониторинга серверов |
TSDB (Prometheus) |
Оптимизация для работы с временными рядами и эффективное хранение данных |
Обработка большого количества транзакций в реальном времени в финансовой системе |
NewSQL (YDB) |
Строгая консистентность и горизонтальное масштабирование |
Анализ данных о поведении пользователей в крупных онлайн-сервисах |
Системы обработки больших данных (Apache Hadoop) |
Распределённая обработка огромных объёмов данных |
Хранение бэкапов данных для обеспечения их надёжности и доступности |
S3 (Object Storage) |
Высочайшая надёжность, масштабируемость и низкая стоимость хранения |
Распределение статического контента (изображения, стили CSS, JavaScript-файлы) для ускорения загрузки веб-сайтов |
CDN (Content Delivery Network) |
Снижение задержки при загрузке контента для пользователей из разных уголков мира |
Моделирование и анализ социальных графов для выявления сообществ и рекомендаций |
Графовая БД (Neo4j) |
Эффективная работа со связями между сущностями и быстрый обход графа |
Саммари
В статье мы разобрали:
различные типы хранилищ данных, включая SQL, Key-Value, Wide-Column, Columnar, документные, графовые, поисковые движки, TSDB, NewSQL;
особенности и преимущества каждого типа хранилища;
примеры использования различных хранилищ в реальных сценариях;
смежные технологии и системы хранения, такие как системы обработки больших данных, S3 и CDN.
Помните главное: идеального хранилища "на все случаи жизни" не существует. Каждое решение — это компромисс. Выбирая базу, вы всегда будете жертвовать чем-то ради чего-то другого. Поэтому спросите себя: что для вашей задачи критичнее? Скорость чтения или записи? Данные чаще читают или пишут? А может, ключевой фактор — это возможность легко масштабироваться горизонтально? Eventual consistency в NoSQL может привести к временным аномалиям в согласованности данных. А транзакции в SQL — к низкой производительности из-за блокировок.
Важно правильно пределять приоритеты, и тогда выбор становится яснее.
Спасибо большое за прочтение статьи!
Комментарии (16)
vanxant
29.06.2025 14:21OLAP/OLTP и SQL/NoSQL это две разные характеристики, зачем вы их смешиваете?
Все "большие" SQL СУБД могут и OLAP, и OLTP. При этом делать OLAP на каком-нибудь Redis - ну, мсье знает толк.
erogov
29.06.2025 14:21Тут, увы, все смешано. Например, колоночное и построчное хранение — тоже перпендикулярная к SQL характеристика.
Kwisatz
Нет не были, тогда их еще в проекте небыло. Для этого придумали денормализацию и другие трюки.
В остальном статья очень по верхам, если вам действительно надо систематизировать свои знания, вы берете PostgreSQL, ставите ее и используете. Ну может быть elastic можно оставить если вам лениво FTS осваивать. Если вдруг в какой то момент вам понадобится колоночное хранилище, подключаете расширение и пользуетесь, аналогично со всем остальным. NoSQL вам не будет нужен, никогда, совсем, вообще, а если будет и вы будете точно понимать что вы делаете то jsonb, может даже с индексацией. Про графовые бд даже их создатели в статьях не могут написать зачем ни нужны, так что и вам ненадо.
Все что я хочу сказать, на старте вы не пытаетесь изучить мир аот астрономии до квантовой физики, это ник чему не приведет, вы берете один инструмент и изучаете его хорошо. А "учиться проходить system design интервью " ненадо. Без хороших знаний вы все равно бесполезны, а с ними получается что для 99% компаний PostgreSQL покрывает все потребности на десятилетия.
vanxant
Ну нет, почему же. Кэшировать запросы на чтение перед PostgreSQL вполне себе:)
Kwisatz
Зачем? Даже если у вас миллион пользователей, спокойно обойдется без кеша если руки правильно растут. А если пользователей больше то вы либо покупаете сервер либо вы уже умнее 99 процентов ))
Politura
В таком случае стоило-бы сразу уточнить, что слова "не будет нужен, никогда, совсем, вообще" относятся исключительно к маленькому пет-проекту, а не к тому времени, когда надо будет работать за зарплату бакендером. :)
Kwisatz
нет не относятся. Большинство разработчиком не столкнется с хайлоадом никогда в своей жизни а с оптимизацией еще меньше, потому что как правило если у компании нечто похоже на хайлоад то дешевле сервера покупать. А оптимизацией хайлоада займется дай боже 0.01-0.1% разработчиков
Politura
Причем здесь хайлоад? Обычная stateless архитектура, которая сейчас у каждого первого стартапа и вот нам нужно где-то держать данные сессии разделяемые разными инстансами, а значит здравствуй Редис, или его аналоги, ибо хранить стейт сессии в базе данных будет только тот, кому не жалко деньгами разбрасываться. А значит сожрут его более эффективные конкуренты.
Можно стейтфул на sticky sessions, но это уже не так надежно - сервер упал и все сессии, что на нем были, слетели, да и сложнее его балансировать, мейнтейнить и тд.
Zulu0
Ну даже при всем этом лучше иметь два независимых ядра на разных хранилищах. Иначе при больших нагрузках есть риск потерять сразу все данные. И тут вопрос: постгря обычная или про, или опенсорсный nosql. Так что всегда есть вопросы, на которые надо знать ответы. И это не просто подготовить поверхности для собеса.
Kwisatz
Нет такого риска, это oltp хранилище
Но бэкапа и реплики никто не отменял, с нагрузкой это правда не связано
Zulu0
Так и я о чем. Вопрос в том, что иногда надо понимать какой инструмент использовать. Нет, конечно, универсальная отвертка с запасом наконечников это классно. Но мне, вот например, для закручивания мебельных болтов, больше подходит шестигранник буквой гы. А если он еще и стоит дешевле чем отвертка, а если в комплекте с мебелью, мммм. Надеюсь вы аллегорию уловили.
Kwisatz
Не уловил, все это говорят нонстоп но для отвёрток можно прочесть куда где и что, а вот в айти как правило если начать задавать вопросы, то быстро выясняется что аргументов то и нет. Не всегда конечно, но довольно часто
mirwide
У меня был удивительный, для меня, опыт, когда замена Elasticsearch на Pоstgre для отдачи нескольких полей по ключу ухудшила латенси в несколько раз. Всё потому, что в Elasticsearch это параллельный поиск по всем шардам, все данные в одном документе. А для Pоstgre нужен джойн нескольких таблиц, для каждой прочитать индекс, потом данные. Если делать денормализацию, нужен ли там Pоstgre. Это было ещё при не совпадении в Elasticsearch ключа шардирования и поиска. И по ключу, без всяких расстояний Левенштейна.
Kwisatz
Но и требования к эластика к ресурсам совершенно конские. Но в общем случае вы правы, однако если это было заметное латенси то что-то СИЛЬНО неправильное происходило с вашей базой
mirwide
Про то, что даже в сценариях где Pоstgre выглядит оптимальным решением, это не всегда так. А есть еще много случаев где он даже теоретически не подходит: хранить сессии пользователей с TTL в час и рейтом чтения десятки тысяч rps или писать Тб данных в день, которые читаются с рейтом 1 rps.
Kwisatz
Все вполне себе нормально с рейтом десятки тысяч rps postgresql: я пару лет назад оптимизировал такие запросы до микросекунд. Если вы пишете ТД в день и вам нужен OLTP то с PG все впорядке, если не нужен то цепляете колоночное хранилище и еще более в порядке.