क्या विदेशी कुंजी को प्राथमिक कुंजी के रूप में रखना ठीक है?


103

मेरे पास दो टेबल हैं:

  • उपयोगकर्ता (उपयोगकर्ता नाम, पासवर्ड)
  • प्रोफ़ाइल (प्रोफाइलआईडी, लिंग, डेटोफर्बथ, ...)

वर्तमान में मैं इस दृष्टिकोण का उपयोग कर रहा हूं: प्रत्येक प्रोफ़ाइल रिकॉर्ड में विदेशी कुंजी के रूप में "userId" नाम का फ़ील्ड है जो उपयोगकर्ता तालिका से लिंक करता है। जब कोई उपयोगकर्ता पंजीकरण करता है, तो उसका प्रोफ़ाइल रिकॉर्ड स्वचालित रूप से बनाया जाता है।

मैं अपने मित्र सुझाव से भ्रमित हूं: "userId" फ़ील्ड को विदेशी और प्राथमिक कुंजी के रूप में रखना और "profileId" फ़ील्ड को हटाना। कौन सा दृष्टिकोण बेहतर है?


3
इकाई ढाँचा उत्पन्न करता है कि (पहले कोड के साथ) शून्यऑन (और एक) के लिए-एक संबंध। तो ... यह संभव है। क्या यह सबसे अच्छा तरीका है ... यह एक और सवाल है। लेकिन यह मान्य है। मैंने अपना डेटाबेस बनाते समय कभी ऐसा नहीं किया (लेकिन मैंने भी कभी ऐसा नहीं सोचा था)।
राफेल अल्टहॉस

जवाबों:


132

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

इसके बजाय, एक फ़ील्ड खोजें जो तालिका में प्रत्येक रिकॉर्ड को विशिष्ट रूप से पहचानती है, या प्राथमिक कुंजी के रूप में कार्य करने के लिए एक नया फ़ील्ड (या तो एक ऑटो-इंक्रीमेंटिंग पूर्णांक या एक GUID) जोड़ें।

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


74
एक समग्र प्राथमिक कुंजी जिसमें दो विदेशी कुंजी शामिल हैं, कई-से-कई संबंधों को लागू करने के लिए भी पूरी तरह से ठीक है।
सही

1
@rezadru: यह मेरे लिए सही अधिकार से असहमत होने के लिए बहुत दूर है, लेकिन एक सरोगेट कुंजी लगभग हमेशा एक बेहतर विकल्प है।
रॉबर्ट हार्वे

4
एक विदेशी कुंजी के बारे में कुछ भी तय नहीं करता है कि यह 1 से कई है (या लिखित रूप में "डुप्लिकेट की अनुमति दें")। मुख्य बाधाएं और विशिष्टता एक डेटाबेस में दो अलग-अलग अवधारणाएं हैं और आसानी से एक सूचकांक को जोड़ने के रूप में आसानी से मिलाया जा सकता है (जो एक तीसरा अलग अवधारणा होगा)।
अंधभक्ति

40

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


11

हां, प्राथमिक कुंजी का विदेशी कुंजी होना कानूनी है। यह एक दुर्लभ निर्माण है, लेकिन यह इसके लिए लागू होता है:

  • 1: 1 संबंध। अलग-अलग अनुमतियों और विशेषाधिकारों के कारण दोनों तालिकाओं को एक में विलय नहीं किया जा सकता है, केवल तालिका स्तर पर लागू होते हैं (2017 तक, ऐसा डेटाबेस विषम होगा)।

  • 1: 0..1 संबंध। उपयोगकर्ता प्रकार के आधार पर प्रोफ़ाइल मौजूद हो सकती है या नहीं भी।

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


यदि टेबल को अक्सर जोड़ा जाता है, तो एक नकारात्मक प्रदर्शन होगा, जो सामान्य अनुशंसा की ओर जाता है कि 1 तालिका बेहतर है। कुछ मामलों में डेटा हमेशा अलग-अलग एक्सेस किया जाता है, इसमें शामिल नहीं होता है, और 1: 1 संबंध के साथ दो तालिकाओं के होने के लिए एक संगठनात्मक लाभ हो सकता है।
अंधभक्ति

4

यह आमतौर पर एक से एक संबंध रखने के लिए बुरा व्यवहार माना जाता है। ऐसा इसलिए है क्योंकि आप केवल एक तालिका में दर्शाए गए डेटा को प्राप्त कर सकते हैं और समान परिणाम प्राप्त कर सकते हैं।

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

मैं वर्तमान में एक ऐसी प्रणाली पर काम कर रहा हूँ जहाँ उपयोगकर्ता एक ऐप के साथ उपयोग करने के लिए पंजीकरण कोड बना सकते हैं। जिन कारणों से मैं अंदर नहीं जाऊंगा, मैं उपयोगकर्ताओं की तालिका में आवश्यक कॉलम जोड़ने में असमर्थ हूं। इसलिए मैं कोड तालिका के साथ एक से एक मार्ग पर जा रहा हूं।


2
मैं आपके साथ ज्यादातर सहमत हूं कि अतिरिक्त स्तंभ के समान तालिका में सभी डेटा होने के कई फायदे हैं। हालाँकि यह गलत है .. "आप केवल एक तालिका में दर्शाए गए डेटा को प्राप्त कर सकते हैं और एक ही परिणाम प्राप्त कर सकते हैं" ..: एक अलग तालिका उपयोगी हो सकती है, उदाहरण के लिए अगर प्रोफ़ाइल तालिका प्रविष्टि वैकल्पिक है। उदाहरण के लिए, प्रत्येक बैंक ग्राहक के पास इंटरनेट बैंकिंग पंजीकरण नहीं हो सकता है। उस स्थिति में आईबी पंजीकरण तालिका का उपयोग अन्य तालिकाओं को आगे के बाल रिकॉर्ड होने से प्रतिबंधित करने के लिए किया जा सकता है। फिर से, यह आईबी पंजीकरण तालिका के लिए एक नए पीके के साथ भी किया जा सकता है।
टेडी

1
@ टेडी इसी तरह मैं ज्यादातर आपके द्वारा कही गई बातों से सहमत हूं। हालांकि, मूल प्रश्न में वे कहते हैं "... उसका प्रोफ़ाइल रिकॉर्ड स्वचालित रूप से बनाया गया है ..." यह कहते हुए कि प्रोफ़ाइल तालिका वैकल्पिक नहीं है। ऐसी स्थिति में जहां प्रोफ़ाइल तालिका वैकल्पिक थी, हाँ, एक अलग तालिका के रूप में होने योग्य है। लेकिन फिर, वे एक ही तालिका में अशक्त स्तंभों का उपयोग कर सकते हैं।
दशमी तिथि

1
एक अलग दूसरी तालिका का उपयोग करके, हम तीसरी तालिका में प्रवेश को रोक सकते हैं जो केवल उन लोगों के लिए अनुमत है जिनके पास दूसरी तालिका में प्रविष्टि है।
टेड्डी

बिल्कुल, लेकिन अगर हम 1 से 1 तालिकाओं का विलय करते हैं तो हम शून्य मान वाले लोगों को तीसरी (तकनीकी रूप से दूसरी) तालिका तक पहुंचने से रोक सकते हैं। लेकिन ओपी ने जो प्रश्न पूछा है उसमें "... साइन अप करते समय .." है ... उसका प्रोफ़ाइल रिकॉर्ड स्वचालित रूप से बनाया गया है ... ", यह निरर्थक बना रहा है।
दशमी तिथि

इस पर विचार करने का मेरा प्राथमिक कारण यह है कि डेटा वेयरहाउसिंग में, तथ्य और आयाम तालिकाओं को अलग करना अच्छा अभ्यास है। अलग-अलग तथ्य और आयाम तालिकाएँ उपयोगी संकेत हैं, जैसे कि पॉवरपिव, पॉवरबीआई और टैब्लेउ जैसे सॉफ्टवेयर के साथ काम करते समय।
मार्को

4

हां, उन तालिकाओं के बीच एक से एक संबंध के मामले में एक विदेशी कुंजी एक प्राथमिक कुंजी हो सकती है


2
यह सुपरटाइप-सबटाइप डिजाइन के लिए भी उपयोगी है। उपप्रकार तालिकाएँ प्राथमिक कुंजी सुपरटाइप तालिका के लिए विदेशी कुंजी संदर्भ होनी चाहिए।
एक्सेलियो

2

मैं वह न करता। मैं profileIDतालिका की प्राथमिक कुंजी के रूप में रखूंगाProfile

एक विदेशी कुंजी केवल दो तालिकाओं के बीच एक संदर्भित अवरोध है

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

http://www.aisintl.com/case/primary_and_foreign_key.html


1
हो सकता है - यदि आपके पास User.UserID और Profile.UserID के बीच FK बाधा है, तो यह प्रोफ़ाइल.UserID पर एक सूचकांक रखने के लिए दृढ़ता से अनुशंसा की जाएगी। क्यों नहीं टेबल प्रोफाइल पर प्राथमिक संकुल सूचकांक, एक दूसरे सूचकांक और डेटाबेस इंजन के लिए अनावश्यक काम की एक पूरी बचत?
उल्टा इंजीनियर 14

1

यह व्यापार और प्रणाली पर निर्भर करता है।

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


0

संक्षिप्त उत्तर: DEPENDS .... इस विशेष मामले में, यह ठीक हो सकता है। हालांकि, विशेषज्ञ इसके खिलाफ हर बार सिफारिश करेंगे; अपने मामले सहित।

क्यों?

जब वे विचाराधीन तालिका में विदेशी हों (तब किसी अन्य तालिका में उत्पन्न) तालिका में कुंजी अद्वितीय रूप से अद्वितीय होती हैं। उदाहरण के लिए, एक आइटम ID एक ITEMS तालिका में अद्वितीय हो सकता है, लेकिन एक ORDERS तालिका में नहीं, क्योंकि एक ही प्रकार का आइटम संभवतः किसी अन्य क्रम में मौजूद होगा। इसी तरह, आदेश आईडी ORDERS तालिका में अद्वितीय (हो सकता है) हो सकता है, लेकिन ORDER_DET Colors जैसी किसी अन्य तालिका में नहीं जहां एक पंक्ति में कई आइटम मौजूद हो सकते हैं और किसी विशेष क्रम में किसी विशेष आइटम के खिलाफ क्वेरी करने के लिए, आपको दो के संयोजन की आवश्यकता है इस तालिका के लिए PK के रूप में FK (order_id और item_id)।

मैं डीबी विशेषज्ञ नहीं हूं, लेकिन यदि आप तार्किक रूप से अपने पीके के रूप में एक ऑटो-जेनरेट किए गए मूल्य को सही ठहरा सकते हैं, तो मैं ऐसा करूंगा। यदि यह व्यावहारिक नहीं है, तो दो (या शायद अधिक) एफके का एक संयोजन आपके पीके के रूप में काम कर सकता है। लेकिन, मैं किसी भी मामले के बारे में नहीं सोच सकता जहाँ पीके के रूप में एक एकल एफके मूल्य को उचित ठहराया जा सकता है।

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