Я наткнулся на проблему с дизайном базы данных, которая выходит за рамки моей лиги, и мой гуру DBA выключен в пожарных учениях.
По сути, у меня есть таблица со следующим первичным ключом (PK для краткости):
child_id integer
parent_id integer
date datetime
child_id
и parent_id
являются внешними ключами таблиц сущностей. Сама «дочерняя» таблица также содержит внешний ключ к «родительской» таблице, и вот, каждая из них child_id
всегда ссылается на то же, parent_id
что и ожидаемая таблица выше. На самом деле, оказывается, есть какой-то дополнительный код, поддерживающий синхронизацию двух.
Что заставляет этого сверхъестественного новичка по нормализации говорить: «Я должен вместо этого удалить избыточность!»
Я разлагаю на следующее:
Table_1 PK:
child_id integer
date datetime
Table_2 PK:
parent_id integer
date datetime
Table_3: (already exists)
child_id integer PRIMARY KEY
parent_id integer FOREIGN KEY
И вот, когда я естественным образом присоединяюсь к этим парням, я возвращаю исходный стол. Это мое понимание, что делает это 5NF.
Однако теперь я понимаю, что есть скрытое бизнес-правило.
Обычно даты, связанные с данным, child_id
должны быть подмножеством дат, связанных с соответствующим parent_id
. Вы можете видеть, что первая таблица применяет это правило.
Моя декомпозиция не применяет правило, потому что вы можете свободно добавлять в таблицу 1, пока даты не станут слишком большими.
Что приводит меня сюда со следующими вопросами:
Это разложение 5NF? Хотя я бы сказал, что он допускает аномалии вставки, он также, похоже, следует примеру Wiki, который сам следует этому руководству . Фраза (выделение мое) «мы можем восстановить все истинные факты из нормализованной формы, состоящей из трех отдельных типов записей», дает мне особую паузу, поскольку независимо от того, сколько мусора я закачиваю
Table_1
, естественное соединение все равно игнорирует его.Предположим, мне не нравится это разложение (мне не нравится). Я свободно признаю, что практическим решением является оставить таблицу и код такими, какие они есть. Но, теоретически, есть ли способ разложить и / или добавить ограничения, чтобы я ушел от первой таблицы и сохранил свои бизнес-правила?
Ответы:
Нормализация основана на функциональных зависимостях. Функциональные зависимости связаны с семантикой; они имеют отношение к тому, что означают данные . Когда вы упрощаете реальную проблему до уровня «parent_id, child_id, date», и вы не включаете никаких примеров данных, вы действительно ограничиваете объем помощи, которую может дать добросовестный разработчик базы данных.
Тот факт, что у вас есть ключ {child_id, parent_id, date} в одной таблице и что у вас есть (кажется) уникальная пара {child_id, parent_id} в дочерней таблице, не обязательно означает, что часть комбинации является избыточной , Это может означать, что в таблице, в которой {child_id, parent_id, date} в качестве первичного ключа, пара атрибутов {child_id, parent_id} должна ссылаться на дочернюю таблицу в первую очередь.
Если это так, вы можете использовать
FOREIGN KEY (child_id, parent_id) REFERENCES child (child_id, parent_id)
. Для этого вам нужно ограничение UNIQUE для пары столбцов (child_id, parent_id) в таблице child, что не должно быть проблемой, если child_id является его первичным ключом.Но невозможно сказать, не зная, что означают данные, и вы единственный, кто знает это. (Но мы были бы рады позволить вам объяснить это нам.)
Что касается исходной таблицы, вы говорите, что child_id -> parent_id. Если это так, то почему parent_id находится в исходной таблице? Почему ключ не просто (child_id, date) со ссылкой внешнего ключа на таблицу child? Мне кажется, что вид избыточности, о котором вы говорите, может быть решен путем удаления столбца "parent_id".
SQL DDL и примеры данных в форме операторов INSERT помогут нам вам помочь. Операторы DDL и INSERT более точны, чем описания.
источник
Попробуй это...
(child_id,parent_id)
в дочернюю таблицу(PK,FK:child_id, PK,FK:parent_id, PK:date)
остается как есть, FK находится на 2 столбца с новым уникальным ограничениемили
(PK,FK:child_id, FK:parent_id)
1: 1 с дочерним элементом(PK,FK: child_id, PK,FK: parent_id, PK:date)
остается как есть. но ФК на 2 колонки к новой таблицеЕсли ничего другого, это может вдохновить вас ...
Если я правильно понял, это удалит избыточность и код ...
источник