Денормализация Базы Данных. За Что? Когда? Как?



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

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

Вопрос о денормализации возникал у меня в голове не раз.

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

Со временем, работая в команде, выяснилось, что это не только моя проблема.

Пришло время разобраться: является ли денормализация злом или нужно просто знать, как ее подготовить?



Что я хотел понять
  • Когда необходима денормализация? Знаки и запахи.

  • Как определить, когда денормализация оправдана?
  • Как правильно реализовать денормализацию


Когда необходима денормализация? Знаки и запахи.

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

Большое количество объединений таблиц.

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

А каждое подключение — очень ресурсоёмкая операция.

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

В такой ситуации может помочь:

  • денормализация за счет уменьшения количества таблиц.

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

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

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

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

Ориентировочные значения.

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

Иногда имеет смысл добавить в таблицу, содержащую часто используемые (и сложные для расчета) расчетные данные, 1-2 дополнительных столбца.

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

Для этого необходимо предварительно определить стоимость каждого товара (по формуле «количество единиц товара» * «цена единицы товара» — скидка).

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

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

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

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

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

Длинные поля.

Если у нас в базе данных есть большие таблицы, содержащие длинные поля (Blob, Long и т.п.

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

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

С точки зрения нормализации абсолютно корректной будет следующая структура таблицы: идентификатор фотографии Идентификатор автора Идентификатор модели камеры сама фотография (поле BLOB-объекта).

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

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

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



Как определить, когда денормализация оправдана?
Затраты и выгоды.

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

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

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

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

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

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

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

Скорость запросов и стабильность производительности.

Например, 70% из 1000 запросов, генерируемых предприятием ежедневно, представляют собой запросы сводного уровня, а не подробные запросы.

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

время обработки на 2730 минут меньше.

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

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

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

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

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

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



Как правильно реализовать денормализацию.

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

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

Например, счетчик посещений.

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

Но для анализа (по периоду, по стране.

) нам, скорее всего, потребуются подробные данные - таблица с информацией о каждом посещении.

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

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

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

Поддержка программного обеспечения Например, в MySQL версии 4.1 вообще нет триггеров и хранимых процедур.

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

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



Краткое содержание
Подведем итоги.

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

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

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

Теги: #денормализация #базы данных #MySQL #MySQL

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