В таблице заказов адрес клиента хранится в каждой строке заказа. Какое свойство нормализованной схемы наруш...

В таблице заказов адрес клиента хранится в каждой строке заказа. Какое свойство нормализованной схемы нарушено, если адрес должен быть единственным для клиента?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Нарушена нормализация, поскольку атрибут адреса зависит от клиента, а не непосредственно от идентификатора заказа. При первичном ключе заказа это создаёт зависимость неключевого атрибута от другого неключевого атрибута и обычно означает нарушение третьей нормальной формы.

Следствие — избыточность данных и аномалии обновления: один и тот же адрес придётся менять во множестве строк, иначе данные станут противоречивыми.

Исторический контекст

Нормализация появилась как способ уменьшить избыточность в реляционных таблицах и сделать зависимости между данными явными. Исходная проблема заключалась в том, что изменение одной сущности требовало синхронно исправлять множество повторяющихся записей.

Разделение сущностей по смыслу позволяет хранить факт один раз, связать его внешним ключом и передать контроль целостности базе данных.

Постановка проблемы

Предположим, в таблице заказов ключом является идентификатор заказа, а каждая строка содержит идентификатор клиента и его текущий адрес. Один клиент с несколькими заказами приводит к многократному хранению одного адреса.

Если клиент переехал, часть строк может быть обновлена, а часть — нет. Возникают противоречивые адреса, лишние операции записи и риск того, что приложение случайно создаст разные варианты одного значения.

Подробное решение

При условии, что адрес описывает именно клиента, его следует вынести в таблицу клиентов. Таблица заказов должна ссылаться на клиента внешним ключом, а не дублировать клиентские атрибуты.

Логическая зависимость выглядит так: идентификатор заказа определяет клиента, а идентификатор клиента определяет адрес. Поэтому адрес транзитивно зависит от идентификатора заказа, хотя не является свойством самого заказа.

Нормализация устраняет эту зависимость из таблицы заказов. Первичный ключ идентифицирует одну сущность, внешний ключ связывает заказ с клиентом, а ограничения NOT NULL, UNIQUE и CHECK при необходимости дополнительно защищают допустимые состояния данных.

Однако вынос адреса не всегда правилен. Если заказ должен хранить адрес доставки на момент оформления, изменение текущего адреса клиента не должно менять историю заказа. В таком случае адрес заказа является историческим снимком и его дублирование — осознанное моделирование, а не нарушение.

Компромисс состоит в выборе между согласованностью текущих данных и сохранением исторического состояния. Нельзя оценивать дублирование только по форме таблицы: сначала нужно определить семантику атрибута и его функциональные зависимости.

Ситуация из практики

В интернет-магазине адрес клиента сначала хранили в заказах. После переезда клиента операторы исправляли только последний заказ, поэтому отчёты по доставке содержали разные адреса для одного клиента.

Рассматривались два варианта. Первый — оставить адрес в заказе и автоматически обновлять все старые строки: это сохраняет простую структуру чтения, но искажает исторические адреса. Второй — хранить текущий адрес в таблице клиентов, а в заказе отдельно сохранять адрес доставки как снимок: это требует больше полей и логики, зато разделяет текущие данные клиента и историю заказа.

Выбрали второй вариант. Ссылка на клиента использовалась для текущих операций, а копия адреса в заказе — для фактической доставки и аудита. В результате переезд клиента не изменял уже оформленные заказы, а текущие данные оставались единообразными.

Что кандидаты часто упускают

  1. Всегда ли дублирование адреса в заказе является нарушением нормализации?

Нет. Если адрес в заказе — это снимок состояния на момент оформления, он функционально зависит от заказа и является частью его истории. Такое дублирование оправдано бизнес-смыслом, хотя требует явно зафиксировать правило: адрес заказа не синхронизируется с текущим адресом клиента.

  1. Достаточно ли внешнего ключа, чтобы устранить проблему?

Нет. Внешний ключ гарантирует наличие связанного клиента, но не запрещает хранить в строке заказа отдельный устаревший или противоречивый адрес. Для устранения избыточности адрес нужно убрать из заказа, если он не является историческим снимком.

  1. Какая аномалия возникает при удалении последнего заказа клиента?

Если сведения о клиенте хранятся только в таблице заказов, удаление последнего заказа может уничтожить единственную запись о клиенте. Это аномалия удаления. Выделение таблицы клиентов позволяет хранить клиента независимо от наличия заказов и управлять жизненным циклом сущностей отдельными ограничениями.