5

मान लीजिए मैं निम्न तालिकाओं को बनाए रखते हुए:एसक्यूएल: डेटाबेस का सामान्यीकरण की कमी

 ____________________    ____________________ 
    |  Organisms  |   |  Species  | 
    |--------------------|   |--------------------| 
    |OrganismId (int, PK)|   |SpeciesId (int, PK) | 
    |SpeciesId (int, FK) |∞---------1|Name (varchar)  | 
    |Name (varchar)  |   |____________________| 
    |____________________|      1 
       1         | 
       |         | 
       |         | 
       ∞         ∞ 
    ______________________  ____________________   _______________ 
    | OrganismPropsValues |  | SpeciesProps  |  |  Props  | 
    |----------------------|  |--------------------|  |---------------| 
    |OrganismId (int, FK) |  |PropId (int,PK,FK) | ∞-----1|PropId (int,PK)| 
    |PropId (int, FK)  |  |SpeciesId(int,PK,FK)|  |Name (varchar) | 
    |Value (varchar)  |  |____________________|  |_______________| 
    |______________________|            1 
       ∞               | 
       |               | 
       ----------------------------------------------------------- 

मैं क्या यहाँ प्रतिनिधित्व करने के लिए कोशिश कर रहा हूँ का एक त्वरित विवरण: लगता है हम इस तरह बिल्ली के रूप में प्रजातियों, की एक सूची है, कुत्ते , मानव, आदि। हमारे पास गुणों का एक समूह भी है (संक्षेप में प्रॉप्स ताकि मैं आरेख में इसे अधिक आसानी से फिट कर सकूं) जो कुछ पर लागू होता है लेकिन जरूरी नहीं कि सभी प्रजातियां - उदाहरण के लिए, यह पूंछ की लंबाई हो सकती है (पूंछ वाली प्रजातियों के लिए), आंखों का रंग (आंखों वाले लोगों के लिए), आदि

प्रजातियां एक लिंकर तालिका है जो परिभाषित करती है कि कौन सी गुण प्रजातियों पर लागू होते हैं - तो यहां हम एलडी में {मानव, आंखों का रंग}, {कुत्ता, आंखों का रंग}, {बिल्ली, आंखों का रंग}, {कुत्ता, पूंछ की लंबाई}, {बिल्ली, पूंछ की लंबाई} है। हमारे पास {मानव, पूंछ की लंबाई} नहीं है क्योंकि पूंछ की लंबाई स्पष्ट रूप से एक मानव पर लागू करने के लिए वैध संपत्ति नहीं है।

जीवों की तालिका प्रजातियों के वास्तविक "कार्यान्वयन" रखती है - तो यहां हमारे पास {मानव, बॉब}, {कुत्ता, रूफस}, और {बिल्ली, फ़ेलिक्स} हो सकता है।

यहां मेरा मुद्दा है: ऑर्गेनिज्मप्रॉपवल्स तालिका में, मैं प्रत्येक जीव के लिए गुणों के 'मान' को संग्रहीत करना चाहता हूं - उदाहरण के लिए, बॉब के लिए मैं {बॉब, आई कलर, ब्लू} स्टोर करना चाहता हूं। रूफस के लिए, मैं {रूफस, आई कलर, ब्राउन} और {रूफस, टेल लम्बाई, 20} (फ़ेलिक्स के लिए समान) स्टोर करना चाहता हूं। मेरी समस्या हालांकि, यह है कि मैंने जो स्कीमा विस्तृत किया है, वह {बॉब, पूंछ की लंबाई, 10} को स्टोर करना पूरी तरह से संभव है, भले ही {मानव, पूंछ की लंबाई} टुपल प्रजातिप्रॉप में मौजूद न हो। मैं इस स्कीमा को कैसे संशोधित कर सकता हूं ताकि मैं पर्याप्त सामान्यीकरण बनाए रखने के दौरान, OrganismPropsValues ​​में प्रजातिप्रॉप में परिभाषित बाधाओं को लागू कर सकूं?
SpeciesProps तालिका में SpeciesPropsId जोड़ें:

+0

डीबी (उदाहरण के ओरेकल के लिए) पर निर्भर करता है मैं सिर्फ सुझाव के लिए सम्मिलित/अपडेट करने के लिए कुछ संग्रहित प्रक्रियाओं – Yahia

+0

@Yahia धन्यवाद पैदा करेगा/हटाएँ और वहाँ किसी भी जटिल बाधाओं को लागू ..., लेकिन अगर वहाँ एक रास्ता है प्रक्रियाओं, ट्रिगर्स इत्यादि को शुरू किए बिना ऐसा करने के लिए मैं इसे पसंद करूंगा। यह एमएस-एसक्यूएल (2008) है। – Andrew

+0

जिसने मेरा सिर चोट पहुंचाई।यह पूछने के लिए भयानक होगा (सोचें कि मानव के बारे में सभी डेटा प्राप्त करने में कितने लोग शामिल होंगे!) और यह एक खराब डिजाइन है जिसे मैं नहीं जानता कि कहां से शुरू करना है। डेटाबेस ऑब्जेक्ट्स नहीं हैं और उन्हें वस्तुओं की तरह डिज़ाइन नहीं किया जाना चाहिए। ईएवी टेबल एक बेहद खराब समाधान हैं। एक असली डेटाबेस डिजाइनर किराया। – HLGEM

उत्तर

4

आप Entity-Attribute-Value antipattern लागू कर रहे हैं। यह सामान्यीकृत डेटाबेस डिज़ाइन नहीं हो सकता है, क्योंकि यह संबंधपरक नहीं है।

  • जीवों के लिए एक तालिका बनाएँ, सभी प्रजातियों के लिए आम गुण युक्त

    क्या मैं बजाय सुझाव है Class Table Inheritance डिजाइन पैटर्न है।

  • प्रति प्रजातियों में एक तालिका बनाएं, जिसमें प्रजातियों के लिए विशिष्ट गुण हों। इन तालिकाओं में से प्रत्येक में जीवों के साथ 1 से 1 संबंध है, लेकिन प्रत्येक संपत्ति अपने स्वयं के कॉलम में है।

    ____________________    ____________________ 
    |  Organisms  |   |  Species  | 
    |--------------------|   |--------------------| 
    |OrganismId (int, PK)|   |SpeciesId (int, PK) | 
    |SpeciesId (int, FK) |∞---------1|Name (varchar)  | 
    |Name (varchar)  |   |____________________| 
    |____________________| 
          1 
          | 
          | 
          1 
    ______________________ 
    | HumanOrganism  | 
    |----------------------| 
    |OrganismId (int, FK) | 
    |Sex  (enum)  | 
    |Race  (int, FK) | 
    |EyeColor (int, FK) | 
    |....     | 
    |______________________| 
    

इसका मतलब यह है कि आप कई टेबल बना होगा, लेकिन एक संबंधित रूप से सही ढंग से गुण भंडारण के लिए कई व्यावहारिक लाभ के साथ एक समंजन के रूप में इस पर विचार करें:

  • आप SQL डेटा का उपयोग कर सकते सबकुछ एक फ्री-फॉर्म वर्कर का इलाज करने के बजाय उचित रूप से टाइप करें।
  • आप कुछ गुणों को पूर्व निर्धारित निर्धारित मूल्यों से प्रतिबंधित करने के लिए बाधाओं या लुकअप टेबल का उपयोग कर सकते हैं।
  • आप गुण अनिवार्य बना सकते हैं (यानी न्यूल नहीं) या अन्य बाधाओं का उपयोग करें।
  • डेटा और अनुक्रमणिका अधिक कुशलता से संग्रहीत की जाती हैं।
  • आरडीबीएमएस निष्पादित करने के लिए आपके लिए लिखना और आसान होना आपके लिए प्रश्न आसान है।

इस डिजाइन पर अधिक के लिए, मार्टिन फाउलर की पुस्तक Patterns of Enterprise Application Architecture, या अपनी प्रस्तुति Practical Object-Oriented Models in SQL, या मेरी किताब, SQL Antipatterns: Avoiding the Pitfalls of Database Programming देखते हैं।

+0

वैकल्पिक सुझाव के लिए धन्यवाद ... मैं इस पैटर्न को देखूंगा। – Andrew

2

हम्म ...
यहाँ एक तरह से यह करने के लिए है।
OrganismPropsValues ​​तालिका में प्रजातियों के साथ PropId बदलें।
आपको थोड़ा बाधाओं को बदलने की आवश्यकता होगी।
जीवों को प्रजातियों में जोड़ने की आवश्यकता हैप्रॉप्स रोकें।
प्रोपस बाधाओं के लिए OrganismPropsValues ​​को हटाने की आवश्यकता है।

तकनीकी रूप से आपको OrganismPropsValues ​​से PropId को हटाने की आवश्यकता नहीं है, लेकिन यदि आप इसे रखते हैं तो यह डेटा को रिडंडैट कर देगा।

1

इन बाधाओं को प्राप्त करने का एक और तरीका तालिका के पीके को OrganismId छोड़कर No जोड़कर बदलना होगा। फिर पीके को यौगिक (SpeciesId, No) बनाएं। तो, "Bob" Would हो (Human, 1), "Rufus" Would हो (Dog, 1), etc.

Then, ऐड में the OrganismPropsValues table, the SpeciesId और the No (removing the OrganismId।)

यह will allow को परिवर्तन the FK से OrganismPropsValuesProps को SpeciesProps बजाय संदर्भित करने के लिए:

 ____________________    ____________________ 
    |  Organisms  |   |  Species  | 
    |--------------------|   |--------------------| 
    |SpeciesId (int, FK) |   |SpeciesId (int, PK) | 
    |No (int)   |∞---------1|Name (varchar)  | 
    |Name (varchar)  |   |____________________| 
    |PK (SpeciedId,No) |      1 
    |____________________|      | 
       1         | 
       |         | 
       |         | 
       ∞         ∞ 
    ______________________  ____________________   _______________ 
    | OrganismPropsValues |  | SpeciesProps  |  |  Props  | 
    |----------------------|  |--------------------|  |---------------| 
    |SpeciesId (int, PK) |  |PropId (int,PK,FK) | ∞-----1|PropId (int,PK)| 
    |No (int, PK)   |  |SpeciesId(int,PK,FK)|  |Name (varchar) | 
    |PropId (int, PK)  |  |____________________|  |_______________| 
    |Value (varchar)  |     1 
    |FK (SpeciesId,No)  |     | 
    |FK (SpeciesId,PropId) |     | 
    |______________________|     | 
       ∞        | 
       |        | 
       ------------------------------- 
+0

क्या @HLGEM संदर्भित करता है "ईएवी" मुद्दा के साथ 'OrganismPropsValues.Value' फ़ील्ड है। उस क्षेत्र पर अखंडता जांच करने का कोई आसान तरीका नहीं है क्योंकि यह विभिन्न प्रकार के डेटा स्टोर कर सकता है। उदाहरण के लिए, आप इस डीबी संरचना के साथ '{बॉब, टेल लम्बाई, 10}' संग्रहित करने से बचते हैं लेकिन आप '{रूफस, टेल लम्बाई, ब्लू} 'या' {बॉब, आई कलर, 20}' से नहीं बच सकते हैं। –

+0

धन्यवाद - मैंने पहले ईएवी पर मूल बातें सुनी हैं, लेकिन अभ्यास में कभी भी इसका इस्तेमाल नहीं किया है। यह वास्तव में एक साइड प्रोजेक्ट है जिस पर मैं काम कर रहा हूं - ऐसा नहीं है कि मैं इसे उत्पादन सॉफ्टवेयर में डाल रहा हूं - लेकिन जिस डेटा को मैं मॉडल करने की कोशिश कर रहा हूं वह इसके लिए कॉल कर रहा है। बेशक विकल्पों के लिए कोई सुझाव स्वागत है - मैं इसका उपयोग करने पर सेट नहीं हूं। – Andrew

2

जब भी आपके पास हीरा के आकार की निर्भरता हो, तो समग्र प्राथमिक कुंजी पर अधिक जोर देने पर विचार करें।

विशेष रूप से, जीव की पहचान अभी नहीं OrganismId द्वारा, लेकिन SpeciesId और OrganismSubId के संयोजन से (आप अभी भी OrganismId हो सकता है, लेकिन एक वैकल्पिक कुंजी के रूप में रखना - यहाँ संक्षिप्तता के लिए नहीं दिखा)।

एक बार जब आप ऐसा करते हैं, अपने मॉडल इस तरह देखने के लिए बनाया जा सकता है:

ER Model

यहाँ ध्यान दें करने के लिए महत्वपूर्ण बात यह है कि SpeciesId "प्रचारित" है नीचे इस हीरे के दोनों किनारों है आकार का ग्राफ। यह वही है जो आपको किसी संपत्ति को "मूल्य निर्दिष्ट" करने में सक्षम नहीं होने का वांछित प्रतिबंध देता है जिसे दी गई प्रजातियों के लिए "घोषित" नहीं किया गया था।

बीटीडब्ल्यू, अपनी टेबल नामकरण करते समय एकवचन का उपयोग करें। इसके अलावा, प्राकृतिक प्राथमिक कुंजी (उदाहरण के लिए SpeciesNameSpeciesId के बजाय पीके के रूप में उपयोग करने पर विचार करें) - यदि सही हो तो यह आपके जॉइन की गति को बढ़ा सकता है (विशेष रूप से क्लस्टरिंग के संयोजन के साथ)।

संबंधित मुद्दे