Базы данных

О базах данных, их видах и компонентах


Что такое база данных?

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

Что такое СУБД?

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

Компоненты

Вот некоторые общие компоненты, найденные в разных базах данных:

Схема

Роль схемы состоит в том, чтобы определить форму структуры данных и указать, какие типы данных могут быть размещены. Схемы могут строго применяться ко всей базе данных, слабо применяться к части базы данных или вообще не существовать.

Стол

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

Столбец

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

Ряд

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

Типы

Ниже приведены различные типы баз данных:

  • SQL
  • NoSQL
    • Документ
    • Ключ-значение
    • График
    • Временная последовательность
    • Широкая колонка
    • Мультимодель

Проблемы

Некоторые распространенные проблемы, возникающие при работе с базами данных в масштабе:

  • Поглощение значительного увеличения объема данных: взрыв данных, поступающих от датчиков, подключенных машин и десятков других источников.
  • Обеспечение безопасности данных: Утечки данных происходят повсеместно в наши дни, как никогда важно обеспечить безопасность данных, а также легкий доступ для пользователей.
  • Удовлетворение спроса: компаниям необходим доступ к своим данным в режиме реального времени, чтобы поддерживать своевременное принятие решений и использовать новые возможности.
  • Управление базой данных и инфраструктурой и их обслуживание: по мере усложнения баз данных и роста объемов данных компании сталкиваются с расходами на наем дополнительных специалистов для управления своими базами данных.
  • Снятие ограничений на масштабируемость: бизнес должен расти, если он хочет выжить, и его управление данными должно расти вместе с ним. Но очень сложно предсказать, какая емкость потребуется компании, особенно для локальных баз данных.
  • Обеспечение резидентности данных, суверенитета данных или требований к задержке: в некоторых организациях есть варианты использования, которые лучше подходят для работы в локальной среде. В таких случаях идеально подходят спроектированные системы, предварительно сконфигурированные и предварительно оптимизированные для работы с базой данных.

базы данных SQL

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

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

Материализованные представления

Материализованное представление — это предварительно вычисленный набор данных, полученный из спецификации запроса и сохраненный для последующего использования. Поскольку данные предварительно вычисляются, выполнение запроса к материализованному представлению выполняется быстрее, чем выполнение запроса к базовой таблице представления. Эта разница в производительности может быть значительной, если запрос выполняется часто или является достаточно сложным.

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

Проблема с запросом N+1

Проблема с запросом N+1 возникает, когда уровень доступа к данным выполняет N дополнительных операторов SQL для извлечения тех же данных, которые могли быть получены при выполнении основного SQL-запроса. Чем больше значение N, тем больше запросов будет выполнено, тем больше влияние на производительность.

Это обычно наблюдается в инструментах GraphQL и ORM (объектно-реляционное сопоставление) и может быть решено путем оптимизации SQL-запроса или использования загрузчика данных, который группирует последовательные запросы и делает один запрос данных скрытно.

Преимущества и недостатки

Давайте рассмотрим некоторые преимущества использования реляционных баз данных:

  • Просто и точно
  • Доступность
  • Согласованность данных
  • Гибкость

Недостатки

Ниже приведены недостатки реляционных баз данных:

  • Дорогой в обслуживании
  • Сложная эволюция схемы
  • Повышение производительности (объединение, денормализация и т. д.)
  • Трудно масштабировать из-за плохой горизонтальной масштабируемости

Примеры

Вот некоторые часто используемые реляционные базы данных:

базы данных NoSQL

NoSQL — это широкая категория, в которую входят любые базы данных, не использующие SQL в качестве основного языка доступа к данным. Эти типы баз данных также иногда называют нереляционными базами данных. В отличие от реляционных баз данных, данные в базе данных NoSQL не обязательно должны соответствовать заранее определенной схеме. Базы данных NoSQL следуют модели согласованности BASE

Ниже приведены различные типы баз данных NoSQL:

Документ

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

Преимущества

  • Интуитивно понятный и гибкий
  • Простое горизонтальное масштабирование
  • Бессхемный

Недостатки

  • Бессхемный
  • Нереляционный

Примеры

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

Один из самых простых типов баз данных NoSQL, базы данных «ключ-значение» сохраняют данные в виде группы пар «ключ-значение», состоящей из двух элементов данных каждая. Их также иногда называют хранилищем ключей и значений.

Преимущества

  • Простой и производительный
  • Высокая масштабируемость для больших объемов трафика
  • Управление сеансом
  • Оптимизирован поиск

Недостатки

  • Базовый CRUD
  • Значения не могут быть отфильтрованы
  • Не хватает возможностей индексации и сканирования
  • Не оптимизирован для сложных запросов

Примеры

График

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

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

Преимущества

  • Скорость запроса
  • Подвижный и гибкий
  • Явное представление данных

Недостатки

  • Сложный
  • Нет стандартизированного языка запросов

Случаи использования

  • Обнаружение мошенничества
  • Рекомендованные двигатели
  • Социальные сети
  • Картирование сети

Примеры

Временная последовательность

База данных временных рядов — это база данных, оптимизированная для данных с отметками времени или временных рядов.

Преимущества

  • Быстрая вставка и извлечение
  • Эффективное хранение данных

Случаи использования

  • Данные Интернета вещей
  • Анализ показателей
  • Мониторинг приложений
  • Понимание финансовых тенденций

Примеры

Широкая колонка

Базы данных с широкими столбцами, также известные как хранилища с широкими столбцами, не зависят от схемы. Данные хранятся в семействах столбцов, а не в строках и столбцах.

Преимущества

  • Высокая масштабируемость, может обрабатывать петабайты данных
  • Идеально подходит для работы с большими данными в режиме реального времени.

Недостатки

  • Дорогой
  • Увеличено время записи

Случаи использования

  • Бизнес-аналитика
  • Хранение данных на основе атрибутов

Примеры

Мультимодель

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

Преимущества

  • Гибкость
  • Подходит для сложных проектов
  • Согласованность данных

Недостатки

  • Сложный
  • Менее зрелый

Примеры

Базы данных SQL и NoSQL

В мире баз данных существует два основных типа решений: базы данных SQL (реляционные) и базы данных NoSQL (нереляционные). Оба они отличаются тем, как они были построены, типом информации, которую они хранят, и тем, как они ее хранят. Реляционные базы данных структурированы и имеют предопределенные схемы, тогда как нереляционные базы данных неструктурированы, распределены и имеют динамическую схему.

Различия высокого уровня

Вот некоторые высокоуровневые различия между SQL и NoSQL:

Хранилище

SQL хранит данные в таблицах, где каждая строка представляет объект, а каждый столбец представляет точку данных об этом объекте.

Базы данных NoSQL имеют разные модели хранения данных, такие как ключ-значение, граф, документ и т. д.

Схема

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

В то время как в NoSQL схемы являются динамическими. Поля можно добавлять на лету, и каждая запись (или ее эквивалент) не обязательно должна содержать данные для каждого поля.

Запрос

Базы данных SQL используют SQL (язык структурированных запросов) для определения данных и управления ими, что является очень мощным.

В базе данных NoSQL запросы сосредоточены на наборе документов. Разные базы данных имеют разный синтаксис для запросов.

Масштабируемость

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

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

Надежность

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

Большинство решений NoSQL жертвуют совместимостью с ACID ради производительности и масштабируемости.

Причины

Как всегда, мы всегда должны выбирать технологию, которая лучше соответствует требованиям. Итак, давайте рассмотрим некоторые причины выбора базы данных на основе SQL или NoSQL:

Для SQL

  • Структурированные данные со строгой схемой
  • Реляционные данные
  • Необходимость сложных соединений
  • Транзакции
  • Поиск по индексу очень быстрый

Для NoSQL

  • Динамическая или гибкая схема
  • Нереляционные данные
  • Нет необходимости в сложных соединениях
  • Очень интенсивная работа с данными
  • Очень высокая пропускная способность для IOPS

Репликация базы данных

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

Мастер-ведомая репликация

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

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

Репликация мастер-мастер

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

Преимущества
  • Приложения могут читать с обоих мастеров.
  • Распределяет нагрузку записи между обоими главными узлами.
  • Простой, автоматический и быстрый переход на другой ресурс.
Недостатки
  • Не так просто, как master-slave для настройки и развертывания.
  • Либо слабо согласованы, либо имеют увеличенную задержку записи из-за синхронизации.
  • Разрешение конфликтов вступает в игру по мере добавления дополнительных узлов записи и увеличения задержки.

Синхронная и асинхронная репликация

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

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

Индексы

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

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

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

Плотный индекс

В плотном индексе запись индекса создается для каждой строки таблицы. Записи могут быть расположены напрямую, поскольку каждая запись индекса содержит значение ключа поиска и указатель на фактическую запись.

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

Разреженный индекс

В разреженном индексе записи создаются только для некоторых записей.

Разреженные индексы требуют меньше обслуживания, чем плотные индексы во время записи, поскольку они содержат только подмножество значений. Это меньшее бремя обслуживания означает, что вставки, обновления и удаления будут выполняться быстрее. Меньшее количество записей также означает, что индекс будет использовать меньше памяти. Поиск данных происходит медленнее, поскольку сканирование страницы обычно следует за бинарным поиском. Разреженные индексы также необязательны при работе с упорядоченными данными.

Нормализация и Денормализация

Условия

Прежде чем мы пойдем дальше, давайте рассмотрим некоторые часто используемые термины нормализации и денормализации.

Ключи

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

Составной ключ: первичный ключ, состоящий из нескольких столбцов.

Суперключ: набор всех ключей, которые могут однозначно идентифицировать все строки, присутствующие в таблице.

Ключ-кандидат: атрибуты, однозначно идентифицирующие строки в таблице.

Внешний ключ: это ссылка на первичный ключ другой таблицы.

Альтернативный ключ. Ключи, не являющиеся первичными, называются альтернативными ключами.

Суррогатный ключ: генерируемое системой значение, которое однозначно идентифицирует каждую запись в таблице, если ни один другой столбец не может содержать свойства первичного ключа.

Зависимости

Частичная зависимость: возникает, когда первичный ключ определяет некоторые другие атрибуты.

Функциональная зависимость: это отношение, которое существует между двумя атрибутами, обычно между первичным ключом и неключевым атрибутом в таблице.

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

Аномалии

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

Существует три типа аномалий базы данных:

Аномалия вставки: возникает, когда мы не можем вставить определенные атрибуты в базу данных без наличия других атрибутов.

Аномалия обновления: возникает в случае избыточности данных и частичного обновления. Другими словами, правильное обновление базы данных требует других действий, таких как добавление, удаление или и то, и другое.

Аномалия удаления: возникает, когда удаление одних данных требует удаления других данных.

Пример

Рассмотрим следующую ненормализованную таблицу:

ID Имя Роль Команда
1 Питер Инженер-программист А
2 Брайан DevOps-инженер Б
3 Хейли Менеджер по продукту С
4 Хейли Менеджер по продукту С
5 Стив Фронтенд-инженер Д

Давайте представим, мы наняли нового человека «Джон», но ему не сразу дали команду. Это вызовет аномалию вставки, так как атрибут команды еще не присутствует.

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

Наконец, мы хотели бы удалить команду B, но для этого нам также потребуется удалить дополнительную информацию, такую как имя и роль, это пример аномалии удаления.

Нормализация

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

Зачем нужна нормализация?

Цель нормализации — устранить избыточные данные и обеспечить согласованность данных. Полностью нормализованная база данных позволяет расширять ее структуру для размещения новых типов данных без слишком большого изменения существующей структуры. В результате приложения, взаимодействующие с базой данных, затрагиваются минимально.

Нормальные формы

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

1NF

Чтобы таблица находилась в первой нормальной форме (1НФ), она должна соответствовать следующим правилам:

  • Повторяющиеся группы не допускаются.
  • Определите каждый набор связанных данных с помощью первичного ключа.
  • Набор связанных данных должен иметь отдельную таблицу.
  • Смешивание типов данных в одном столбце не допускается.

2НФ

Чтобы таблица находилась во второй нормальной форме (2НФ), она должна соответствовать следующим правилам:

  • Удовлетворяет первой нормальной форме (1НФ).
  • Не должно быть частичной зависимости.

3NF

Чтобы таблица находилась в третьей нормальной форме (3НФ), она должна соответствовать следующим правилам:

  • Удовлетворяет второй нормальной форме (2НФ).
  • Транзитивные функциональные зависимости не допускаются.

БКНФ

Нормальная форма Бойса-Кодда (или BCNF) — это немного усиленная версия третьей нормальной формы (3NF), используемая для устранения определенных типов аномалий, с которыми не имеет дело 3NF, как первоначально определено. Иногда его также называют нормальной формой 3,5 (3,5NF).

Чтобы таблица находилась в нормальной форме Бойса-Кодда (BCNF), она должна соответствовать следующим правилам:

  • Выполняется третья нормальная форма (3NF).
  • Для каждой функциональной зависимости X → Y, X должен быть суперключом.

Есть более нормальные формы, такие как 4NF, 5NF и 6NF, но мы не будем их здесь обсуждать. Посмотрите это потрясающее видео, в котором подробно рассказывается.

В реляционной базе данных отношение часто называют «нормализованным"_, если оно соответствует третьей нормальной форме. Большинство отношений 3NF свободны от аномалий вставки, обновления и удаления.

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

Преимущества

Вот некоторые преимущества нормализации:

  • Уменьшает избыточность данных.
  • Улучшенный дизайн данных.
  • Повышает согласованность данных.
  • Обеспечивает ссылочную целостность.
Недостатки

Давайте рассмотрим некоторые недостатки нормализации:

  • Дизайн данных сложен.
  • Более низкая производительность.
  • Накладные расходы на техническое обслуживание.
  • Требовать больше соединений.

Денормализация

Денормализация — это метод оптимизации базы данных, при котором мы добавляем избыточные данные в одну или несколько таблиц. Это может помочь нам избежать дорогостоящих соединений в реляционной базе данных. Он пытается улучшить производительность чтения за счет некоторой производительности записи. Избыточные копии данных записываются в несколько таблиц, чтобы избежать дорогостоящих объединений.

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

Примечание. Денормализация не означает отмену нормализации.

Преимущества

Давайте рассмотрим некоторые преимущества денормализации:

  • Получение данных быстрее.
  • Писать запросы проще.
  • Сокращение количества столов.
  • Удобен в управлении.
Недостатки

Ниже приведены некоторые недостатки денормализации:

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

Модели согласованности ACID и BASE

Давайте обсудим модели согласованности ACID и BASE.

КИСЛОТА

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

Чтобы поддерживать согласованность до и после транзакции, реляционные базы данных следуют свойствам ACID. Давайте разберемся в этих терминах:

Атомный

Все операции в транзакции завершаются успешно или каждая операция откатывается.

Последовательный

По завершении транзакции база данных является структурно прочной.

Изолированный

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

Прочный

После завершения транзакции и записи на диск записей и обновлений он останется в системе, даже если произойдет системный сбой.

БАЗА

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

В мире баз данных NoSQL транзакции ACID менее распространены, поскольку некоторые базы данных ослабили требования к немедленной согласованности, актуальности данных и точности, чтобы получить другие преимущества, такие как масштабируемость и отказоустойчивость.

Свойства BASE намного свободнее, чем гарантии ACID, но между двумя моделями согласованности нет прямого соответствия один к одному. Давайте разберемся в этих терминах:

Базовая доступность

База данных работает большую часть времени.

Мягкое состояние

Хранилища не должны быть согласованными по записи, а разные реплики не должны быть все время взаимно согласованными.

Конечная согласованность

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

ACID против BASE Компромиссы

Нет правильного ответа на вопрос, нужна ли нашему приложению модель согласованности ACID или BASE. Обе модели были разработаны для удовлетворения различных требований. При выборе базы данных мы должны помнить о свойствах как моделей, так и о требованиях нашего приложения.

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

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

Теорема CAP

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

Давайте подробно рассмотрим три характеристики распределенной системы, на которые ссылается теорема CAP.

Последовательность

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

Доступность

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

Допуск разделения

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

Компромисс между согласованностью и доступностью

Мы живем в физическом мире и не можем гарантировать стабильность сети, поэтому распределенные базы данных должны выбирать Partition Tolerance (P). Это подразумевает компромисс между согласованностью © и доступностью (A).

База ЦС

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

Пример: PostgreSQL, MariaDB.

База данных CP

База данных CP обеспечивает согласованность и устойчивость к разделам за счет доступности. Когда между любыми двумя узлами возникает разделение, система должна отключить несогласованный узел до тех пор, пока разделение не будет разрешено.

Пример: MongoDB, Apache HBase.

База данных точек доступа

База данных AP обеспечивает доступность и устойчивость к разделам за счет согласованности. Когда происходит разделение, все узлы остаются доступными, но те, которые находятся на неправильном конце раздела, могут возвращать более старую версию данных, чем другие. Когда раздел разрешен, базы данных AP обычно повторно синхронизируют узлы, чтобы исправить все несоответствия в системе.

Пример: Apache Cassandra, CouchDB.

Теорема PACELC

Теорема PACELC является расширением теоремы CAP. Теорема CAP утверждает, что в случае разделения сети (P) в распределенной системе необходимо выбирать между доступностью (A) и согласованностью ©.

PACELC расширяет теорему CAP, вводя задержку (L) в качестве дополнительного атрибута распределенной системы. Теорема утверждает, что иначе (E), даже когда система работает нормально при отсутствии разделов, приходится выбирать между задержкой (L) и согласованностью ©.

Теорема PACELC была впервые описана Дэниелом Дж. Абади.

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

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

транзакций

Транзакция — это серия операций с базой данных, которые считаются «единой единицей работы»_. Операции в транзакции либо завершаются успешно, либо завершаются ошибкой. Таким образом, понятие транзакции поддерживает целостность данных, когда часть системы дает сбой. Не все базы данных выбирают поддержку транзакций ACID, обычно потому, что они отдают приоритет другим оптимизациям, которые сложно или теоретически невозможно реализовать вместе.

Обычно реляционные базы данных поддерживают ACID-транзакции, а нереляционные базы данных — нет (есть исключения).

Состояния

Транзакция в базе данных может находиться в одном из следующих состояний:

Активный

В этом состоянии транзакция выполняется. Это начальное состояние каждой транзакции.

Частично совершено

Когда транзакция выполняет свою последнюю операцию, говорят, что она находится в частично зафиксированном состоянии.

Преданный идее

Если транзакция успешно выполняет все свои операции, говорят, что она зафиксирована. Все его эффекты теперь навсегда установлены в системе баз данных.

Неуспешный

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

Прервано

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

Модуль восстановления базы данных может выбрать одну из двух операций после прерывания транзакции:

  • Перезапустить транзакцию
  • Убить транзакцию
Прекращено

Если отката нет или транзакция выходит из совершенного состояния, то система непротиворечива и готова к новой транзакции, а старая транзакция завершается.

Распределенные транзакции

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

Зачем нужны распределенные транзакции?

В отличие от транзакции ACID в одной базе данных, распределенная транзакция включает изменение данных в нескольких базах данных. Следовательно, распределенная обработка транзакций более сложна, поскольку база данных должна координировать фиксацию или откат изменений в транзакции как автономная единица.

Другими словами, все узлы должны зафиксироваться, иначе все должны прерваться и вся транзакция откатится. Вот почему нам нужны распределенные транзакции.

Теперь давайте рассмотрим некоторые популярные решения для распределенных транзакций:

Двухэтапная фиксация

Протокол двухфазной фиксации (2PC) — это распределенный алгоритм, который координирует все процессы, участвующие в распределенной транзакции, в отношении того, следует ли фиксировать или прерывать (откатывать) транзакцию.

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

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

Фазы

Двухэтапная фиксация состоит из следующих фаз:

Подготовка

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

Фаза фиксации

Если все участники отвечают координатору, что они подготовлены, то координатор просит все узлы зафиксировать транзакцию. В случае сбоя транзакция будет отменена.

Проблемы

В протоколе двухэтапной фиксации могут возникнуть следующие проблемы:

  • А если один из узлов выйдет из строя?
  • А если сам координатор рухнет?
  • Это блокирующий протокол.

Трехэтапная фиксация

Трехфазная фиксация (3PC) — это расширение двухфазной фиксации, в котором фаза фиксации разделена на две фазы. Это помогает решить проблему блокировки, возникающую в протоколе двухфазной фиксации.

Фазы

Трехэтапная фиксация состоит из следующих фаз:

Подготовка

Эта фаза аналогична двухфазной фиксации.

Фаза перед фиксацией

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

Фаза фиксации

Этот шаг также аналогичен протоколу двухэтапной фиксации.

Чем полезен этап Pre-commit?

На этапе предварительной фиксации выполняется следующее:

  • Если в этой фазе найдены узлы-участники, это означает, что каждый участник завершил первую фазу. Завершение фазы подготовки гарантировано.
  • Каждая фаза теперь может истечь по тайм-ауту и избежать неопределенного ожидания.

Саги

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

Координация

Существует два распространенных подхода к реализации:

  • Хореография: каждая локальная транзакция публикует события домена, которые запускают локальные транзакции в других службах.
  • Оркестрация: оркестратор сообщает участникам, какие локальные транзакции выполнять.
Проблемы
  • Шаблон Saga особенно сложно отлаживать.
  • Существует риск циклической зависимости между участниками саги.
  • Отсутствие изоляции данных участников создает проблемы с надежностью.
  • Тестирование затруднено, поскольку для имитации транзакции должны быть запущены все службы.

Шардинг

Прежде чем мы обсудим шардинг, давайте поговорим о разбиении данных:

Разделение данных

Разделение данных — это способ разбить базу данных на множество более мелких частей. Это процесс разделения базы данных или таблицы на несколько компьютеров для улучшения управляемости, производительности и доступности базы данных.

Методы

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

Горизонтальное разбиение (или сегментирование)

В этой стратегии мы разбиваем данные таблицы по горизонтали на основе диапазона значений, определяемого partition key. Его также называют сегментированием базы данных.

Вертикальное разбиение

При вертикальном разделении мы разделяем данные вертикально на основе столбцов. Мы делим таблицы на относительно меньшие таблицы с небольшим количеством элементов, и каждая часть присутствует в отдельном разделе.

В этом уроке мы сосредоточимся на шардинге.

Что такое шардинг?

Разделение — это шаблон архитектуры базы данных, связанный с горизонтальным разделением, которое представляет собой практику разделения строк одной таблицы на несколько разных таблиц, известных как partitions или shards. Каждый раздел имеет одинаковую схему и столбцы, а также подмножество общих данных. Точно так же данные, хранящиеся в каждом разделе, уникальны и не зависят от данных, хранящихся в других разделах.

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

Критерий разделения

Существует большое количество критериев для разделения данных. Некоторые наиболее часто используемые критерии:

На основе хэша

Эта стратегия делит строки на разные секции на основе алгоритма хеширования, а не группирует строки базы данных на основе непрерывных индексов.

Недостатком этого метода является то, что динамическое добавление/удаление серверов баз данных становится дорогостоящим.

На основе списка

При секционировании на основе списка каждая секция определяется и выбирается на основе списка значений столбца, а не набора смежных диапазонов значений.

На основе диапазона

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

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

Композитный

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

Преимущества

Но зачем нам шардинг? Вот некоторые преимущества:

  • Доступность: обеспечивает логическую независимость многораздельной базы данных, обеспечивая высокую доступность нашего приложения. Здесь отдельными разделами можно управлять независимо.
  • Масштабируемость: повышает масштабируемость за счет распределения данных по нескольким разделам.
  • Безопасность: помогает повысить безопасность системы за счет хранения конфиденциальных и неконфиденциальных данных в разных разделах. Это может обеспечить лучшую управляемость и безопасность конфиденциальных данных.
  • Производительность запросов: повышает производительность системы. Вместо того, чтобы запрашивать всю базу данных, теперь система должна запрашивать только меньший раздел.
  • Управление данными: таблицы и индексы делятся на более мелкие и более управляемые единицы.

Недостатки

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

Когда использовать шардинг?

Вот несколько причин, почему шардинг может быть правильным выбором:

  • Использование существующего оборудования вместо высокопроизводительных машин.
  • Ведение данных в различных географических регионах.
  • Быстро масштабируйте, добавляя больше осколков.
  • Лучшая производительность, так как каждая машина находится под меньшей нагрузкой.
  • Когда требуется больше одновременных подключений.

Консистентное хеширование

Давайте сначала поймем проблему, которую мы пытаемся решить.

Зачем нам это надо?

В традиционных методах распространения на основе хеширования мы используем хеш-функцию для хеширования ключей нашего раздела (т. е. идентификатора запроса или IP-адреса). Затем, если мы используем модуль по отношению к общему количеству узлов (серверов или баз данных). Это даст нам узел, на который мы хотим направить наш запрос.

$$
\начать{выравнивать} & Hash (key1) \to H1 \bmod N = Node0 \ & Hash (key2) \to H2 \bmod N = Node1 \
& Hash (key3) \to H3 \bmod N = Node2 \ &…\ & Хэш (keyn) \to Hn \bmod N = Node{n-1}
\конец{выравнивание
}
$$

Где,

key: идентификатор запроса или IP-адрес.

H: Результат хэш-функции.

N: общее количество узлов.

«Узел»: узел, на который будет направляться запрос.

Проблема в том, что если мы добавим или удалим узел, это приведет к изменению N, а это означает, что наша стратегия сопоставления сломается, поскольку одни и те же запросы теперь будут сопоставляться с другим сервером. Как следствие, большинство запросов нужно будет перераспределять, что очень неэффективно.

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

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

Теперь, когда мы поняли проблему, давайте подробно обсудим последовательное хеширование.

Как это работает

Согласованное хеширование — это схема распределенного хеширования, которая работает независимо от количества узлов в распределенной хеш-таблице, назначая им позицию в абстрактном круге или хэш-кольце. Это позволяет масштабировать серверы и объекты, не затрагивая систему в целом.

При использовании согласованного хеширования повторное распределение потребуется только для данных «K/N».

$$
Р = К/Н
$$

Где,

R: Данные, которые потребуют повторного распространения.

K: Количество ключей раздела.

N: количество узлов.

Выход хеш-функции — это диапазон, скажем, «0…m-1», который мы можем представить в нашем кольце хеширования. Мы хешируем запросы и распределяем их по кольцу в зависимости от того, что было на выходе. Точно так же мы также хешируем узел и также распределяем их по тому же кольцу.

$$
\начать{выравнивать} & Хэш (ключ1) = P1 \
& Хэш (ключ2) = P2 \
& Хэш (ключ3) = P3 \
&…\
& Хэш (keyn) = P{m-1}
\конец{выравнивание
}
$$

Где,

key: идентификатор запроса/узла или IP-адрес.

P: Позиция на кольце.

m: общий диапазон хэш-кольца.

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

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

Давайте посмотрим, как мы можем решить эти проблемы.

Виртуальные узлы

Чтобы обеспечить более равномерное распределение нагрузки, мы можем представить идею виртуального узла, иногда также называемого VNode.

Вместо того, чтобы назначать узлу одну позицию, диапазон хэшей делится на несколько меньших диапазонов, и каждому физическому узлу назначается несколько таких меньших диапазонов. Каждый из этих поддиапазонов считается VNode. Следовательно, виртуальные узлы — это, по сути, существующие физические узлы, многократно отображаемые в хеш-кольце, чтобы свести к минимуму изменения в назначенном узлу диапазоне.

Для этого мы можем использовать k хэш-функций.

$$
\начать{выравнивать} & Хэш1(ключ1) = P1 \ & Хэш2(ключ2) = P2 \
& Хэш3(ключ3) = P3 \ &. . . \ & Hashk (keyn) = P{m-1}
\конец{выравнивание
}
$$

Где,

key: идентификатор запроса/узла или IP-адрес.

k: количество хеш-функций.

P: Позиция на кольце.

m: общий диапазон хэш-кольца.

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

Репликация данных

Чтобы обеспечить высокую доступность и надежность, согласованное хеширование реплицирует каждый элемент данных на множестве N узлов в системе, где значение N эквивалентно коэффициенту репликации.

Коэффициент репликации — это количество узлов, которые получат копию одних и тех же данных. В окончательно непротиворечивых системах это делается асинхронно.

Преимущества

Давайте рассмотрим некоторые преимущества последовательного хеширования:

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

Недостатки

Ниже приведены некоторые недостатки последовательного хеширования:

  • Увеличивает сложность.
  • Каскадные сбои.
  • Распределение нагрузки по-прежнему может быть неравномерным.
  • Управление ключами может быть дорогостоящим, когда узлы временно выходят из строя.

Примеры

Давайте рассмотрим несколько примеров, где используется последовательное хеширование:

  • Разделение данных в Apache Cassandra.
  • Распределение нагрузки между несколькими хостами хранилища в Amazon DynamoDB.

Федерация базы данных

Федерация (или функциональное разделение) разделяет базы данных по функциям. В архитектуре федерации несколько отдельных физических баз данных представляются конечным пользователям как одна логическая база данных.

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

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

Характеристики

Давайте рассмотрим некоторые ключевые характеристики федеративной базы данных:

  • Прозрачность: объединенная база данных маскирует различия между пользователями и реализациями базовых источников данных. Поэтому пользователям не нужно знать, где хранятся данные.
  • Неоднородность: источники данных могут различаться по многим параметрам. Система федеративных баз данных может обрабатывать различное оборудование, сетевые протоколы, модели данных и т. д.
  • Расширяемость: для удовлетворения меняющихся потребностей бизнеса могут потребоваться новые источники. Хорошая федеративная система баз данных должна позволять легко добавлять новые источники.
  • Автономия: объединенная база данных не изменяет существующие источники данных, интерфейсы должны оставаться прежними.
  • Интеграция данных: объединенная база данных может интегрировать данные из различных протоколов, систем управления базами данных и т. д.

Преимущества

Вот некоторые преимущества федеративных баз данных:

  • Гибкий обмен данными.
  • Автономность среди компонентов базы данных.
  • Единый доступ к разнородным данным.
  • Нет тесной связи приложений с устаревшими базами данных.

Недостатки

Ниже приведены некоторые недостатки федеративных баз данных:

  • Добавляет больше оборудования и дополнительную сложность.
  • Объединение данных из двух баз данных является сложным.
  • Зависимость от автономных источников данных.
  • Производительность запросов и масштабируемость.