Интернет и базы данных. Часть 03. Денормализация базы данных

Мы хорошо потрудились, нормализовав таблицы базы до четвертой нормальной формы. Зачем же сейчас возвращаться назад?

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

Для чего нужна денормализация

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

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

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

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

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

Расчетные значения

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

Длинные поля

Если у нас в базе данных есть большие таблицы, содержащие длинные поля (Blob, Long и т.п.), то серьезно ускорить выполнение запросов к такой таблице мы сможем, если вынесем длинные поля в отдельную таблицу. Хотим мы, скажем, создать в базе каталог фотографий, в том числе хранить в blob-полях и сами фотографии (профессионального качества, с высоким разрешением, и соответствующего размера). С точки зрения нормализации абсолютно правильной будет такая структура таблицы:

  • ID фотографии
  • ID автора
  • ID модели фотоаппарата
  • сама фотография (blob-поле).

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

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

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

Проводя денормализацию, мы неизбежно создаем в базе данных избыточные, дублирующиеся данные. Поэтому перед разработчиками сразу возникает задача обеспечить непротиворечивость (а чаще - идентичность) дублирующихся данных. Как это реализовать?

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

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

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