Привет, хабр!

Меня зовут Кирилл, и на протяжении последних двух лет я мечтал научиться проходить 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, затем все Имена, все Фамилии). Это даёт два преимущества:

  1. Фантастическое сжатие данных, так как данные одного типа (например, числа) сжимаются гораздо лучше, чем разнородные.

  2. Высокая скорость аналитических запросов. Если вам нужно посчитать средний возраст пользователей (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)


  1. Kwisatz
    29.06.2025 14:21

    Именно для таких специфичных кейсов и были придуманы NoSQL-решения.

    Нет не были, тогда их еще в проекте небыло. Для этого придумали денормализацию и другие трюки.

    В остальном статья очень по верхам, если вам действительно надо систематизировать свои знания, вы берете PostgreSQL, ставите ее и используете. Ну может быть elastic можно оставить если вам лениво FTS осваивать. Если вдруг в какой то момент вам понадобится колоночное хранилище, подключаете расширение и пользуетесь, аналогично со всем остальным. NoSQL вам не будет нужен, никогда, совсем, вообще, а если будет и вы будете точно понимать что вы делаете то jsonb, может даже с индексацией. Про графовые бд даже их создатели в статьях не могут написать зачем ни нужны, так что и вам ненадо.

    Все что я хочу сказать, на старте вы не пытаетесь изучить мир аот астрономии до квантовой физики, это ник чему не приведет, вы берете один инструмент и изучаете его хорошо. А "учиться проходить system design интервью " ненадо. Без хороших знаний вы все равно бесполезны, а с ними получается что для 99% компаний PostgreSQL покрывает все потребности на десятилетия.


    1. vanxant
      29.06.2025 14:21

      NoSQL вам не будет нужен, никогда, совсем, вообще

      Ну нет, почему же. Кэшировать запросы на чтение перед PostgreSQL вполне себе:)


      1. Kwisatz
        29.06.2025 14:21

        Зачем? Даже если у вас миллион пользователей, спокойно обойдется без кеша если руки правильно растут. А если пользователей больше то вы либо покупаете сервер либо вы уже умнее 99 процентов ))


        1. Politura
          29.06.2025 14:21

          В таком случае стоило-бы сразу уточнить, что слова "не будет нужен, никогда, совсем, вообще" относятся исключительно к маленькому пет-проекту, а не к тому времени, когда надо будет работать за зарплату бакендером. :)


          1. Kwisatz
            29.06.2025 14:21

            нет не относятся. Большинство разработчиком не столкнется с хайлоадом никогда в своей жизни а с оптимизацией еще меньше, потому что как правило если у компании нечто похоже на хайлоад то дешевле сервера покупать. А оптимизацией хайлоада займется дай боже 0.01-0.1% разработчиков


            1. Politura
              29.06.2025 14:21

              Причем здесь хайлоад? Обычная stateless архитектура, которая сейчас у каждого первого стартапа и вот нам нужно где-то держать данные сессии разделяемые разными инстансами, а значит здравствуй Редис, или его аналоги, ибо хранить стейт сессии в базе данных будет только тот, кому не жалко деньгами разбрасываться. А значит сожрут его более эффективные конкуренты.

              Можно стейтфул на sticky sessions, но это уже не так надежно - сервер упал и все сессии, что на нем были, слетели, да и сложнее его балансировать, мейнтейнить и тд.


    1. Zulu0
      29.06.2025 14:21

      Ну даже при всем этом лучше иметь два независимых ядра на разных хранилищах. Иначе при больших нагрузках есть риск потерять сразу все данные. И тут вопрос: постгря обычная или про, или опенсорсный nosql. Так что всегда есть вопросы, на которые надо знать ответы. И это не просто подготовить поверхности для собеса.


      1. Kwisatz
        29.06.2025 14:21

        Нет такого риска, это oltp хранилище

        Но бэкапа и реплики никто не отменял, с нагрузкой это правда не связано


        1. Zulu0
          29.06.2025 14:21

          Но бэкапа и реплики никто не отменял, с нагрузкой это правда не связано

          Так и я о чем. Вопрос в том, что иногда надо понимать какой инструмент использовать. Нет, конечно, универсальная отвертка с запасом наконечников это классно. Но мне, вот например, для закручивания мебельных болтов, больше подходит шестигранник буквой гы. А если он еще и стоит дешевле чем отвертка, а если в комплекте с мебелью, мммм. Надеюсь вы аллегорию уловили.


          1. Kwisatz
            29.06.2025 14:21

            Не уловил, все это говорят нонстоп но для отвёрток можно прочесть куда где и что, а вот в айти как правило если начать задавать вопросы, то быстро выясняется что аргументов то и нет. Не всегда конечно, но довольно часто


    1. mirwide
      29.06.2025 14:21

      NoSQL вам не будет нужен, никогда, совсем, вообще

      У меня был удивительный, для меня, опыт, когда замена Elasticsearch на Pоstgre для отдачи нескольких полей по ключу ухудшила латенси в несколько раз. Всё потому, что в Elasticsearch это параллельный поиск по всем шардам, все данные в одном документе. А для Pоstgre нужен джойн нескольких таблиц, для каждой прочитать индекс, потом данные. Если делать денормализацию, нужен ли там Pоstgre. Это было ещё при не совпадении в Elasticsearch ключа шардирования и поиска. И по ключу, без всяких расстояний Левенштейна.


      1. Kwisatz
        29.06.2025 14:21

        Но и требования к эластика к ресурсам совершенно конские. Но в общем случае вы правы, однако если это было заметное латенси то что-то СИЛЬНО неправильное происходило с вашей базой


        1. mirwide
          29.06.2025 14:21

          Про то, что даже в сценариях где Pоstgre выглядит оптимальным решением, это не всегда так. А есть еще много случаев где он даже теоретически не подходит: хранить сессии пользователей с TTL в час и рейтом чтения десятки тысяч rps или писать Тб данных в день, которые читаются с рейтом 1 rps.


          1. Kwisatz
            29.06.2025 14:21

            Все вполне себе нормально с рейтом десятки тысяч rps postgresql: я пару лет назад оптимизировал такие запросы до микросекунд. Если вы пишете ТД в день и вам нужен OLTP то с PG все впорядке, если не нужен то цепляете колоночное хранилище и еще более в порядке.


  1. vanxant
    29.06.2025 14:21

    OLAP/OLTP и SQL/NoSQL это две разные характеристики, зачем вы их смешиваете?

    Все "большие" SQL СУБД могут и OLAP, и OLTP. При этом делать OLAP на каком-нибудь Redis - ну, мсье знает толк.


    1. erogov
      29.06.2025 14:21

      Тут, увы, все смешано. Например, колоночное и построчное хранение — тоже перпендикулярная к SQL характеристика.