Могу ли я без потерь разложить эту таблицу?

10

Я наткнулся на проблему с дизайном базы данных, которая выходит за рамки моей лиги, и мой гуру 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, пока даты не станут слишком большими.

Что приводит меня сюда со следующими вопросами:

  1. Это разложение 5NF? Хотя я бы сказал, что он допускает аномалии вставки, он также, похоже, следует примеру Wiki, который сам следует этому руководству . Фраза (выделение мое) «мы можем восстановить все истинные факты из нормализованной формы, состоящей из трех отдельных типов записей», дает мне особую паузу, поскольку независимо от того, сколько мусора я закачиваю Table_1, естественное соединение все равно игнорирует его.

  2. Предположим, мне не нравится это разложение (мне не нравится). Я свободно признаю, что практическим решением является оставить таблицу и код такими, какие они есть. Но, теоретически, есть ли способ разложить и / или добавить ограничения, чтобы я ушел от первой таблицы и сохранил свои бизнес-правила?

Тревор
источник
1
Каковы ключи в вашей исходной таблице? Какие зависимости он должен удовлетворить? Похоже, вы говорите, что child_id-> parent_id, и в этом случае child_id и parent_id не могут быть частью одного и того же ключа в этой таблице.
nvogel
1
@trevor: Вы когда-нибудь просматривали ответы здесь? Последний раз видели через 19 минут после запроса. Ответы пришли позже.
ГБН

Ответы:

9

Нормализация основана на функциональных зависимостях. Функциональные зависимости связаны с семантикой; они имеют отношение к тому, что означают данные . Когда вы упрощаете реальную проблему до уровня «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 более точны, чем описания.

Майк Шеррилл 'Cat Recall'
источник
1
+2 к напоминанию о «функциональной зависимости»
jcolebrand
3

Попробуй это...

  • Добавить уникальное ограничение (child_id,parent_id)в дочернюю таблицу
  • Ваша текущая таблица (PK,FK:child_id, PK,FK:parent_id, PK:date)остается как есть, FK находится на 2 столбца с новым уникальным ограничением

или

  • Удалить FK из текущей дочерней таблицы
  • Создайте новую таблицу (PK,FK:child_id, FK:parent_id)1: 1 с дочерним элементом
  • Ваша текущая таблица (PK,FK: child_id, PK,FK: parent_id, PK:date)остается как есть. но ФК на 2 колонки к новой таблице

Если ничего другого, это может вдохновить вас ...

Если я правильно понял, это удалит избыточность и код ...

ГБН
источник