В этой статье я постарался описать базовые знания о мире хранилищ и баз данных. Они помогут вам начать свой путь, укрепить знания или выбрать бд для своего нового проекта. Ниже будет сравнение SQL и NoSQL, описание ACID-транзакций и CAP-теоремы. Итак, поехали!
Как вы будете выбирать базу данных? Ну скорее всего, вы посмотрите в сторону реляционных баз данных. В зависимости от ваших рассуждений вы выберете свое любимое хранилище данных SQL или NoSQL и все будет работать.
Выбор правильного хранилища может сильно упростить вам работу. А выбор неправильного наоборот - превратить ее в ад.
Базы данных
Для хорошего понимания работы баз данных следует понимать из чего они как правило состоят.
Пять основных компонентов БД
Интерфейс взаимодействия или API. Каждая база данных определяет свой язык, спецификацию или API для манипуляций и контроля над данными и транзакциями.
Обработчик запросов. Это центральный процессор баз данных. Его задача обработка входящих запросов, выполнение необходимых действий и выдача результатов.
Хранилище. Дисковая или оперативная память где хранятся данные.
Индексы. Структуры данных для быстрого поиска запрашиваемых данных в хранилище.
Метаданные. Допольнительная информация о данных, индексах и хранилище (схема, размеры индексов, привелеги и т.д.).
Обработчик запросов выполняет следующие шаги для каждого входящего запроса:
Анализирует запрос и сверяет его с метаданными.
Создает эффективный план выполнения использующий индексы.
Читает или обновляет данные в хранилище.
Обновляет метаданные и индексы.
Вычисляет и выдает результаты.
Чтобы определить, какое хранилище данных соответствует потребностям вашего приложения необходимо внимательно изучить:
Операции, поддерживаемые интерфейсом или API. Если требуемые вычисления встроены, вам нужно будет писать меньше кода.
Доступные индексы. Это определит как быстро будут выполняться ваши запросы.
Далее мы рассмотрим операции и индексы в хранилищах для различных типов данных.
Хранилище BLOB-объектов
Файловая система - это самое простое и самое старое хранилище данных. Мы используем его каждый день для хранения всех типов данных. Хранилище BLOB-объектов - это гипермасштабируемая файловая система с распределенной версией, используемая для хранения неструктурированных данных.
BLOB это бэкроним от Binary Large OBject — двоичный большой объект. В нем вы можете хранить любые данные. Следовательно, хранилище данных BLOB-объектов не играет никакой роли в интерпретации данных:
Blob поддерживает CRUD-операции (создание, чтение, обновление, удаление) на файловом уровне.
Путь к каталогу или файлу - это индекс.
Табличные хранилища данных
Табличные хранилища данных подходят для хранения структурированных данных. Каждая запись (строка) имеет одинаковое количество атрибутов (столбцов) одного типа.
Есть два типа приложений:
Обработка транзакций в реальном времени (OLTP): cбор, хранение и обработка данных транзакций в режиме реального времени.
Обработка аналитики в реальном времени (OLAP): анализ агрегированных исторических данных из OLTP-приложения.
Приложениям OLTP необходимы хранилища данных, поддерживающие чтение и запись отдельных записей с малой задержкой. Приложениям OLAP требуются хранилища данных, поддерживающие высокую пропускную способность чтения большого количества записей.
Реляционная или строковая база данных
Реляционная система управления базами данных (РСУБД) - одно из самых первых хранилищ данных. Данные организованы в таблицы. Таблицы нормализованы для уменьшения избыточности и лучшей целостности данных.
Таблицы могут иметь первичный и внешний ключи:
Первичный ключ - это минимальный набор атрибутов (столбцов), который однозначно идентифицирует запись (строку) в таблице.
Внешний ключ устанавливает отношения между таблицами. Это набор атрибутов в таблице, который относится к первичному ключу другой таблицы.
Реляционные базы данных оптимизированы для транзакционных операций. Транзакции часто обновляют несколько записей в нескольких таблицах. Индексы оптимизированы для частой работы с ACID-транзакциями с малой задержкой:
Атомарность (Atomicity): любая транзакция, которая обновляет несколько строк, рассматривается как единый блок. Успешная транзакция выполняет все обновления. Неудачная транзакция не выполняет никаких обновлений, т. е. база данных остается неизменной.
Согласованность (Consistency): каждая транзакция переводит базу данных из одного допустимого состояния в другое. Это гарантирует поддержание всех инвариантов и ограничений базы данных.
Изолированность (Isolation): одновременное выполнение нескольких транзакций оставляет базу данных в том же состоянии, как если бы транзакции выполнялись последовательно.
Прочность (Durability): подтвержденные транзакции являются постоянными и выдерживают даже падения системы.
Из чего выбирать:
Без облаков: Oracle, Microsoft SQL Server, IBM DB2, PostgreSQL, MySQL.
AWS: PostgreSQL и MySQL в Relational Database Service (RDS)
Microsoft Azure: SQL Server в Azure SQL Database
Google Cloud: PostgreSQL and MySQL in Cloud SQL, а также горизонтально масштабируемый Cloud Spanner
Колоночные БД
Пока транзакции выполняются по строкам (записям), аналитические свойства вычисляются по столбцам (атрибутам). Приложениям OLAP требуется оптимизированная операция чтения столбцов в таблице.
Один из способов добиться этого - добавить колоночные индексы, в реляционные базы данных. Например:
Индексы Columnstore в Microsoft SQL Server
Индексы Columnstore в PostgreSQL
Однако основная операция РСУБД - это высокочастотные ACID-транзакции с малой задержкой. Это не масштабируется до объема больших данных, который обычно используется в аналитических приложениях.
Для больших данный, хранимых в blob-хранилищах стал популярен метод хранения Озеро Данных (Data Lake). Частичные аналитические сводки вычислялись и поддерживались в OLAP-кубах. Прогресс в масштабировании и производительности колоночного хранилища сделал OLAP-кубы устаревшими. Но концепции по-прежнему актуальны для проектирования конвейеров данных.
Современные хранилища данных построены на колоночных базах данных. Данные хранятся по столбцам, а не по строкам. Доступные варианты:
AWS: RedShift
Azure: Synapse
Google Cloud: BigQuery
Apache: Druid, Kudu, Pinot
Others: ClickHouse, Snowflake
Разница между SQL и NoSQL
Нереляционные БД приобрели свою популярность по двум причинам:
РСУБД не масштабируется горизонтально для больших данных
Не все данные вписываются в строгую схему РСУБД
NoSQL решения предлагают горизонтальное масштабирование при различных компромиссах в рамках CAP теоремы. Согласно этой теореме, распределенное хранилище данных может дать не более 2 из следующих 3 гарантий:
Cогласованность данных (consistency). Результатом каждого чтения должны быть актуальные и непротиворечащие друг другу данные.
Доступность (availability). Каждый запрос получает ответ (без ошибок), независимо от отдельных состояний узлов.
Устойчивость к разделению (partition tolerance). Кластер не выходит из строя, несмотря на произвольное количество сообщений, отбрасываемых (или задерживаемых) сетью между узлами.
Обратите внимание что описание согласованности в CAP-теореме и ACID-транзакциях разное. ACID-согласованность это целостность данных (данные согласованы с отношениями и ограничениями после каждой транзакции). CAP - это состояние всех узлов, согласованных друг с другом в любой момент времени.
Очень мало NoSQL решений поддерживают ACID. Большинство хранилищ данных NoSQL поддерживают модель BASE:
Базовая доступность (basically available). Данные реплицируются во многие системы хранения и доступны большую часть времени.
Неустойчивое состояние (soft-state). Реплики не всегда согласованы; таким образом, состояние может быть правильным только частично.
Согласованность в конечном счёте (eventual consistency). Данные станут согласованными в какой-то момент в будущем, но не известно когда.
Отличия NoSQL от SQL баз данных:
Данные. SQL базы используются для нормализованных структурированных (табличных) данных, строго придерживающихся реляционной схемы.
Транзакции. Все SQL базы данных поддерживают ACID-транзакции, а большинство NoSQL предлагают BASE-транзакции.
CAP-компромиссы. SQL базы данных отдают предпочтение согласованности над всем остальным. Но для хранилищ данных NoSQL обычно отдается приоритет доступности и допустимости секционирования (горизонтальное масштабирование), а в конечном счете обеспечивается согласованность.
NoSQL и полуструктурированные типы данных
Варианты таких баз данных это: ключ-значение, документоориентированные, графовые и широкие колонки (wide-column).
Ключ-значение
Это базы данных основанные на словаре или хеш-таблице. Он предназначен для CRUD-операций с уникальным ключом для каждой записи:
Create (ключ, значение): добавить пару "ключ-значение" в хранилище данных.
Read (ключ): поиск значения, связанного с ключом.
Update (ключ, значение): изменить существующее значение ключа.
Delete (ключ): удалить запись (ключ, значение) из хранилища данных.
Значения не имеют фиксированной схемы и могут быть любыми, от примитивных значений до составных структур. Хранилища "ключ-значение" обладают высокой степенью разделения (поэтому масштабируются по горизонтали). Одно из самых популярных решений сегодня это Redis.
Wide-column
В этом типе бд есть таблицы, строки и столбцы. Но имена столбцов и их типы могут быть разными для каждой строки в одной и той же таблице. По логике, это разреженная матрица с контролем версий и многомерным отображением (значение строки, значение столбца, отметка времени). Это похоже на двумерное хранилище ключей и значений, в котором каждому значению ячейки присваивается версия с меткой времени.
Wide-column также обладают высокой степенью разделения. В нем есть понятие семейств столбцов, которые хранятся вместе. Логические координаты ячейки: ключ строки, имя столбца, версия. Итак, хранилища с широкими столбцами на самом деле являются базами данных, ориентированными на строки. Первой таким опенсорсным решением была HBase от Apache.
Документоориентированные
Хранилища документов предназначены для хранения и извлечения документа, состоящего из вложенных объектов. древовидная структура, такая как XML, JSON и YAML.
В вариантах ключ-значение значение непрозрачно. Но документоориентированные БД используют древовидную структуру значений, чтобы предлагать больше возможностей по манипуляции с данными. MongoDB - популярный пример документоориентированной базы данных.
Графовые
Графовые базы данных похожи на документоориентированные, но предназначены для графов, а не для деревьев документов. Например, база данных графа подойдет для хранения и поиска связей между людьми в социальных сетях. Neo4J - известная графовая база данных.
Заключение
Мы с вами прошлись по основным компонентам баз данных, рассмотрели различные варианты хранилищ данных и обсудили как выбирать их на основе:
Применение: транзакции или аналитика (OPTP и OLAP)
Преимущества и недостатки SQL / NoSQL
Тип данных: Структурированные, полуструктурированные, неструктурированные.
Полезные ссылки
Обзор БД Амазона
Как выбрать подходящую БД (+видео)