Нормализация
Классический теоретический вопрос с практическим продолжением: «а когда денормализуете?». Второе интереснее первого и проверяет понимание размена, а не заученные определения нормальных форм.
Стержень: нормализация обеспечивает хранение каждого факта ровно в одном месте и убирает аномалии изменения. Плата за это - соединения таблиц при чтении.
// Формулировки: «зачем нормализация?», «что нарушает первую нормальную форму?», «когда денормализация оправдана?»
Аномалии изменения - вот в чём смысл
Нормализация нужна не для красоты схемы, и объясняется это одним примером. Пусть адрес клиента скопирован в каждый его заказ, а заказов у него тысяча. Клиент переехал. Теперь надо обновить тысячу строк, и это уже неприятно, но терпимо.
Дальше начинается интересное. Обновление шло пачками, три пачки не прошли по таймауту, никто не заметил. С этого момента на вопрос «какой адрес у клиента» система даёт два разных ответа в зависимости от того, из какого заказа смотреть. Восстановить, какой из них правильный, уже нельзя - оба выглядят одинаково законно.
Первая нормальная форма требует атомарности значений. Список телефонов через запятую в одном поле ломает сразу три вещи: поиск по телефону (база видит текст, а не два номера), проверку формата и возможность связать телефон с чем-либо ещё.
// Отдельно стоит различать дубль и зафиксированный факт. Цена в позиции заказа - не избыточность, хотя внешне выглядит как копия цены товара. Это цена на момент сделки, самостоятельный факт, который обязан не меняться при смене прайса. Убрать её «ради нормализации» - значит потерять историю продаж.
Денормализация как осознанный размен
Денормализация оправдана там, где чтение частое и тяжёлое, а данные меняются редко: витрины отчётности, кэширующие таблицы, материализованные представления. То есть ровно там, где аномалии изменения не страшны, потому что изменений почти нет.
Обязательное условие - явный механизм поддержания копий в согласованном состоянии и заданное допустимое отставание. Без первого копии тихо разъезжаются, без второго начинается вечный спор «в отчёте одно, в системе другое», где обе стороны правы.
Лечить надо адресно: витрина под конкретный отчёт, а не возврат к плоской таблице. Логическая модель при этом остаётся чистой и продолжает быть источником правды, а денормализация живёт на физическом уровне, где ей и место.
// Отставание называют числом и записывают в требования: «витрина обновляется раз в час, данные могут отставать до шестидесяти минут». Тогда расхождение перестаёт быть багом и становится согласованным свойством.
Почему в хранилищах живут иначе
В аналитических хранилищах нагрузка принципиально другая. Здесь не точечные изменения по одной записи, а массовые запросы, которые читают миллионы строк и что-то по ним считают.
Под такую нагрузку хорошо ложится схема «звезда»: одна широкая таблица фактов - продажи, события, транзакции - и вокруг неё справочники измерений. Соединений получается мало, а колоночное хранение позволяет читать только те столбцы, которые нужны запросу, не трогая остальные.
Обновления там редки и идут пакетами по расписанию, поэтому аномалии изменения почти не возникают. Отход от нормализации здесь сознательный, а не от невежества.
// Это полезно держать в голове на собесе: вопрос «почему в хранилище денормализуют» проверяет не знание схемы «звезда», а понимание того, что нормализация - инструмент под конкретную нагрузку, а не универсальная догма.
Как отвечать: «Схема нормализована, чтение стало медленным. Что предложишь?»
Точечную денормализацию под конкретные запросы, а не возврат к плоской структуре. Сначала посмотрю, какие именно запросы страдают: почти всегда это два-три тяжёлых отчёта, а не вся система, и лечить надо их. Под них делаю витрину или материализованное представление, а логическую модель оставляю чистой - она остаётся источником правды. Обязательно фиксирую в требованиях, как часто обновляется копия и какое отставание допустимо, потому что бизнес будет принимать по ней решения и должен знать, насколько свежие данные видит. Возврат к плоской таблице вернул бы все аномалии изменения разом, а рассогласованные данные обходятся дороже, чем медленный отчёт.
Кандидат лечит адресно, сохраняет чистоту логической модели и не забывает про требование к отставанию копии. Последнее называют редко, а именно оно снимает будущие споры о цифрах.
На чём валятся
- −− Считают нормализацию самоцелью и доводят схему до нечитаемости.
- −− Денормализуют без правила обновления копий - витрина тихо отстаёт.
- −− Убирают зафиксированную цену сделки, приняв её за избыточность.
- −− Не задают допустимое отставание витрины и получают спор «в отчёте одно, в системе другое».
- −− Хранят список значений в одном поле через запятую и теряют поиск по нему.
Проверьте себя
Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.
- Когда денормализация оправдана?A)Когда таблиц стало больше десятиB)Когда чтение критично и данные почти не меняютсяC)Когда разработчику неудобно писать соединенияD)Когда в базе появились составные ключи
показать ответ и разбор
+B)Когда чтение критично и данные почти не меняются// разбор: Осознанная денормализация — размен: платим избыточностью и риском рассинхрона за скорость чтения. Оправдана там, где запросы частые и тяжёлые, а данные меняются редко: витрины отчётности, кэширующие таблицы. Обязательное условие — явный механизм поддержания копий в согласованном состоянии.
- В заказе хранят итоговую сумму, хотя её можно посчитать из позиций. Это ошибка?A)Нет, при условии фиксации на момент сделкиB)Да, если в базе есть представленияC)Да, вычисляемое значение хранить не принятоD)Нет, потому что так быстрее считаются отчёты
показать ответ и разбор
+A)Нет, при условии фиксации на момент сделки// разбор: Хранить итог правильно, когда он фиксирует юридический факт: сумма сделки на момент оформления не должна меняться из-за смены цен или ставки НДС. Тогда это не избыточность, а самостоятельный факт. Плохо, когда итог хранят просто для скорости и забывают пересчитывать при изменении позиций.
- Аналитик довёл модель до высоких нормальных форм, чтение стало медленным. Что обсудить с командой?A)Вернуться к плоской таблице целикомB)Отказаться от отчётности по этим даннымC)Увеличить мощность сервера базы данныхD)Точечную денормализацию под известные запросы
показать ответ и разбор
+D)Точечную денормализацию под известные запросы// разбор: Нормализация — не самоцель, а инструмент против аномалий. Если конкретные запросы страдают, лечат адресно: витрина под отчёт, кэширующая таблица, материализованное представление. Логическая модель при этом остаётся чистой, а денормализация живёт на физическом уровне с явными правилами обновления.
- Почему в аналитических хранилищах сознательно отходят от нормализации?A)Там данные загружаются только вручнуюB)Там оптимизируют чтение больших выборокC)Там связи между таблицами не используютD)Там не требуется целостность данных
показать ответ и разбор
+B)Там оптимизируют чтение больших выборок// разбор: Нагрузка в хранилище другая: массовые агрегирующие запросы вместо точечных изменений. Схема «звезда» с широкой таблицей фактов и справочниками сокращает число соединений и укладывается на колоночное хранение. Обновления там редки и идут пакетами, поэтому аномалии изменения почти не страшны.
- Что обязательно описать в требованиях, вводя денормализованную копию данных?A)Имя таблицы и порядок её полейB)Объём дискового пространства под копиюC)Момент обновления и допустимое отставаниеD)Права доступа к исходной таблице
показать ответ и разбор
+C)Момент обновления и допустимое отставание// разбор: Копия неизбежно отстаёт от источника, и бизнес должен знать, насколько. Обновляется ли витрина при каждой записи, раз в пять минут или ночью — от этого зависит, можно ли принимать по ней решения. Незаданное отставание порождает классический конфликт: в отчёте одно, в системе другое.
дальше
Теорию прочитали. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.