क्या हर टेबल में एक सिंगल-फील्ड सरोगेट / कृत्रिम प्राथमिक कुंजी होनी चाहिए?


33

मैं सामान्य रूप से सरोगेट / कृत्रिम कुंजी के एक लाभ को समझता हूं - वे नहीं बदलते हैं और यह बहुत सुविधाजनक हो सकता है। यह सच है कि क्या वे एकल या एकाधिक क्षेत्र हैं - जब तक वे 'कृत्रिम' नहीं हैं।

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

स्पष्ट होने के लिए, यह प्रश्न कृत्रिम बनाम प्राकृतिक के बारे में नहीं है - लेकिन इस बारे में है कि क्या सभी कृत्रिम कुंजी एकल-फ़ील्ड होनी चाहिए


जवाबों:


28

मैं हमेशा नहीं, बल्कि ज्यादातर समय हां कहने जा रहा हूं

ये कुछ परिस्थितियाँ हैं जिनमें आपको सरोगेट या कृत्रिम कुंजी की आवश्यकता नहीं है:

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

कुछ स्थितियां ऐसी भी हैं जहां पुराने-वफादार मोनोटोनॉली बढ़ते पूर्णांक सरोगेट कुंजी आदर्श नहीं है। आपके पास कुंजी हो सकती है जो अल्फ़ान्यूमेरिक सरोगेट हैं। ये शामिल हो सकते हैं:

  • स्थिति जहां आपको कई, स्वतंत्र स्रोतों से डेटा मर्ज करने की आवश्यकता होती है। प्रमुख टकरावों से बचने के लिए आप पहचान कुंजी के बजाय GUID का उपयोग कर सकते हैं।
  • ऐसी स्थितियाँ जहाँ आपको गैर-संख्यात्मक कुंजी अभ्यावेदन का उपयोग करने के लिए मजबूर किया जाता है। मान लीजिए कि आपको लाइसेंस प्लेट डेटाबेस मिल गया है। आपकी कुंजी शुद्ध संख्या के बजाय अल्फ़ान्यूमेरिक मान हो सकती है।
  • स्थिति जहां कुछ बाहरी आवश्यकता आपको अपने प्रमुख मूल्य पर संपीड़न लागू करने के लिए मजबूर करती है। एक इंट 32 के लिए 10 अंकों का उपयोग करने के बजाय आप छह आधार 36 अंकों का उपयोग कर सकते हैं।

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

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


"सरोगेट कुंजी का उपयोग करना आपको इस जाल में गिरने से बचाएगा" सवाल सरोगेट बनाम प्राकृतिक के बारे में नहीं है, बल्कि सिंगल-फील्ड बनाम मल्टी-फील्ड सरोगेट के बारे में है।
जैक डगलस

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

मैंने इस प्रश्न को नहीं बदला जैसा कि आप इतिहास से देख सकते हैं, मैंने केवल जोर दिया है जहां मुझे लगा कि यह स्किम-पाठकों की मदद करेगा
जैक डगलस

12

नहीं।

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

मैं निम्नलिखित उदाहरणों में अपनी बात को स्पष्ट करने का प्रयास करूँगा, जिसमें:

  • brand कार मार्के, उदाहरण के लिए फोर्ड, टोयोटा आदि है
  • dealer एक भौतिक डीलरशिप है, जो एक ब्रांड से जुड़ा है (उदाहरण के लिए एक फोर्ड डीलरशिप केवल बिक्री के लिए)
  • model कार का प्रकार है जैसे फोर्ड फोकस, फोर्ड फिएस्टा आदि
  • stock प्रत्येक डीलरशिप के लिए वर्तमान फोरकोर्ट कार गिनती है

हम एक ही क्षेत्र किराए की कुंजी बनाते हैं के लिए dealerऔर modelके रूप में इस प्रकार है:

create table brand( brand_id integer primary key );

create table dealer( dealer_id integer primary key, 
                     brand_id integer references brand )

create table model( model_id integer primary key, 
                    brand_id integer references brand )

create table stock( model_id integer references model, 
                    dealer_id integer references dealer, 
                    quantity integer,
                      primary key(model_id, dealer_id) )

फिर उस पंक्ति में stockएक फोर्ड dealerको "टोयोटा" मॉडल से जोड़ना संभव है। केवल जोड़ने brand_id references brandसे stockसमस्या बदतर हो जाती है। दूसरी ओर यदि हम प्राथमिक कुंजी के भाग के रूप में विदेशी कुंजी को निम्नानुसार रखते हैं:

create table brand( brand_id integer primary key );

create table dealer( brand_id integer references brand, 
                     dealer_id integer, 
                       primary key(brand_id, dealer_id) )

create table model( brand_id integer references brand, 
                    model_id integer, 
                      primary key(brand_id, model_id) )

create table stock( brand_id integer, 
                    model_id integer, 
                    dealer_id integer, 
                    quantity integer,
                      primary key(brand_id, model_id, dealer_id),
                      foreign key(brand_id, model_id) references model,
                      foreign key(brand_id, dealer_id) references dealer )

अब यह नियम कि "फोर्ड" डीलर केवल "फोर्ड" कारों को स्टॉक कर सकते हैं, मॉडल द्वारा स्वाभाविक रूप से लागू किया जाता है।

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

create table dealer( brand_id integer references brand, 
                     dealer_id serial unique, 
                       primary key(brand_id, dealer_id) )

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

1
इसलिए "आपके व्यवसाय के नियम बदल सकते हैं"। यह किसी भी व्यावसायिक नियम के बारे में सच है और हमेशा पुन: मॉडल के लिए संभावित रूप से कठिन होने वाला है। मुझे आमतौर पर बताया जाता है कि व्यावसायिक नियम क्या हैं - मैं उन्हें अपने लिए तय नहीं करता।
जैक डगलस

1
क्या आप कह रहे हैं कि व्यावसायिक नियमों को लागू करने के लिए DRI का उपयोग बिल्कुल नहीं किया जाना चाहिए? नहीं है कि केवल एक चीज DRI करता है? - यहां तक ​​कि सरल विदेशी चाबियाँ DRI द्वारा लागू व्यावसायिक नियम हैं।
जैक डगलस

4
बेशक डीआरआई व्यावसायिक नियमों को लागू करता है। आपको यह तय करना होगा कि कौन से नियम कोड में और आपके स्कीमा में लागू होने जा रहे हैं। कोड परिवर्तन की तुलना में स्कीमा परिवर्तन लगभग हमेशा कठिन होते हैं। दो प्रकार के व्यावसायिक नियम हैं जो आपके डेटा मॉडल में जा सकते हैं। एक वहाँ है और एक नहीं है। आपके व्यवसाय के लिए महत्वपूर्ण डेटा की मूलभूत प्रकृति बहुत अधिक नहीं बदलती है। उस डेटा पर आपके द्वारा संचालित विशिष्ट तरीके बहुत अधिक अस्थिर हैं । कारों की तरह एक नियम एक निर्माता है जो डेटा मॉडल में है। डीलरों की तरह एक नियम कारों के दो ब्रांडों को कभी नहीं बेचेगा।
जोएल ब्राउन

4
"स्कीमा परिवर्तन कोड परिवर्तन की तुलना में लगभग हमेशा कठिन होते हैं" IMO विपरीत सच है। वास्तव में मैं वस्तुतः आपकी हर बात से असहमत हूं, लेकिन मुझे संदेह है कि आपके साथ टॉस करने का कोई भी तर्क है, इसलिए मैं इसे उस पर छोड़ दूंगा।
जैक डगलस

12

"निर्भर करता है"

हां: प्राकृतिक कुंजी व्यापक और गैर-संख्यात्मक होने पर सरोगेट पहचान / AUTONUMBER फ़ील्ड अच्छे होते हैं। नोट: यह "पीके" और क्लस्टर किए गए सूचकांक के संलयन को मानता है जो डिफ़ॉल्ट रूप से SQL सर्वर और Sybase आदि में होता है।

नहीं: कई / कई तालिकाएँ जब 2 मूल कुंजियाँ पर्याप्त होती हैं। या जब प्राकृतिक कुंजी छोटी और निश्चित लंबाई होती है जैसे मुद्रा कोड

बेशक, एक braindead ORM (पढ़ें: (n) हाइबरनेट) इन नियमों को रद्द कर सकता है ...

संपादित करें: प्रश्न को फिर से पढ़ना

2 सरोगेट माता-पिता की चाबियों के साथ कई / कई टेबल में एक एकाधिक कॉलम पीके होगा।
हालाँकि, इसे किसी अन्य सरोगेट कॉलम की आवश्यकता नहीं है।

यदि किसी तालिका में एक सरोगेट (पहचान आदि) कुंजी है तो इसके लिए कई कॉलम होने की आवश्यकता नहीं है।

आपके पास एक सुपर कुंजी हो सकती है जिसमें सरोगेट शामिल है लेकिन यह अन्य नियमों (जैसे उपप्रकारों ) को लागू करने के लिए होगा

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