Собесов

Денормализация: когда стоит нарушить нормальные формы

SQLНормализацияСредняяMiddle

Условие

Какие проблемы возникают при чрезмерной нормализации и какие преимущества даёт денормализация?

Решение

Проблемы избыточной нормализации

Проблема Что происходит
Много JOIN'ов Запрос обходит 5–10 таблиц для одного отчёта
Медленные ad-hoc запросы Аналитик тратит минуты на запрос вместо секунд
Сложность написания Легко забыть JOIN и получить декартово произведение
Когнитивная нагрузка Новые сотрудники долго входят в схему

Что даёт денормализация

  • Скорость чтения — все данные в одной таблице, без JOIN'ов.
  • Упрощение кода — короткие SELECT'ы.
  • Кеш-дружественность — последовательное чтение «широкой» таблицы.
  • Колоночное хранение — в ClickHouse/Vertica широкая таблица читается выборочно по нужным колонкам.

Цена денормализации

  • Избыточностьclient_city дублируется в каждой строке фактов.
  • Аномалии обновления — изменив город клиента, нужно обновить миллионы строк или принять историчность (SCD-2).
  • Объём — таблица растёт.

Где применяется

Слой Норма Почему
OLTP (транзакционная БД) Высокая (3NF) Частые INSERT/UPDATE, целостность важнее скорости чтения
DWH staging Средняя Зеркало источников
DWH витрины (data marts) Низкая (звезда/снежинка) Аналитические запросы должны быть быстрыми
OLAP-куб / широкая таблица Очень низкая (1 таблица) Чтение в колонках, нет UPDATE

Звезда (Star schema)

Факт в центре, рядом — небольшие dim-таблицы. Это компромисс: нормализованные dim'ы (3NF) + плоский факт. Один-два JOIN на запрос.

Подводные камни

  1. «Денормализуем всё» — для OLTP это убийство производительности на UPDATE.
  2. Не путать денормализацию с дублированием. Денормализация — осознанный архитектурный выбор; дубли — баг.
  3. Историчность — при денормализации атрибутов из dim в fact нужно решить: сохранять snapshot на момент транзакции или брать «текущее».
  4. Object storage / Iceberg — там денормализованные «широкие» таблицы — норма, потому что нет UPDATE in-place.

Эталонный ответ

Чрезмерная нормализация усложняет запросы (много JOIN'ов) и снижает производительность чтения. Денормализация ускоряет аналитические запросы за счёт избыточности. В OLTP — нормализуем, в DWH-витринах — денормализуем (звезда/снежинка).

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти