Чи можна без втрат розкласти цю таблицю?


10

Я натрапив на проблему дизайну бази даних, яка не входить до моєї ліги, і мій гуру DBA до DBA не працює на пожежних навчаннях.

По суті, у мене є таблиця з наступним первинним ключем (ПК для стислості):

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 хвилин після запиту. Відповіді надійшли пізніше.
gbn

Відповіді:


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_id є його первинним ключем.

Але неможливо сказати, не знаючи, що означають дані, і ти єдиний у цій темі, хто це знає. (Ми з радістю дозволимо вам пояснити нам це.)

Що стосується оригінальної таблиці, ви, здається, говорите, що child_id -> parent_id. Якщо це так, то чому саме в початковій таблиці в першу чергу знаходиться parent_id? Чому ключ не просто (child_id, дата) із зовнішнім ключовим посиланням на таблицю "дитина"? Мені здається, що вид надмірності, про який ви говорите, може бути вирішений шляхом випадання стовпця "parent_id".

SQL DDL та вибіркові дані у вигляді тверджень INSERT допомагають нам допомогти вам. Оператори DDL та INSERT є більш точними, ніж описи.


1
+2 для нагадування про "функціональну залежність"
jcolebrand

3

Спробуйте це...

  • Додайте унікальне обмеження (child_id,parent_id)в дочірній таблиці
  • Ваша поточна таблиця (PK,FK:child_id, PK,FK:parent_id, PK:date)залишається такою, якою є, ФК знаходиться в 2 стовпцях до нового унікального обмеження

або

  • Видаліть FK з поточної дочірньої таблиці
  • Створіть нову таблицю, (PK,FK:child_id, FK:parent_id)яка дорівнює 1: 1 з дитиною
  • Ваша поточна таблиця (PK,FK: child_id, PK,FK: parent_id, PK:date)залишається такою, якою є. але ФК знаходиться в 2 стовпцях до нової таблиці

Якщо нічого іншого, це може надихнути вас ...

Якщо я правильно зрозумів, це видалить надмірність та код ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.