Какие принципы нормализации данных вы используете при формировании табличных структур
Что проверяют
Понимаете ли вы, какие проблемы решает нормализация, и умеете ли остановиться вовремя. Следом обычно дают таблицу заказов с именем клиента и названием товара в каждой строке, просят её разложить, а потом спрашивают, где бы вы денормализовали обратно.
Как отвечать
Начните с цели: нормализация убирает аномалии. Если адрес клиента хранится в каждом заказе, его придётся обновлять во многих строках, клиента нельзя завести без заказа, а удаление последнего заказа стирает и клиента.
- 1НФ: атомарные значения и никаких повторяющихся групп. Не
phones = '111, 222'в одной ячейке, а отдельная таблица телефонов; - 2НФ: неключевые поля зависят от всего составного ключа. В
order_items(order_id, product_id, product_name)название зависит только отproduct_id, значит ему место вproducts; - 3НФ: нет транзитивных зависимостей, когда неключевое поле зависит от другого неключевого.
city_nameрядом сcity_idв таблице клиентов лишний; - НФБК (BCNF): каждый детерминант является потенциальным ключом. Большинство схем в 3НФ ей уже соответствуют.
На практике схему доводят до 3НФ, а денормализуют точечно и осознанно: счётчики, агрегаты для отчётов, материализованные представления.
Выгодно назвать нюанс: цена в строке заказа не дублирует products.price. Это факт на момент покупки, и хранить её там правильно, иначе смена цены в каталоге перепишет историю.
Со стороны Java покажите, как схема видна в коде. Нормализованная модель это связи @ManyToOne и @OneToMany в JPA, а значит риск N+1 запросов, который решают JOIN FETCH или @EntityGraph. Схему ведут миграциями Flyway или Liquibase, а не ddl-auto=update.
Где спотыкаются
Путают 2НФ и 3НФ. Разница: 2НФ про зависимость от части составного ключа, 3НФ про зависимость от неключевого поля.
Считают, что нормализация всегда замедляет систему. Соединения стоят денег, но с индексами на внешних ключах большинство запросов работает быстро, а денормализация без замеров приносит рассинхрон данных.
Хранят списки в строке через запятую ради простоты. Поиск превращается в LIKE без индекса, внешний ключ на элемент списка не поставить, и целостность никто не проверяет.