क्या कई-कई (जंक्शन) तालिका में एक विशिष्ट आईडी कॉलम की आवश्यकता है?


22

कुछ परियोजनाओं को EF के साथ शुरू करना, लेकिन मेरे पास तालिकाओं और कुंजियों आदि में शामिल होने के बारे में कुछ प्रश्न थे। चलो कहते हैं कि मेरे पास अनुप्रयोगों की एक तालिका और अनुमतियों की एक तालिका है। एप्लिकेशन की कई अनुमतियां हैं और प्रत्येक अनुमति कई एप्लिकेशन (कई-कई) से संबंधित हो सकती है।

अब, अनुप्रयोग और अनुमति तालिकाएँ आसान हैं:

Applications
--------------
PK  ApplicationID
    Name

Permissions
--------------
PK  PermissionID
    Name

लेकिन जॉइन टेबल को करने का सबसे अच्छा तरीका क्या है? मेरे पास ये दो विकल्प हैं:

ApplicationPermissions
-----------------------
PK  ApplicationPermissionID
CU  ApplicationID
CU  PermissionID

या

ApplicationPermissions
-----------------------
CPK ApplicationID
CPK PermissionID

PK = Primary Key
CPK = Composite Primary Key
CU = Composite Unique Index

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

जवाबों:


20

मेरा मानना ​​है कि आपका मतलब "जंक्शन" टेबल है, न कि "जॉइन" टेबल।

जंक्शन आईडी के लिए कोई आवश्यकता नहीं है कि यह अपना आईडी क्षेत्र है। आपको ऐसी आईडी पर जुड़ने या फ़िल्टर करने की आवश्यकता नहीं होगी। आप केवल उन मैप्स की आईडी पर आईडी से जुड़ेंगे या फ़िल्टर करेंगे। जंक्शन टेबल पर एक आईडी डिस्क स्थान की बर्बादी है।

तो आईडी से बचने के लिए "सबसे अच्छा" विकल्प है। आमतौर पर एक जंक्शन टेबल में 2 कवरिंग इंडेक्स होंगे। प्रत्येक कवर किए गए इंडेक्स को मैप किए गए आईडी में से एक को प्राथमिक सॉर्ट फ़ील्ड के रूप में उपयोग किया जाता है।

लेकिन "सर्वश्रेष्ठ" लंबे शॉट द्वारा नहीं है। अतिरेक आईडी क्षेत्र का होना बहुत मामूली समस्या है। थोड़ी मात्रा में व्यर्थ डिस्क पर आपके पास कोई डरावनी कहानियां नहीं होंगी। आईडी क्लस्टर्ड इंडेक्स को "चोरी" नहीं करेगा क्योंकि आप वैसे भी मैप किए गए कॉम्बो पर क्लस्टर नहीं करना चाहते हैं।

यदि आपका ढांचा चाहता है कि सभी तालिकाओं में एक आईडी है, तो इसके लिए जाएं। यदि आपकी टीम के डेटाबेस मानक सभी तालिकाओं को निर्धारित करते हैं, तो एक आईडी होनी चाहिए। यदि नहीं, तो इससे बचें।


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

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

4
@RobertHarvey। एक आईडी संस्थाओं के लिए एक अच्छा अभ्यास है। लेकिन एक जंक्शन कई-कई संबंधों के लिए कार्यान्वयन विवरण से अधिक है, यह अपने आप में एक इकाई नहीं है। लेकिन जैसा कि जेसी सी। स्लाइडर बताते हैं, ऐसे मामले हैं कि एक जंक्शन को एक व्यावसायिक इकाई माना जा सकता है।
माइक 30

1
"डिस्क स्थान की बर्बादी।" - मुझे लगता है कि कुछ इंजन (InnoDB?) वैसे भी एक (आंतरिक) प्राथमिक कुंजी बनाते हैं यदि आप स्वयं एक नहीं बनाते हैं - तो आप वास्तव में एक नहीं होने से डिस्क स्थान प्राप्त कर सकते हैं।
एलेक्स

@Alex। आपने मैप की गई आईडी पर एक कंपोज़िट पीके रखा है।
20:30 बजे mike30

11

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

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

एक और बात, जब आप संयुक्त पीके के साथ शुरू करते हैं, तो आप संभवतः कुछ समय बाद संयुक्त विदेशी कुंजी की आवश्यकता में भाग लेंगे (क्योंकि आप एक बिंदु पर आ सकते हैं जहां आप अपनी ApplicationPermissionsतालिका में एफके रेफरी जोड़ना चाहते हैं )। फिर अगली आवश्यकता इस FK को अन्य विशेषताओं या विदेशी कुंजियों के साथ अद्वितीय होने के लिए हो सकती है - जिसके परिणामस्वरूप समग्र जटिलता बढ़ जाएगी। कुछ भी नहीं जो अधिकांश आधुनिक डीबी सिस्टम के लिए संभालना संभव नहीं है, बेशक, लेकिन एक समान समाधान प्रोग्रामर के लिए जीवन को बहुत आसान बना देता है।

और अंत में, एक कथन SELECT ... FROM TABLE WHERE TableNameID IN (id1,id2,...)प्राथमिक कुंजी के रूप में एकल कॉलम के साथ अच्छी तरह से काम करता है, लेकिन मैंने अब तक एक एसक्यूएल बोली नहीं देखी है जो आपको संयुक्त कुंजी के साथ ऐसा करने की अनुमति देता है। यदि आप पहले से जानते हैं कि आपको इस तरह की क्वेरी की आवश्यकता नहीं होगी, ठीक है, लेकिन आश्चर्यचकित न हों यदि कल आपको एक आवश्यकता मिलती है जो इस तरह के एसक्यूएल के साथ सबसे आसानी से हल हो जाएगी।

बेशक, जब आप उम्मीद करते हैं कि आपकी ApplicationPermissionsतालिका में कई सौ लाखों पंक्तियां हैं, तो आपको कुछ इस तरह से बचने पर विचार करना चाहिए ApplicationPermissionsID


हालाँकि मैंने आपका जवाब नहीं चुना। मुझे इसके पहलू पसंद हैं। आपके विचारों के लिए धन्यवाद (upvote)।
23

6

जबकि माइक का जवाब अच्छा है, यहां कारण हैं कि मैं एक अलग आईडी फ़ील्ड जोड़ूंगा या नहीं।

  1. जंक्शन / ज्वाइन टेबल के लिए एक अलग आईडी फ़ील्ड का उपयोग करने पर विचार करें यदि इसमें आईडी के अलावा अन्य फ़ील्ड शामिल हैं । यह ध्यान देता है कि यह प्रथम श्रेणी की संस्था है।

  2. यदि API या कोई मौजूदा लॉजिक इकाइयाँ संपादित / संपादित करने के लिए एकल फ़ील्ड का उपयोग करते हैं, तो एक अलग ID फ़ील्ड का उपयोग करने पर विचार करें। जो अन्य लोगों को एक बड़ी परियोजना के संदर्भ में आपके कोड का पालन करने में मदद कर सकता है।

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


-5
table Person
   Id int identity(1,1) not null primary key
   ...other fields go here...
table Address
   Id int identity(1,1) not null primary key
   ...other fields go here...
table PersonAddress
   Id int identity(1,1) not null primary key
   PersonId int not null
   AddressId int not null

एक इंडेक्स और दोनों पर विदेशी कुंजी बनाने के लिए याद रखें PersonIdऔर AddressId

कोई फर्क नहीं पड़ता कि दूसरों को क्या लगता है कि "बेहतर" या "आपको चाहिए", यह डेटाबेस को ठीक से काम करने की अनुमति देने का सबसे सरल और आसान तरीका है।


1
मुझे लगता है कि इस दृष्टिकोण के साथ एक समस्या स्कीमा दो PersonAddressपंक्तियों को समान PersonIdऔर AddressIdमूल्यों के साथ अनुमति देती है ।
सैम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.