Рассмотрите таблицу, где в одном атрибуте хранится список значений: почему такая структура не является отно...

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

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

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

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

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

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

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

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

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

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

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

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

Тогда поиск, соединение, проверка уникальности и удаление одной связи выполняются над отдельными строками. Для пары товар—поставщик можно задать составной ключ, а идентификатор поставщика — сделать внешним ключом; это позволяет выразить ограничения средствами реляционной модели.

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

Некоторые СУБД поддерживают массивы или JSON. Это может быть оправдано для редко изменяемых полуструктурированных данных, но переносит часть проверок и операций из реляционных ограничений в функции обработки содержимого. Если элементы списка участвуют в соединениях, фильтрации или ограничениях, отдельная таблица обычно даёт более предсказуемую модель.

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

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

Вариант с JSON был удобен для передачи данных во внешний API, однако целостность и поиск по отдельным складам требовали специальных средств СУБД и зависели от формата документа. Выбранное решение — отдельная таблица связей — позволило создать внешний ключ и уникальность пары товар—склад.

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

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

  1. Всегда ли массив или JSON автоматически нарушает первую нормальную форму?

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

  1. Почему отдельная таблица устраняет не только проблему поиска, но и аномалии обновления?

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

  1. Может ли хранение списка быть оправданным?

Да, если элементы не являются самостоятельными сущностями и над ними не нужны отдельные ограничения, соединения и частые изменения. Например, документ с редко анализируемыми дополнительными параметрами может быть удобнее в JSON. Компромисс состоит в том, что приложение или специальные возможности СУБД должны самостоятельно обеспечивать структуру, индексацию и проверку таких данных.