Как проектировать таблицы: в нормальных формах или денормализованные?
Что проверяют
Есть ли у вас критерий выбора, а не заученное «нормализация это хорошо». Для аналитика важно показать, что вы связываете структуру таблиц с тем, как данные будут записываться и читаться. Следом часто просят разобрать конкретный пример: заказ, клиент, товары.
Как отвечать
Коротко назовите нормальные формы, которые реально нужны на практике:
- 1НФ: в ячейке одно значение, нет списков через запятую и повторяющихся групп колонок вроде
phone1,phone2; - 2НФ: при составном ключе каждая колонка зависит от ключа целиком, а не от его части;
- 3НФ: нет транзитивных зависимостей. Название города не хранится в заказе, если оно определяется идентификатором города.
Дальше правило выбора. Для учётной системы (OLTP), где много мелких изменений и важна целостность, базовая точка это 3НФ: каждый факт хранится в одном месте, аномалии обновления исключены. Денормализуют точечно и по результатам замеров, когда отчёт или экран упирается в тяжёлые соединения. Способы: вычисляемое поле (сумма заказа), материализованное представление, отдельная витрина.
Для аналитики логика обратная. В хранилище данных принята схема «звезда»: таблица фактов и денормализованные справочники-измерения, а в колоночных базах вроде ClickHouse часто строят широкие плоские таблицы. Там данные загружаются пачками, читаются агрегатами, и лишние соединения стоят дороже избыточности.
Каждое дублирование в требованиях стоит сопровождать правилом синхронизации: кто и когда обновляет копию (триггер, ETL, событие) и что будет, если она отстанет.
Где спотыкаются
Называют денормализацией хранение цены в строке заказа. Это не дубль, а исторический факт: цена на момент покупки должна остаться прежней, даже если в каталоге она изменилась.
Денормализуют заранее, «для скорости», без замеров. В итоге получают расхождения в данных, а узким местом оказывается совсем другой запрос.
Не различают OLTP и аналитику и пытаются одной схемой обслужить и приём заказов, и отчёты. Правильнее разделить учётную базу и витрину.