Это первый выпуск в серии статей про СУБД, в рамках которых буду достаточно простыми словами давать информацию про то, что сейчас есть на рынке баз данных, и что выбрать для решения своих задач.

Заметил, что когда спрашиваешь кого-нибудь, особенно на собеседовании, какие типы СУБД существуют, то первое что вспоминают многие – это реляционные базы данных, и NoSQL, а вот про разновидности часто забывают или не могут сформулировать их отличие. Поэтому начнем с простого перечисления наиболее используемых.

  1. Реляционные

  2. Ключ-значение

  3. Документные

  4. Графовые

  5. Колоночные

Тем, кому не хочется долго читать, может сразу перейти на итоговую таблицу.

Нужно обязательно сделать ремарку, что некоторые крупные производители, имеют в своем арсенале несколько типов СУБД, как в виде отдельных продуктов, так и в виде внутренней реализации. Например, у Oracle на самом деле чего только нет, начиная с классической реляционной СУБД, продолжая с отдельным продуктом Oracle NoSQL Database, который может использоваться и как документная, и как колоночная, и как ключ-значение. Отдельное решение от того же Oracle, Autonomous Data Warehouse – это уже специализированное решение для хранилищ данных. Еще один отдельный продукт от Oracle – Oracle Graph Server для работы с графами, и еще много другого. Этому можно посвятить отдельную серию статей.


Реляционные СУБД

Начнем по порядку, классические, реляционные СУБД чаще всего используются для построения решений OLTP (Online Transaction Processing). В таких решениях СУБД работает с небольшими по размерам транзакциями, но идущими большим потоком, и при этом от системы требуется минимальное время отклика, а так же возможность, при определенных условиях, отменить любые изменения выполняемых в рамках транзакции. Если вы строите систему, в рамках которой требуется хранить значительное количество сущностей (таблиц), с различными типами связей между ними (один-к-одному, один-к-многим, многие-ко-многим), то это скорее всего про реляционные СУБД.

Наиболее известные СУБД такого типа - Oracle, Microsoft SQL, PostgreSQL, MySQL.

Когда выбирать реляционную СУБД

Один из основных признаков, который говорит о том что нужно выбирать реляционную СУБД – это высокая нормализация данных. Дополнительными признаками будет необходимость обработки большого кол-ва коротких транзакций, с большей долей операций на вставку

Когда не выбирать реляционную СУБД

Если предполагается хранить не структурируемые данные, или наоборот очень простые структуры типа ключ-значение, то лучше посмотреть в сторону документных СУБД и специализированных СУБД типа ключ-значение соответственно.

Так же один из признаков, что имеет смысл подумать не о реляционных СУБД, это такой факт как необходимость часто обновлять значения в одних и тех же строках. Обычно это обходится "дорого" в реляционных СУБД, и нужно применять "продвинутую магию" что бы делать это корректно.

Конечно, тут есть много «но», или «а если очень хочется», и других ситуаций, когда данные рекомендации можно игнорировать. Это нормально, особенно когда за дело берется эксперт, который знает как это сделать.


СУБД типа ключ-значение

Наверное один из самых простых типов СУБД. В упрощенном виде, это некая таблица с уникальным ключом и собственно связанным с ним значением, в котором может быть что угодно. Чаще всего такие СУБД используют для кэширования, т.к. они очень быстро работают, а это и не сложно, когда есть уникальный ключ, и запрос возвращает только одно значение. У некоторых представителей данных СУБД есть возможность работать полностью в памяти, а так же есть возможность задавать срок жизни записи, после истечения которого, записи будут автоматически удаляться.

Наиболее известные СУБД такого типа - Redis и Memcached.

Когда выбирать СУБД ключ-значение

Если СУБД будет использоваться для кэширования данных или для брокеров сообщений, то это очень подходящий тип. Так же, такая СУБД хорошо подходит для баз где нужно хранить достаточно простые структуры, и иметь к ним очень быстрый доступ.

Когда не выбирать СУБД ключ-значение

Если вы предполагаете хранить в базе данных много сущностей (таблиц), а у сущностей будут сложные структуры с разными типами данных. Так же, если вы предполагаете делать из этой таблицы сложные запросы которые возвращают множества строк.


Документные СУБД

Документные или документно-ориентированные СУБД - это одна из наиболее популярных разновидностей NoSQL СУБД, где основной единицей логической модели данных является документ - структурированный текст, с определенным синтаксисом.

Иногда встречаются мнения что модель данных в документных БД похожа на модель данных в объектно-ориентированных базах данных. В этом есть доля правды, единственная реальная разница между ними заключается в том, что базы данных документов только сохраняют состояние, но не поведение.

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

Интересно, что документные СУБД развиваются достаточно активно, и сейчас некоторые из них, в том числе, поддерживают проверку схемы.

Известными представителями таких СУБД являются CouchDB, MongoDB, Amazon DocumentDB.

Когда выбирать документную СУБД

Если нужно хранить объекты в одной сущности, но с разной структурой. Если нужно хранит структуры, включая объекты, списки и словари, особенно в формате близкому к JSON.

На самом деле область применения документных СУБД очень широкая. Их можно использовать как компактную базу данных для отдельно взятого микро-сервиса, так и для вполне масштабных решений, в качестве хранилища состояний чего-либо.

Когда не выбирать документную СУБД

Не самое лучшее решение для реализации транзакционная модели, и точно не лучший вариант для формирования отчетности.


Графовые СУБД

Графовые СУБД - специфичный тип, предназначены для работы с графами, с их узлами, свойствами, и произвольными отношениями между узлами.

Очень простой пример, это организация связей в различного типа социальных сетях, где нужно хранить связи между пользователями (узлами) по разным критериям (родственные связи, коллеги, общие интересы).

Известные представители этого типа субд - Neo4j, Amazon Neptune, InfiniteGraph, InfoGrid.

Когда выбирать графовые СУБД

Точно стоит обратить внимание на графовые СУБД, если строите какое-то подобие социальной сети, или реализуете систему оценок и рекомендаций. Ну и во всех случаях когда вы хорошо понимаете что такое графы, и для чего это нужно.

Когда не выбирать графовые СУБД

Практически во всех остальных случаях, кроме указанных выше, лучше воздержаться от использования графовых СУБД.


Колоночные СУБД

Колоночные СУБД очень похожи на реляционные. Они так же состоят из строк, которые имеют атрибуты, а строки группируются в таблицах. Различия в логических моделях несущественные, а вот на уровне физического хранения данных различия значительные.

В реляционных СУБД данные хранятся "построчно", это означает что для считывания значения определенной колонки, придется прочитать практически всю строку, как минимум от первой до нужной колонки. В колоночной СУБД данные хранятся "поколоночно", т.е. колонка - это как отдельная таблица. Соответственно чтение будет происходить из конкретного столбца сразу. На практике это реально работает очень быстро (проверено мной на нескольких реализованных хранилищах данных).

Основные преимущества колоночных СУБД – эффективное выполнения сложных аналитических запросов на больших объемах, и легкое, практически мгновенное, изменение структуры таблиц с данными, плюс существенная компрессия и сжатие, которое позволяет значительно экономить место.

Яркие представители колоночных СУБД - Sybase IQ (ныне SAP IQ), Vertica, ClickHouse, Google BigTable, InfoBright, Cassandra.

Когда выбирать колоночные СУБД

Один из весомых аргументов за использование именно колоночной СУБД - это если вы хотите построить хранилище данных, и планируете делать выборки со сложными аналитическими вычислениями. Косвенный признак, который так же может сигнализировать о том, что имеет смысл, хотя бы посмотреть в сторону колоночных СУБД - это если количество строк, из которых делаются выборки, превышает сотни миллионов.

Когда не выбирать колоночные СУБД

Учитывая специфику колоночных СУБД, будет не эффективно ее использовать, если выборки достаточно простые, параметры выборки статичны, и если преобладают выборки по ключевым значениям. Так же, если количество строк в таблице, из которой делается выборка, меньше сотен миллионов строк, то скорее всего не будет большого преимущества, по сравнению с реляционной СУБД.

Нужно так же иметь ввиду, что в колоночных СУБД могут быть и другие ограничения. Например, может отсутствовать поддержка транзакций, а язык запросов может отличаться от классического SQL, и прочее.


Итоги

Важное замечание – не пытайтесь сразу все задачи решить в рамках одной СУБД. Это более чем нормально иметь несколько разных типов СУБД. Так же, не пытайтесь сразу определиться с производителем СУБД, или связать свою жизнь с одним конкретным брендом.

При выборе типа СУБД следует, прежде всего, исходить из типа решаемых задач, типов обрабатываемых данных, перспектив роста и масштабирования.

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

В данной статье я намеренно не делаю акцент на выбор между облачными и on-premise решениями - эта тема одной из следующих статей.

Итак, в таблице представленной ниже, кратко собрано то, что описано выше в статье.

Тип СУБД

Когда выбирать

Примеры популярных СУБД

Реляционные

Нужна транзакционность; высокая нормализация; большая доля операций на вставку

Oracle, MySQL, Microsoft SQL Server, PostgreSQL

Ключ-значение

Задачи кэширования и брокеры сообщений

Redis, Memcached

Документные

Для хранения объектов в одной сущности, но с разной структурой; хранение структур на основе JSON

CouchDB, MongoDB, Amazon DocumentDB

Графовые

Задачи подобные социальным сетям; системы оценок и рекомендаций

Neo4j, Amazon Neptune, InfiniteGraph, InfoGrid

Колоночные

Хранилища данных; выборки со сложными аналитическими вычислениями; количество строк в таблице превышает сотни миллионов

Vertica, ClickHouse, Google BigTable, Sybase \ SAP IQ, InfoBright, Cassandra

Надеюсь данная статья оказалась полезной.

В следующих статьях посмотрим на выбор между облачными и on-premise СУБД, платными и бесплатными, и многое другое.

Комментарии (39)


  1. saboteur_kiev
    21.09.2021 21:52
    -3

    "документно-ориентированные СУБД" это видимо от слова документны ?

    memcached сложно назвать базой данных, это скорее система кеширования. А для redis есть термин - это представитель no-sql баз данных.

    Еще вы забыли о явно выделяющихся в отдельный класс TSDB

    И я бы не назвал MongoDB документо-ориентированной. Это объектно-ориентированная база данных.


    1. h1pp0
      21.09.2021 22:48
      +2

      И я бы не назвал MongoDB документо-ориентированной.

      "MongoDB is a source-available cross-platform document-oriented database program" из вики

      В туториале они тоже называют себя именно документо-ориентированной базой


      1. saboteur_kiev
        27.09.2021 13:54
        -1

        Вот только в том же туториале они парой слов позже поясняют, что они имеют ввиду под словом документ:

        MongoDB documents are similar to JSON objects

        Documents (i.e. objects) correspond to native data types in many programming languages.

        В английском языке, слово document в общем значении имеет конечно текстовый документ с информацией или инструкцией, зачастую даже бумажный.
        Но применительно к компьютерной терминологии, больше имеет значение как файл со своей структурой и информацией, то есть по сути - объект. И при переводе эта специализация теряется.



  1. Scank
    21.09.2021 21:52
    +1

    Отличная статья для новичков! Спасибо.


  1. mentin
    22.09.2021 03:20
    +2

    Яркие представители колоночных СУБД - .... Google BigTable,

    Думаю вы перепутали с Google BigQuery.

    BigTable совсем другая технология, ближе к ключ-значение. Хотя и элементы хранения по колонкам там есть, но в этом списке ей точно не место.


    1. YevSam Автор
      22.09.2021 07:50

      Спасибо за замечание.

      BigQuery конечно будет релевантнее, ведь в BigQuery можно делать запросы из BigTable.
      https://cloud.google.com/bigquery/external-data-bigtable#java


      1. mentin
        22.09.2021 08:06

        Я предлагаю так глубоко не рыть :). Потому что из BigQuery можно так же делать запросы и к MySQL и к PostgreSQL (если они в GCP развернуты через Cloud SQL). А к тому же Bigtable можно делать запросы не только из BigQuery, но и из PostgreSQL (есть расширение https://github.com/durch/google-bigtable-postgres-fdw). И так далее - многие базы данных умеют выставить через свой интерфейс чужие базы данных. Но это все побочные сценарии, часто идущие вразрез с основным режимом использования - просто для удобства, немного данных можно достать из внешней базы, чаще всего несколько баз нужно как раз потому что внешняя база совсем другая и данные в ней нужны для совсем другого.


        1. YevSam Автор
          22.09.2021 08:19

          Согласен.


  1. mentin
    22.09.2021 05:17
    +7

    Все переписать :) Шутка.

    Сначала надо определиться, по какому признаку верхний уровень классификации. "Реляционные" описывает высокоуровневый интерфейс, а "колоночная" описывает физическое устройство базы, вместе их использовать не надо (бывают, скажем, реляционные колоночные). На самом деле похоже базы классифицируются не по первому, и не по второму признаку, а по типу использования. Группу "реляционные" я бы назвал "транзакционные" - рассчитанные на частые транзакции, и да, чаще всего нынче у них реляционный интерфейс, но не всегда. "Колоночные" по типу использования следует назвать "аналитические", и да, нынче в них модно использовать колоночное хранение данных, но бывают и кубы и прочее.

    И конечно не забыть про прочие специализированные базы, вроде time series. Они наверное используются на практике не реже графовых.


    1. jenki
      22.09.2021 17:33

      И конечно не забыть про прочие специализированные базы, вроде time series. Они наверное используются на практике не реже графовых.

      Практически весь мониторинг строится на базах time series


  1. funny_falcon
    22.09.2021 06:16

    Google BigTable и Cassandra (а также HBase, Amazon DynamoDB и некоторые другие) - это не колоночные базы. Это wide row базы - в одной строке может быть огромное число колонок, причём их имена от колонки к колонке могут не повторятья.

    По сути же, это (Key,Key)->Value хранилища. Чуть точнее, (RowKey, ColumnName)->Value.

    Отличительная особенность колоночных баз: чтобы отфильтровать по произвольной колонке, с диска нужно прочитать и распарсить только эту колонку, записанную весьма компактно. В Cassandra для этого нужно прочитать и распарить всю базу - что сразу ставит крест на применимости термина "колоночная" к Кассандре.


  1. tobolenok
    22.09.2021 09:50

    Картинка ужас.

    В Customer зашиты Заказ и Инвойс

    В Product - цена и количество.

    Перекрестные ссылки друг на друга.

    Как сломать понимающего и запутать новичка.


  1. MilashchenkoEA
    22.09.2021 10:27
    +2

    Встраиваемую SQLite можно было бы еще упомянуть наверное в реляционных.


    1. YevSam Автор
      22.09.2021 10:29

      Согласен, добавлю.


  1. KohrAhr
    22.09.2021 10:27
    +1

    а Teradata как то вы в стороне оставили


    1. YevSam Автор
      22.09.2021 10:32

      Спасибо за комментарий. Предполагал о Teradata написать в одной из следующих статей.


  1. apapacy
    22.09.2021 11:17
    +2

    По классификации не согласен принципиально с многими утверждениями.
    Когда выбирать реоляционную базу — практически всегда если не нужно обрабатывать
    1) очень большой поток запросов
    2) хранить очень много данных
    Реляционные базы универсальны. Сейчас они могут хранить и неструкрутрированне данные в JSON или text/bonary полях. Все это хорошо пока данных становится очень много или запросов становится очень много и нужно масштабирваться. Реляционные это не умеют ока во всяком случае. Подмена на стороне сервера совместимыми с протоколом MySQL/Postgrеs клинетов распределенные азы данных конечно появились. Но имеют два недостатка: они на порядок медленнее чем сразу делают свое использование неэффективным, когда мы заменяем 1 сервер реляционной базы 10 серверами yogobyte и других эрзац-реляционных баз и получаем все еще ту же самую эжффективность запросов. Второе они пока еще очень нестабильны.
    Поэтому приходится идти на компромисы и там где все признаки необзодимости испольщовать релационные базы данных — кроме только того что нужно иметь возможность горизщонтального масшабирования — использовать как раз NoSQL базы данных только лишь потому что их можно шардировать.


  1. sanchezzzhak
    22.09.2021 12:43

    Мой список

    1. Из обычных бд postgres потом mysql(Mysql не неумеет подчищать за собой раздутые таблицы)

    2. Монго слишком дорого в обсуживание, данных под 2 тб.. 5 серверов, потихоньку делаю замену в пользу pg

    3. Колоночные - кликхаус оправдал с старта


    1. apapacy
      22.09.2021 15:05

      Из обычных бд postgres потом mysql(Mysql не неумеет подчищать за собой раздутые таблицы)

      Умел и умеет. Насколько я понял имеется в виду таблицы innodb. Действительно если выбрано хранение одним файлом то пространство один раз выделенное не сокращается. Если хранение одна таблица=один файл — пространство сокращается. В последнрих версиях MySQL такой способ хранения задается по умолчанию. А раньше был одним файлом.


      Как раз у Postgres больше проблем с раздутыми таблицами так как каждое изменения данных это фактичепски новая строка (хоня к старому варианту в явном виде доступа нет) vacuum не зря там есть такая команда


  1. OlgaRode
    22.09.2021 13:23

    Полезная статья.


  1. derikn_mike
    22.09.2021 13:33

    я вот не нашел ответов на свои вопросы:

    1) использовал mongodb для отношения лайков для видео: VideoID:[userID] , почему? потомучто есть атомарность без транзакций и блокировок , тоесть db.addIfNotExist(videoId, userId), но появилась проблема , что появились популярные люди , их посты начали собирать по N млн лайков . На их форуме "профессионалы" ты всё правильно деалешь , но надо использовать bucket паттерн , я окей... но появилась еще проблема

    2) использовав bucket паттерн поломалась пагинация , тоесть если бакеты все заполнены , то все отлично

    10 | 10 | 10 | 10

    но добавляем еще один лайк и создается новый бакет

    1 | 10 | 10 | 10 | 10

    И получается что если я возьму 1 бакет (отображаем на сайте самые новые), то выведется 1 запись , хотя можно больше .... "знаточки" предложили В КОДЕ while(count < pageSize) { db.loadMore} :D

    3) попытался создать рекомендательную систему , для этого попытался с помощью механизма mongodb CreateView найти пересечения пользователей около 10 млн , и что вы думаете ? НЕ проворачивается , просто бесконечный (PS даже в JS такая операция пересечения пару секунд проворачивает)

    Ладно про 3й пункт окей , но как быть в двумя первыми?


  1. UncleJo
    22.09.2021 20:07
    +1

    Нужная статья, но добавлю 5 копеек.

    • Для реляционных баз. что их не стоит применять для систем с большими потоками однотипных данных, пусть даже хорошо нормализованных. Индексирование снизит скорость вставки, а при недостатке ресурсов запросы будут работать очень медленно.

    • Нет информации о колоночной БД Apache Druid

    • Особенность колоночных баз, да и колоночных индексов в том, что для них невозможна операция промежуточной вставки или апдейта. Часто эти базы не предусматривают оператор UPDATE. Только DELETE и INSERT.


    1. YevSam Автор
      22.09.2021 20:10

      Спасибо за комментарий.

      Про Druid добавлю.

      Про колоночные БД - тут все зависит от конкретной СУБД.


      1. UncleJo
        22.09.2021 22:00
        +1

        Согласен, я слишком категоричен. Правильнее - INSERT и UPDATE для колоночных баз и индексов дорогие операции, часто дороже, чем для реляционных базах с индексами, построенными на основе деревьев.


  1. Odmino
    23.09.2021 08:43

    А где же про великую и ужасную DB2? Статья вполне интересная, хоть и для новичков.


    1. YevSam Автор
      23.09.2021 08:45

      Спасибо за комментарий!
      Да, можно добавить DB2 в список. Был у меня опыт работы с такой СУБД - надо отметить что очень неприхотливая.


  1. x67
    23.09.2021 21:33
    +1

    Подобных статей много.

    А вот как выбрать конкретную субд среди реляционных.. Вопрос на который нет ответа


    1. apapacy
      25.09.2021 15:59
      -1

      Так они практчески имеют одинаковую производительность и одинакоые возможности. Конечно есть sqlite и h2 которые общем случае считаются менее пригодными для высоких нагрузок, но по факту есть много умельев которыен все далают на sqlite


    1. YevSam Автор
      25.09.2021 18:58

      Выбор конкретную СУБД из множества имеющихся на рынке - хорошая идея для отдельной статьи.


  1. Dansoid
    23.09.2021 22:44
    +1

    Не забываем и NewSQL базы. Очень впечатлил SingleStore (бывший MemSQL). Когда PG начал тупить, пришлось попробовать альтернативы. И я был приятно удивлен скоростью трехэтажных запросов, где PG просто заставлял идти делать чай между попытками заставить его паралелить запросы, ведь ему дали 40 ядер, а он использует одно.


    1. YevSam Автор
      01.10.2021 15:52

      Спасибо за комментарий!

      NewSQL - это тоже интересный тип. К сожалению с ним я меньше всего знаком, но сколько было холиварных часов потрачено на споры с коллегами в свое время ))

      Обязательно потестирую SingleStore.


  1. jobgemws
    29.09.2021 22:14
    +1

    Ещё есть тип геоданных и СУБД под них.
    А вообще тренд идёт к тому, что у бывших реляционных СУБД появляются возможности для работы с NoSQL (или как ранее их называли неполно-структурированные данные) причем вполне эффективно.
    А у NoSQL СУБД появляются возможности характерные для реляционных СУБД.
    Потому с одной стороны можно сделать зоопарк из разных типов СУБД и это будет тяжело все поддерживать с тем учётом, что понадобится гораздо больше людей для обслуживания всех этих систем и разработчиков с нужными знаниями и опытом.
    С другой стороны можно выбрать одну СУБД и правильно ее готовить и лишь в тех местах, где уже нельзя выжать больше-использовать другие виды СУБД, но только если это оправдано. Такое решение проще обслуживать и не нужно искать разрабов всех мастей по всем СУБД, достаточно будет несколько экспертов по каждому типу используемой СУБД.
    И немаловажно при выборе СУБД да и вообще любой технологии ее распространение и доступность человеческих ресурсов в форме тех спецов, кто будет обслуживать и разрабатывать под эти СУБД (не по миру, а там где компания может себе позволить нанимать таких экспертов).
    Часто можно встретить сложную систему из нескольких типов СУБД, где сложно что-либо дебажить или найти причину дефекта, равно как и обслуживать этот разросшийся хаос. Хотя на самом деле для таких решений достаточно было правильно настроить и правильно разрабатывать под один тип СУБД+ (очень редко) ещё один тип СУБД.


    1. YevSam Автор
      01.10.2021 14:35
      +1

      Спасибо за комментарий!

      Да, верно про для работы с гео-данными есть специализированный тип СУБД - Spatial, я обязательно о нем напишу в следующей статье.

      По поводу выбора одной СУБД для решения разных типов задач - вы правы, так можно делать, если это оправдано, но надо понимать, что скорее всего это будет компромисс. Как правило, те СУБД, которые "заточены" на работу с определенным типом данных\активностей, работают эффективнее, чем гибридные СУБД. При этом на небольших и средних нагрузках, скорее всего никто не заметит разницы, а вот при серьезных промышленных нагрузках, high-load'е, скорее всего разница в производительности будет ощутимой.

      Во всем должен быть разумный подход. ))


      1. Jovanny
        01.10.2021 18:01
        +2

        И опять же в MS SQL Server есть тип данных geography.
        Так что разделение СУБД по типам становится всё менее и менее актуально


  1. Jovanny
    01.10.2021 14:16
    +1

    На сегогдняшний день все более-менее продвинутые СУБД поддерживают большинство типов хранения данных.
    Например, MS SQL Server. На сегодняшний день она и реляционная, и колоночная, и графовая.
    Ну, ключ-значение даже не обсуждается.
    А поддержка XML и JSON вполне позволяет отнести её и к документо-ориентированным.
    Не упомянута и Cosmos DB, которая поддерживает API всех 5 типов.


    1. YevSam Автор
      01.10.2021 14:22

      Спасибо за комментарий!

      Все верно, некоторые вендоры предоставляют несколько решений под своим брендом. Я упомянул в статье про Oracle, и конечно же Microsoft SQL так же поддерживает несколько типов.
      Про Cosmos DB добавлю.


  1. vodopad
    04.10.2021 20:13
    +1

    Тема колоночных СУБД не раскрыта, нужны бы более наглядные примеры в статью.


    1. YevSam Автор
      06.10.2021 17:42

      Спасибо за комментарий!
      Это интересная тема, готов раскрыть ее в отдельной статье.