Денормализация — стратегия повышения производительности уже нормализованной базы данных путём размещения избыточных данных там, где это наиболее эффективно. Это может включать добавление полей в существующие таблицы, создание новых таблиц или дублирование существующих.
В отличие от нормализации, цель которой — декомпозиция таблиц, изоляция контекстов и сосредоточение атрибутов конкретной сущности в одной таблице, денормализация упрощает доступ к данным и ускоряет выполнение запросов. Часто это достигается созданием таблиц с предварительно рассчитанными результатами отчётов. Важно: денормализация применяется к уже нормализованной базе данных. Ненормализованная база, объявленная «денормализованной», свидетельствует об ошибках проектирования.
Применение денормализации
Денормализация оправдана, если выгода от повышения производительности превышает негативные последствия. Рассмотрим несколько ситуаций:
- Хранение исторических данных: Если важны значения полей на момент создания записи (например, имя клиента, адрес), добавление таблицы истории изменений или дополнительных полей в исходную таблицу может быть решением.
- Повышение производительности запросов: Запросы, объединяющие множество таблиц с большими объемами данных (например, для получения имени клиента и проданных ему товаров), могут быть значительно ускорены добавлением необходимых полей в целевые таблицы.
- Ускорение создания отчётов: Ежедневная генерация отчетов по большим объёмам данных может сильно замедлить систему. Денормализация с предварительным расчетом необходимых данных позволит ускорить этот процесс.
- Предварительные вычисления часто запрашиваемых значений: Хранение часто используемых результатов расчетов вместо их повторного вычисления существенно экономит время.
Негативные последствия
Несмотря на преимущества, денормализация имеет недостатки:
- Увеличение занимаемого места на диске: из-за дублирования данных.
- Аномалии данных: изменения данных требуют корректного обновления их копий. Для решения этой проблемы можно использовать триггеры, транзакции и хранимые процедуры.
- Сложности в документации: каждое изменение требует обновления документации.
- Замедление других операций: вставка, модификация и удаление данных могут стать медленнее. Однако, если эти операции редки, а сложные запросы сильно замедляют систему, это может быть оправдано.
- Увеличение объёма кода: необходимо написать дополнительный код для поддержания целостности данных и оптимизации запросов.
Пример денормализации в CRM-системе
Рассмотрим упрощенную модель CRM-системы с таблицами: User_Account, Client, Product, Task, Call, Meeting, Task_Outcome, Meeting_Outcome, Call_Outcome, Product_Offered, Product_Sold, Supply_Order, Write_Off. Эта модель хорошо нормализована. Денормализация может выглядеть так:
- Таблица Product: добавлено поле units_in_stock для хранения актуального количества товара на складе. Это ускорит запросы, избавляя от необходимости вычисления этого значения из нескольких таблиц (units_ordered, units_sold, units_offered, units_write_off). Однако, требуется обновление units_in_stock при каждой операции ввода, обновления или удаления в связанных таблицах.
- Таблица Task: добавлены поля client_name и user_first_last_name, хранящие актуальные значения на момент создания задачи. Эти данные могут меняться со временем.
- Таблица Product_Offered: добавлены поля price_per_unit и price (вычисляемое значение unit_sold * price_per_unit). Это позволяет хранить актуальную цену на момент предложения товара и избегать повторных вычислений.
- Таблица Product_Sold: аналогично Product_Offered.
- Новая таблица Statistics_per_Year: содержит предварительно рассчитанную статистику по клиентам за каждый год (по успешным задачам, встречам и звонкам). Это ускоряет создание отчётов.
Денормализация — эффективный инструмент повышения производительности, но её применение должно быть взвешенным. Необходимо анализировать производительность системы и обосновывать необходимость денормализации. Тщательное документирование изменений поможет избежать проблем. В некоторых случаях денормализация может быть необходима для достижения требуемой производительности, но это крайняя мера. Кэширование данных в приложении также является эффективным методом оптимизации.