क्या मैं दोषरहित रूप से इस तालिका का विघटन कर सकता हूं?


10

मैं एक डेटाबेस डिजाइन समस्या है कि मेरी लीग से बाहर है ठोकर खाई है, और मेरे गो-टू डीबीए गुरु आग अभ्यास पर बंद है।

संक्षेप में, मेरे पास निम्न प्राथमिक कुंजी (संक्षिप्तता के लिए 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 है? जबकि मैं कहूंगा कि यह सम्मिलन विसंगतियों को अनुमति देता है, यह विकी उदाहरण का अनुसरण भी करता है, जो स्वयं इस गाइड का अनुसरण करता है । वाक्यांश (जोर मेरा) "हम तीन अलग-अलग रिकॉर्ड प्रकारों से मिलकर एक सामान्य रूप से सभी सही तथ्यों को फिर से संगठित कर सकते हैं" मुझे विशेष विराम देता है, क्योंकि मैं चाहे कितना भी कचरा पंप करता हो 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)। ऐसा करने के लिए, आपको टेबल "चाइल्ड" में कॉलम (चाइल्ड_आईडी, पेरेंट_ड) की जोड़ी पर एक यूनीक्विक बाधा की आवश्यकता है, जो कि चाइल्ड_आईडी इसकी प्राथमिक कुंजी है, तो यह समस्या नहीं होनी चाहिए।

लेकिन यह जानने का कोई तरीका नहीं है कि डेटा का क्या मतलब है, और आप जानते हैं कि इस सूत्र में केवल वही है जो यह जानता है। (लेकिन हम आपको इसे हमें बताने में प्रसन्न होंगे।)

जहाँ तक मूल सारणी का सवाल है, तो आप यह कहते हुए प्रतीत होते हैं कि child_id -> parent_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)इस प्रकार है, FK नए अनूठे अवरोध के 2 स्तंभों पर है

या

  • वर्तमान चाइल्ड टेबल से FK निकालें
  • (PK,FK:child_id, FK:parent_id)बच्चे के साथ 1: 1 का नया टेबल बनाएं
  • आपकी वर्तमान तालिका इस (PK,FK: child_id, PK,FK: parent_id, PK:date)प्रकार है। लेकिन FK नए टेबल पर 2 कॉलम पर है

अगर और कुछ नहीं, तो यह आपको प्रेरित कर सकता है ...

अगर मैंने सही ढंग से समझा है, तो यह अतिरेक और कोड को हटा देगा ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.