2009-09-05 30 views
18

मैं डेटाबेस के डिज़ाइन पर काम कर रहा हूं जिसका उपयोग कई अलग-अलग स्रोतों से उत्पन्न डेटा को संग्रहीत करने के लिए किया जाएगा। जिन मामलों को मैं संग्रहीत कर रहा हूं उन्हें मूल स्रोतों द्वारा अद्वितीय आईडी असाइन की गई हैं। मेरे द्वारा संग्रहीत प्रत्येक इंस्टेंस में उस स्रोत के बारे में जानकारी होनी चाहिए, जिस आईडी से यह इस स्रोत से जुड़ा हुआ आईडी था।समग्र प्राथमिक कुंजी

---------------------------------------------------------------- 
| source_id | id_on_source | data        | 
---------------------------------------------------------------- 
| 1   | 17600  | ...        | 
| 1   | 17601  | ...        | 
| 2   | 1   | ...        | 
| 3   | 1   | ...        | 
---------------------------------------------------------------- 

ध्यान दें कि जब id_on_source प्रत्येक स्रोत के लिए अद्वितीय है, यह संभव है के लिए एक ही id_on_source विभिन्न स्रोतों के लिए पाया जा सकता है:

उदाहरण के लिए, निम्न तालिका है कि समस्या को दिखाता है पर विचार करें।

मुझे संबंधपरक डेटाबेस की अच्छी समझ है, लेकिन एक विशेषज्ञ या यहां तक ​​कि एक अनुभवी उपयोगकर्ता से बहुत दूर है। इस डिजाइन के साथ मुझे जिस समस्या का सामना करना पड़ता है वह है जिसे मुझे प्राथमिक कुंजी के रूप में उपयोग करना चाहिए। डेटा (source_id, id_on_source) की एक समग्र प्राथमिक कुंजी के उपयोग को निर्देशित करता है। थोड़ा गुगल करने के बाद मुझे समग्र प्राथमिक कुंजी के पेशेवरों और विपक्ष पर कुछ गर्म बहसें मिलीं, हालांकि, मुझे थोड़ा उलझन में छोड़ दिया गया।

तालिका में अन्य तालिकाओं के साथ एक से अधिक संबंध होंगे, और इस प्रकार अन्य तालिकाओं की विदेशी कुंजी में संदर्भित किया जाएगा।

मैं एक विशिष्ट RDBMS से बंधा नहीं कर रहा हूँ और मुझे यकीन है कि अगर यह मायने रखती है तर्क की खातिर नहीं हूँ, लेकिन कहते हैं कि मैं SQLite और MySQL साथ काम करना पसंद करते हैं।

इस मामले में एक समग्र विदेशी कुंजी का उपयोग करने के पेशेवर और विपक्ष क्या हैं? तुम किसे वरीयता दोगे?

उत्तर

26

मुझे व्यक्तिगत रूप से दर्दनाक होने के लिए समग्र प्राथमिक कुंजी मिलती है। आपके द्वारा "स्रोत" तालिका में शामिल होने वाली प्रत्येक तालिका के लिए आपको Source_id और id_on_source फ़ील्ड दोनों को जोड़ना होगा।

मैं आपकी स्रोत तालिका पर एक मानक ऑटो-वृद्धिशील प्राथमिक कुंजी तैयार करूंगा और Source_id और id_on_source कॉलम पर एक अद्वितीय अनुक्रमणिका जोड़ूंगा।

यह आपको अन्य तालिकाओं पर विदेशी कुंजी के रूप में स्रोत तालिका की आईडी जोड़ने की अनुमति देता है।

आम तौर पर मैं भी कई व्यवस्थाएं और टूलींग उत्पादों के भीतर समग्र प्राथमिक कुंजी के लिए समर्थन मिल गया है पर सबसे अच्छा और दूसरों में न के बराबर

+0

युग और टाइमस्टैम्प (1, 1 9 70 ~ 2106) (2, 2106 ~ 2242) को स्टोर करने के लिए एक समग्र पीके के बारे में सोचें। चूंकि INT8, INT16, INT32, INT64 बाइनरी आधारित हैं और बिट आकार में आधारित हैं, तो हमारे पास वर्ष 99 99 के लिए उपयुक्त आईएनटी आकार नहीं है। INT पर्याप्त नहीं है और बड़ा इंट बहुत बड़ा है। – Alix

12

समग्र कुंजी प्रबंधन करने के लिए कठिन और शामिल होने के लिए धीमी गति से कर रहे हैं "विचित्र" किया जाना है। चूंकि आप सारांश तालिका बना रहे हैं, इसलिए एक सरोगेट कुंजी (यानी एक ऑटोइनक्रिकमेंट/पहचान कॉलम) का उपयोग करें। वहां अपने प्राकृतिक कुंजी कॉलम छोड़ दें।

इसमें कई अन्य लाभ भी हैं। मुख्य रूप से, यदि आप किसी कंपनी के साथ विलय करते हैं और उनके पास एक ही स्रोत है, लेकिन पुन: उपयोग की गई कुंजी है, तो आप नहीं हैं, जो सरोगेट कुंजी का उपयोग कर परेशानी में पड़ने जा रहे हैं।

यह डाटा वेयरहाउसिंग में व्यापक रूप से स्वीकार्य सर्वोत्तम अभ्यास है (जो आप कर रहे हैं उससे काफी बड़ा उपक्रम है, लेकिन अभी भी प्रासंगिक है), और अच्छे कारण के लिए। सरोगेट डेटा अखंडता और त्वरित जुड़ता है प्रदान करते हैं। आप प्राकृतिक चाबियों के साथ बहुत जल्दी जला सकते हैं, इसलिए पहचानकर्ता के रूप में उनसे दूर रहें, और केवल आयात प्रक्रिया पर उनका उपयोग करें।

+3

आप किस बारे में बात कर रहे हैं, बिल्कुल? यदि आपके पास विलय पर संघर्ष है, तो क्या आप शायद डुप्लिकेट डेटा की बजाय त्रुटि नहीं चाहते हैं? –

+2

@ जेफ डेविस वास्तव में, सरोगेट कुंजी अनावश्यकता को आमंत्रित करते हैं। – nottinhill

+0

क्या आप समझा सकते हैं कि संयुक्त कुंजी क्यों शामिल हो रही है? मैं समझने की कोशिश कर रहा हूं कि मैं वास्तव में समग्र कुंजी का उपयोग क्यों नहीं करूंगा। अगर मेरे पास एक सारणी है जो एक समग्र कुंजी (ए, बी) के साथ संदर्भित करती है, तो मुझे वास्तव में पूरे पीके में शामिल नहीं होना पड़ता है। मैं 'ऑन (ए.ए = ए.ए.ए.ए.) लिख सकता हूं, है ना? तो यह धीमा क्या बनाता है? – displayname

1

कुछ लोग आपको वैश्विक स्तर पर अद्वितीय आईडी (GUID) का उपयोग करने की सलाह देते हैं: merge replication and transactional replication with updating subscriptions use uniqueidentifier columns to guarantee that rows are uniquely identified across multiple copies of the table। यदि मूल्य बनाया गया है तो वैश्विक रूप से अद्वितीय है, तो आपको इसे अद्वितीय बनाने के लिए स्रोत_आईडी जोड़ने की आवश्यकता नहीं है।


हालांकि एक uniqueid एक अच्छा प्राथमिक कुंजी है, मैं मानता हूँ कि यह आम तौर पर अपने संकुल सूचकांक के रूप में एक अलग, प्राकृतिक (जरूरी नहीं अद्वितीय) कुंजी का उपयोग करना बेहतर है। उदाहरण के लिए यदि एक अनूठा पीके है जो कर्मचारियों की पहचान करता है, तो आप क्लस्टर इंडेक्स को विभाग बनना चाहेंगे (यदि आपके चयन बयान आमतौर पर किसी दिए गए विभाग के भीतर सभी कर्मचारियों को पुनर्प्राप्त करते हैं)। यदि आप क्लस्टरेड इंडेक्स के रूप में एक अनक्यूसिड का उपयोग करना चाहते हैं, तो NEWSEQUENTIALID() फ़ंक्शन देखें: यह अनुक्रमिक अद्वितीय मान बनाता है, जो (अनुक्रमिक होने) में बेहतर क्लस्टरिंग प्रदर्शन होता है।

+0

बस सावधान रहें (SQL सर्वर में) ** नहीं ** अपनी GUID प्राथमिक कुंजी को तालिका की क्लस्टर कुंजी (जो डिफ़ॉल्ट रूप से है) बनाने के लिए - किम ट्रिप के उत्कृष्ट लेख को क्यों नहीं देखें: http: // www। sqlskills.com/BLOGS/KIMBERLY/post/GUIDs-as-PRIMARY-KEYs-andor-the-clustering-key.aspx –

+0

पते के मेरे उत्तर में जोड़ा गया है कि GUID के बारे में – ChrisW

+0

टिप्पणी करें: यदि आवश्यकता केवल अनूठी है प्रत्येक रिकॉर्ड के लिए आईडी, हाँ, यह काम करेगा। लेकिन अगर आपको यह जानने की ज़रूरत है कि स्रोत क्या था, तो आपको या तो स्रोत आईडी को रिकॉर्ड में पोस्ट करना होगा, या आपको कहीं और लुकअप टेबल (यक) रखना होगा, या आपको ढूंढने वाले सभी संभावित स्रोतों को खोजना होगा वह GUID (डबल यक)। अगर आपको स्रोत आईडी को वैसे भी रखना है, तो एक GUID कोई मूल्य नहीं जोड़ता है। – Jay

6

मेरा मानना ​​है कि समग्र कुंजी एक बहुत ही प्राकृतिक और वर्णनात्मक डेटा मॉडल बनाती है। मेरा अनुभव ओरेकल से आता है और मुझे नहीं लगता कि एक समग्र पीके बनाते समय कोई तकनीकी समस्याएं हैं। असल में डेटा डिक्शनरी का विश्लेषण करने वाले किसी भी व्यक्ति को टेबल के बारे में कुछ समझ जाएगा। आपके मामले में यह स्पष्ट होगा कि प्रत्येक स्रोत_आईडी में अद्वितीय id_on_source होना चाहिए।

प्राकृतिक चाबियों का उपयोग अक्सर गर्म बहस बनाता है, लेकिन जिन लोगों को मैं एक अच्छे डेटा मॉडल परिप्रेक्ष्य से प्राकृतिक चाबियों के साथ काम करता हूं।

+1

हां, लेकिन एक बच्चे की मेज से प्राथमिक कुंजी में शामिल होने से आपको दो, तीन, चार स्थितियों में शामिल होना पड़ता है - और यह प्राथमिक कुंजी और इस प्रकार आपके सभी सूचकांक को फटकारता है। यह प्राकृतिक महसूस हो सकता है, लेकिन हकीकत में, यह एक अच्छा विचार नहीं है –

+1

बिंदु लिया गया। आम तौर पर आप पाएंगे कि प्राथमिक संस्थाओं में डीबी ने अद्वितीय कुंजी उत्पन्न की होगी। जैसे ग्राहक आईडी के साथ ग्राहक तालिका। इसकी आमतौर पर माध्यमिक संबंधित सारणी होती है जिसमें समग्र कुंजी होती है और उनमें से अधिकतर में एफके संदर्भित नहीं होता है। जैसे यदि आप ग्राहक फोन नंबरों का इतिहास संग्रहीत करते हैं तो ग्राहक_contact_history तालिका में कॉलम ग्राहक आईडी, फोन, बदलना समग्र पीके हो सकता है क्योंकि ये 3 चीजें स्वाभाविक रूप से अद्वितीय हैं। – softveda

+0

मैं आपको एक वोट दे रहा हूं क्योंकि मैं सिद्धांत रूप से सहमत हूं। लेकिन मुझे नहीं लगता कि यह इस विशेष उदाहरण में सबसे अच्छा समाधान है! – Jay

1

एक अतिरिक्त आईडी कॉलम जोड़ना आपको एक के बजाय दो विशिष्टता बाधाओं को लागू करने के लिए छोड़ देगा।

अन्य संदर्भ तालिकाओं में विदेशी कुंजी के रूप में उस अतिरिक्त आईडी कॉलम का उपयोग करके, जो स्वयं स्वाभाविक रूप से प्रस्तुत की जाने वाली कुंजी की बजाय, आपको अधिक शामिल करना होगा, अर्थात् उन सभी मामलों में जहां आपको मूल soruce_ID प्लस ID_on_source की आवश्यकता है संदर्भ तालिका से डेटा के साथ।

+0

क्या आपको इस एप्लिकेशन में विशिष्टता लागू करने की आवश्यकता है? यदि आप इन अन्य प्रणालियों से डेटा प्राप्त कर रहे हैं, तो संभवतः यह विशिष्टता को लागू करने की उनकी समस्या है। यह आपको वापस पूरा करने की आवश्यकता के लिए वापस आता है। – Jay

+0

अतिरिक्त जुड़ने के लिए: मैं स्रोत और id_on_source को उसी तालिका में रखूंगा, चाहे वह प्राथमिक कुंजी हो या नहीं। मुझे अनुवाद करने के लिए दूसरी लुक-अप तालिका रखने के लिए यहां कोई कारण नहीं दिख रहा है। इसे सब एक साथ रखें। – Jay

8

आपके पास एक व्यावसायिक आवश्यकता है कि उन दो विशेषताओं का संयोजन अद्वितीय है। तो, आपके पास उन दो विशेषताओं पर UNIQUE बाधा होनी चाहिए। चाहे आप इसे UNIQUE बाधा कहते हैं "प्राथमिक" वास्तव में केवल एक वरीयता है, इसका दस्तावेज़ीकरण से अलग प्रभाव नहीं पड़ता है।

एकमात्र सवाल यह है कि क्या आप एक अतिरिक्त कॉलम जोड़ते हैं और इसे UNIQUE चिह्नित करते हैं। ऐसा करने का एकमात्र कारण मैं प्रदर्शन कर सकता हूं, जो एक वैध कारण है।

व्यक्तिगत रूप से, मैं अनिवार्य रूप से एक ग्राफ, जहां उत्पन्न कॉलम अनिवार्य रूप से संकेत दिए गए हैं में हर डेटाबेस मोड़ के दृष्टिकोण पसंद नहीं है और आपको बस अगले एक से traversing कर रहे हैं। मुझे लगता है कि एक संबंध प्रणाली की सभी महानता को फेंकता है। यदि आप वापस कदम उठाते हैं और इसके बारे में सोचते हैं, तो आप उन स्तंभों का एक समूह पेश कर रहे हैं जिनके आपके व्यवसाय का कोई मतलब नहीं है। आपको मेरी related blog post में रुचि हो सकती है।

3

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

के रूप में दूसरों का उल्लेख किया है, समग्र कुंजी है क्योंकि आपके मिलती है सभी टुकड़ों को शामिल करने के लिए है सबसे अन्य परिस्थितियों में एक दर्द कर रहे हैं। यह, क्वेरी, धीमी आदि

दो भाग चाबियाँ बुरा नहीं कर रहे हैं टाइप करने के लिए जो गलतियों के लिए और अधिक संभावित अर्थ है अधिक है; मैं उनको काफी बार करता हूं। मैं एक तीन भाग कुंजी का उपयोग करने के लिए अनिच्छुक हूँ। तीन हिस्सों से अधिक, मैं इसे भूल जाऊंगा।

अपने उदाहरण में, मैं बहुत कम समग्र कुंजी का उपयोग करके प्राप्त किया जा रहा है पर शक। बस एक नया अनुक्रम संख्या का आविष्कार और स्रोत और स्रोत कुंजी साधारण गुण हो।

2

मैं कई समग्र कुंजी का उपयोग कर समस्याओं में भाग गया और इसलिए मैं इसे (अधिक नीचे) की अनुशंसा नहीं करता, मुझे यह भी पता चला कि एक स्वतंत्र/सरोगेट कुंजी (प्राकृतिक की बजाय) में लाभ होने पर मुझे वापस उपयोगकर्ता गलतियों को रोल करें। समस्या यह थी कि संबंधों के एक सेट के माध्यम से, एक तालिका दो तालिकाओं में शामिल हो गई जहां समग्र के प्रत्येक पंक्ति भाग के समान था (यह तीसरे सामान्य रूप में उपयुक्त था - माता-पिता के दो हिस्सों के बीच तुलना)। मैंने जॉइन टेबल में समग्र रिश्ते के उस हिस्से को डुप्लिकेट किया (इसलिए parent1ID, other1ID, parent2ID, other2ID के बजाय parentID, other1ID, other2ID था) लेकिन अब संबंध प्राथमिक कुंजी में परिवर्तन अपडेट नहीं कर सका, क्योंकि यह कोशिश की गई प्रत्येक मार्ग के माध्यम से इसे दो बार करने के लिए और बीच में विफल रहा।

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