Базы Данных: Большой Обзор Типов И Подходов. Отчет Яндекса

Это конспект лекции Татьяны Денисовой.

тденисова — backend-разработчик Яндекс.

Учебника.

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

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

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

Информации будет много, вот содержание.

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

Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

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

Или допустим у вас проблема, вы видите, что база данных не работает, тормозит или есть проблемы с данными, несогласованность.

Тогда вы должны понимать, куда копать.

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



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

Сначала поговорим о данных.

Что это вообще такое? Вокруг нас много фактов, много информации, но пока они не собраны каким-либо образом, они для нас бесполезны.

Мы их собираем, структурируем и храним.

И именно эта сохраненная структуризация называется данными, а то, что ее хранит, называется базой данных.

Но хотя эти данные просто где-то собираются, они нам тоже в принципе бесполезны.

Поэтому над базами данных есть слой — СУБД.

Это то, что позволяет нам извлекать данные, хранить их и анализировать.

Таким образом, мы превращаем полученные данные в информацию, которую можем отобразить пользователю.

Пользователь получает знания и применяет их.



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

Мы обсудим, как структурировать информацию и факты, хранить их, в каком типе данных, в какой модели.

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



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

Сначала поговорим о реляционных базах данных.

Думаю, реляционная модель знакома многим из вас.

Это модель типа таблиц и связей между таблицами.

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

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

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

На слайдах есть примечания и ссылки.

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

Я постараюсь не рассказывать о технических понятиях, которые могут быть вам незнакомы.

Но все, что я говорю, вы найдете в примечаниях к слайдам.

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



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

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

Например, теперь есть таблица пользователей, чат мессенджера и сообщения.

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

То есть мы обеспечиваем целостность данных.

Мы гарантируем, что всегда сможем собрать всю картину воедино.

Но при этом мы храним, например, в таблице сообщений только идентификаторы, только идентификаторы.

Таким образом мы уменьшаем общий размер базы данных, делая ее меньше.

Соответственно, мы упрощаем запись в эту базу данных.

Нам не нужно постоянно писать во множество таблиц.

Просто записываем его в одну таблицу с идентификатором человека.



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

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

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

Но конечная картина, общие данные останутся нетронутыми.

Я уже сказал об уменьшении размера базы данных.

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

Чтобы просмотреть профиль, мы можем просто перейти к таблице «Пользователи».

Я также предупредил о противоречивой зависимости.

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

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

Эта структура также защищает наши данные от случайного удаления.

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

Это такая маленькая подстраховка.

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

Над чем еще нужно поработать?

Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

Давайте представим, что мы действительно это запустили, у нас теперь много пользователей и соответственно много сообщений.

Они постоянно общаются друг с другом.

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

Естественно, чем больше пользователей, чем больше сообщений, тем дольше будут выполняться брутфорс-запросы.

Нам нужно решение, которое позволит нам быстро искать сообщения в таблице.

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

Самая простая ассоциация с индексами — это содержание книги.

Если вам нужно найти информацию в книге, вы можете просто пролистать книгу, а можете перейти к оглавлению.

Индексы — это своего рода оглавление.

Еще есть хороший пример с телефонной книгой.

Вы можете нажать на букву на своем телефоне, и он сразу же свяжет вас с фамилиями, начинающимися на эту букву.

Индексы базы данных работают по очень похожему принципу.

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



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

Пожалуйста, обратите внимание на то, как именно мы будем работать с данными.

Не с тем, какие строки у нас в таблице, а вообще.

Индексы создаются на основе ваших запросов.

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

Давайте построим индекс конкретно по столбцу чата.

Индексы в базе данных представляют собой отдельную структуру.

Таблица от этого не зависит. То есть удалить и перестроить индекс можно в любой момент, и таблица от этого не пострадает. Здесь вы можете видеть, что мы выбрали, поставили индекс по столбцу и выделили отдельную структуру, что уже немного уменьшило количество записей, ведь в чате 11 уже есть несколько сообщений.

В СУБД предусмотрен быстрый поиск.

в этом маленьком столике для чата.

Как это сделано? Естественно, поиск осуществляется не простым перебором.

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

Это сбалансированное дерево.



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

Как это работает? У нас есть номер чата, это целочисленное значение, и дерево строится по такому принципу: то, что слева от узла, имеет меньше значений, а справа от узла имеет больше значений.

Что нам дает эта структура? Если посмотреть на получившиеся листы этого дерева, то все значения внизу упорядочены.

Это огромный плюс с точки зрения повышения производительности.

Сейчас я покажу вам, почему.



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

Например, мы ищем смысл.

Очень легко искать одно значение.

Двигаемся вниз по дереву или влево, вправо – в зависимости от того, больше или меньше это значение.



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

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

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



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

Если нам нужен диапазон, определенный от и до, мы делаем то же самое.

Находим начальное значение и идем по листовым ссылкам до максимального значения.

Мы прошли через дерево только один раз.

Это очень удобно, очень быстро.

Таким же образом будем искать максимальное и минимальное значения.

Идите полностью налево, полностью направо.

Мы также получим упорядоченный список.

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

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

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

Почему вы думаете, что это не сработает? Почему у нас не будет прироста скорости, если мы построим дерево для каждого столбца? (.

) Наш выбор действительно ускорится.

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

Индексы, как правило, содержат ссылки на строки, а не сами строки.

И для селекционеров это прекрасно работает. Но как только мы захотим установить данные таблицы, обновить или удалить данные, то все эти деревья придется перестраивать.

На самом деле удаление не перестроит, а просто фрагментирует это дерево, и в итоге у нас останется много пустых значений.

Будет огромное дерево с пустыми значениями.

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

В результате мы получим огромные накладные расходы на всю эту структуру.

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



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

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

Есть индексы для ускорения работы, а есть индексы для обеспечения целостности.

Одним из самых простых является первичный ключ.

Это тоже показатель уникальности.

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

Мы обсуждали, что вам необходимо учитывать накладные расходы на поддержание индексов при вставке данных.

Забыл сказать, что при построении индекса он должен быть очень избирательным.

Что это значит? Давайте посмотрим на это дерево.

Мы понимаем, что если для индекса установлено значение true false, то мы получим просто две огромные деревяшки слева и справа.

И мы проходим в лучшем случае 50% таблицы, что на самом деле не очень эффективно.

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

Таким образом мы ускорим наши образцы.

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

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

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

А запросы, включающие индексы, нужно писать очень внимательно.

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

В планировщике есть определенная таблица соответствия между тем, сколько стоит операция и насколько она дорогая.

В примере с PostgreSQL есть специальные технические таблицы, которые собирают информацию о ваших данных, о ваших таблицах.

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

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



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

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

Если вы хотите фактического выполнения, вы можете использовать анализ объяснения.

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

Поэтому фактическое время может варьироваться в зависимости от машины и особенностей ваших данных.

Так что если вам просто нужно фактическое выполнение, то, конечно, лучше использовать анализ объяснения.

На этом слайде вы можете увидеть пример.

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

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

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

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



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

Есть такое понятие как денормализация.

Это копирование наиболее часто используемых данных или предварительный расчет необходимых данных и сохранение их в таблицу.



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

Вот как могут выглядеть отношения между пользователем и чатом.

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

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



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

В чем преимущество денормализации? Ускоряем процесс получения данных.

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

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

Поэтому денормализацию следует использовать только тогда, когда она вам действительно нужна.

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

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

Узнайте, как они на самом деле выполняются, как их выполняет планировщик.

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

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

Пойдем дальше.

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

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

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

Они могут обновлять одни и те же данные одновременно.

Мы должны быть в состоянии решить все эти проблемы.

Давайте рассмотрим на конкретных примерах то, о чем мы говорим.



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

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

Пользователь 1 видит, что переговорная комната в настоящее время свободна, и начинает ее бронировать.

У него открывается окно, и он думает, кому из коллег мне позвонить.

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

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

Но в это время пользователь 2 перезаписывает свои данные, и получается, что разговор закреплен за пользователем 2. Это называется конфликтом данных.

И мы должны уметь эти конфликты показывать людям и как-то их разрешать.

Здесь мы будем переписывать.



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

Как это сделать? Мы можем просто заблокировать разговор на некоторое время, пока пользователь 1 думает. Если он сохранил данные, то пользователю 2 мы не позволим это сделать.

Если он выпустил данные и не сохранил их, то пользователь 2 сможет забронировать встречу.

Похожую картину вы можете увидеть при покупке билетов в кино.

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

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

Допустим, я хочу перевести деньги с банковского счета 1 на счет 2. На данный момент у меня есть три операции.

Я проверяю, достаточно ли у меня средств, снимаю средства с первого счета и переношу их на второй счет. Понятно, что если я потерплю неудачу в любом из этих пунктов, то что-то пойдет не так.

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

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

Получается, что в итоге на моем банковском счету, на всех моих счетах, станет какая-то сумма меньше.

Нет возможности вернуть свои деньги.

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

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

Таким образом мы гарантируем, что все эти операции будут выполнены как единое целое или не будут выполнены вообще.

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

Транзакции имеют четыре свойства и четыре требования к ним.

Это атомарность, согласованность, изоляция и долговечность — атомарность, согласованность, изоляция и постоянство данных.

Что это за свойства?

  • Атомарность или атомарность — это гарантия того, что выполняемая вами операция будет завершена полностью, а не частично.

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

  • Непротиворечивость или непротиворечивость — это скорее бизнес-правило, а не со стороны СУБД или самой базы данных.

    Последовательность не следует путать с целостностью.

    Если кто-то из вас работал с базами данных и перенес данные с несуществующего идентификатора, то вы могли получить Integrity Error: система не понимала, что с этим делать.

    Именно наличие взаимосвязей и уникальность ключей называется целостностью.

    А согласованность — это то, что мы пишем в самой транзакции.

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

    Это последовательность.



    Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

  • Изоляция или изоляция – это именно то, что мы рассмотрели на примере переговорной комнаты.

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

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

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

Давайте подробнее поговорим об изоляции.

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

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

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

Давайте посмотрим поближе.

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



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

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



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

В данном случае пользователь 1 что-то записал в базу данных.

Пользователь 2 в это время что-то считал оттуда и строил аналитику на основе этих данных.

А пользователь 1 обнаружил ошибку, несогласованность и откатывает эти данные.

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

Неповторяемое чтение — это когда у пользователя есть 1 длинная транзакция.

Он выбирает данные из базы данных, а в это время пользователь 2 меняет часть этих же данных.



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

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

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

Таким образом, у него возникнет конфликт, несоответствие в записываемых данных.



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

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

То есть пользователь 1 сделал запрос, а потом при повторном запросе тех же данных строки появлялись или исчезали.

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



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

Для решения этих проблем существует четыре уровня изоляции.

Первый, самый низкий уровень — чтение без фиксации.

Это то, что PostgreSQL описывает как «Без блокировки».

Когда мы читаем или записываем данные, мы не запрещаем другим пользователям читать или записывать эти данные.

Получается, что мы не блокируем никакие изменения.

Все четыре перечисленные проблемы все еще могут возникнуть.

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

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

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

а что нет. А затем второй запрос — на отладку, отладку, проверку — вы выполняете именно на этом уровне изоляции.

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

Или не откатился, но на данный момент видно состояние системы.



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

Чтение зафиксировано, чтение фиксированных данных.

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

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

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

Мы гарантируем, что у нас никогда не возникнет ситуация, когда мы увидим какие-то части данных, незаконченные данные.

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

Потому что если у нас такая ситуация, то логично, что наша аналитика сразу «пойдёт».

От чего не защищает такой уровень изоляции? Он не защищает от того, что выбранные вами данные могут быть изменены.

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

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

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



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

Как это обеспечивается? Использование блокировки таблицы, то есть блокировки нашего выбора.

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

И в этот момент мы не видим изменений других пользователей; мы всегда работаем с этой копией данных.

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

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

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

Но могут появиться новые данные.

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

Есть еще один уровень изоляции — сериализация.

Это часто называют упорядочиваемостью.

Это полная блокировка данных в таблице.

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

И мы выполняем наши запросы комплексно.



Базы данных: большой обзор типов и подходов.
</p><p>
 отчет яндекса

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

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

Это высшая степень изоляции.

Здесь наибольшее количество блокировок и наименьшая возможность распараллеливания запросов.

Что нужно знать о транзакциях? Что он Теги: #Хранение данных #Администрирование баз данных #Анализ и проектирование системы #sql #шардинг #графовые базы данных #индексы #репликация #реляционные базы данных #acid #нормализация #денормализация #нереляционные базы данных #хранилище ключей и значений

Вместе с данным постом часто просматривают: