ฉันจะสลายตารางนี้โดยไม่สูญเปล่าได้หรือไม่?


10

ฉันสะดุดกับปัญหาการออกแบบฐานข้อมูลที่ไม่ได้อยู่ในลีกของฉันและกูรู DBA ของฉันที่ไปใช้ยังอยู่ในช่วงซ้อมหนีไฟ

ในสาระสำคัญฉันมีตารางที่มีคีย์หลักต่อไปนี้ (PK สำหรับความกะทัดรัด):

child_id   integer
parent_id  integer
date       datetime

child_idและparent_idเป็นกุญแจต่างประเทศในตารางกิจการ ตาราง "child" นั้นมี foreign key ไปยังตาราง "parent" และแท้จริงแล้วแต่ละตัวchild_idจะอ้างอิงเหมือนกันparent_idตามที่คาดไว้โดยตารางข้างต้น ในความเป็นจริงปรากฎว่ามีโค้ดพิเศษบางอย่างที่ทำให้ทั้งสองซิงค์กันอยู่

ซึ่งทำให้สามเณรการปรับสภาพ overenthusiastic นี้พูดว่า "ฉันควรลบความซ้ำซ้อนแทน!"

ฉันย่อยสลายต่อไปนี้:

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
คีย์ในตารางเดิมของคุณคืออะไร มันควรพึ่งพาอะไร satsify? คุณดูเหมือนจะพูดว่า 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" ซึ่งไม่น่าจะมีปัญหาหาก child_id เป็นคีย์หลัก

แต่ไม่มีวิธีที่จะบอกโดยไม่ทราบว่าข้อมูลหมายถึงอะไรและคุณเป็นเพียงคนเดียวในชุดข้อความนี้ที่รู้เรื่องนั้น (แต่เรายินดีที่จะให้คุณอธิบายให้เรา)

เท่าที่เกี่ยวข้องกับตารางดั้งเดิมคุณดูเหมือนจะพูดว่า child_id -> parent_id หากเป็นกรณีนี้ทำไม parent_id ในตารางเริ่มแรก ทำไมคีย์ไม่ได้เป็นเพียง (child_id, วันที่) โดยมีการอ้างอิงคีย์ต่างประเทศไปยังตาราง "child" สำหรับฉันแล้วดูเหมือนว่าประเภทของความซ้ำซ้อนที่คุณกำลังพูดถึงอาจได้รับการแก้ไขโดยการวางคอลัมน์ "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)ยังคงเดิม FK อยู่ใน 2 คอลัมน์ของข้อ จำกัด ใหม่

หรือ

  • เอา FK ออกจากตารางลูกปัจจุบัน
  • สร้างตารางใหม่(PK,FK:child_id, FK:parent_id)ที่เป็น 1: 1 พร้อมลูก
  • ตารางปัจจุบันของคุณ(PK,FK: child_id, PK,FK: parent_id, PK:date)ยังคงเป็นเช่นเดิม แต่ FK อยู่ใน 2 คอลัมน์ไปยังตารางใหม่

หากไม่มีอะไรอื่นมันอาจเป็นแรงบันดาลใจให้คุณ ...

หากฉันเข้าใจถูกต้องแล้วมันจะลบความซ้ำซ้อนและรหัส ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.