समग्र प्राथमिक कुंजी एक बुरा अभ्यास है? [बन्द है]


15

मैं जानना चाहता हूं कि क्या समग्र प्राथमिक कुंजी एक खराब अभ्यास है और यदि नहीं, तो किन परिदृश्यों का उपयोग करने की सिफारिश की जाती है।

मेरा प्रश्न इस लेख पर आधारित है

डेटाबेस डिजाइन गलतियों

समग्र प्राथमिक कुंजी के बारे में हिस्सा:

बुरा अभ्यास नंबर 6: समग्र प्राथमिक कुंजी

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

एक समग्र प्राथमिक कुंजी की छवि

हालांकि, यह सिर्फ एक सम्मेलन है और निश्चित रूप से, डीबीई समग्र प्राथमिक कुंजी की परिभाषा की अनुमति देते हैं, जो कई डिजाइनरों को लगता है कि अपरिहार्य हैं। इसलिए, अतिरेक के साथ, समग्र प्राथमिक कुंजी एक डिजाइन निर्णय है।

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


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

यह लेख एक बिंदु को इंगित करता है, लेकिन अगर हम इसकी "सर्वोत्तम प्रथाओं" में लोकप्रिय रूपरेखा (उदाहरण के लिए रेल) ​​देखते हैं तो यह इस प्रकार की प्राथमिक कुंजी का समर्थन नहीं करता है, इसलिए मैंने पूछा क्यों? यह तकनीकी कठिनाइयों या कुछ और के लिए है।
हैकवान

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

1
एक GUID एक INTEGER से बेहतर कैसे है [सीरियल | Auto_Increment | पहचान | <जो भी_इन्टेगर_यौ_ जैसा>]?
विएर्स

4
मैं उस लेखक को नहीं
paparazzo

जवाबों:


31

कहने का मतलब है कि "Composite keys as PRIMARY KEY is bad practice"ister बकवास का उपयोग !

समग्र PRIMARY KEYएस अक्सर एक "बहुत अच्छी बात" होती है और रोजमर्रा की जिंदगी में आने वाली प्राकृतिक स्थितियों को मॉडल करने का एकमात्र तरीका है!

क्लासिक डेटाबेस -१०१ छात्रों और पाठ्यक्रमों और कई छात्रों द्वारा उठाए गए कई पाठ्यक्रमों के शिक्षण उदाहरण के बारे में सोचो!

टेबल कोर्स और छात्र बनाएँ:

CREATE TABLE course
(
  course_id SERIAL,
  course_year SMALLINT NOT NULL,
  course_name VARCHAR (100) NOT NULL,
  CONSTRAINT course_pk PRIMARY KEY (course_id)
);


CREATE TABLE student
(
  student_id SERIAL,
  student_name VARCHAR (50),
  CONSTRAINT student_pk PRIMARY KEY (student_id)
);

मैं आपको PostgreSQL बोली (और MySQL ) में उदाहरण दूंगा - किसी भी सर्वर के लिए थोड़ा सा काम करना चाहिए।

अब, आप स्पष्ट रूप से इस बात का ध्यान रखना चाहते हैं कि कौन सा छात्र कौन सा पाठ्यक्रम ले रहा है - इसलिए आपने क्या कहा है joining table(इसे भी कहा जाता है linking, many-to-manyया m-to-nटेबल)। उन्हें associative entitiesअधिक तकनीकी शब्दजाल के रूप में भी जाना जाता है!

1 पाठ्यक्रम में कई छात्र हो सकते हैं ।
1 छात्र कई पाठ्यक्रम ले सकता है ।

तो, आप एक ज्वाइनिंग टेबल बनाएं

CREATE TABLE course_student
(
  cs_course_id INTEGER NOT NULL,
  cs_student_id INTEGER NOT NULL,

  -- now for FK constraints - have to ensure that the student
  -- actually exists, ditto for the course.

  CREATE CONSTRAINT cs_course_fk FOREIGN KEY (cs_course_id) REFERENCES course (course_id),
  CREATE CONSTRAINT cs_student_fk FOREIGN KEY (cs_student_id) REFERENCES student (student_id)
);

अब, इस तालिका को समझदारी से देने का एकमात्र तरीका यह PRIMARY KEYहै कि KEYपाठ्यक्रम और छात्र का एक संयोजन बनाया जाए। इस तरह, आप प्राप्त नहीं कर सकते हैं:

  • छात्र और पाठ्यक्रम संयोजन की नकल

    • एक पाठ्यक्रम केवल एक ही छात्र एक बार नामांकित हो सकता है, और

    • एक छात्र केवल एक समय में एक ही पाठ्यक्रम में दाखिला ले सकता है

  • आपके पास KEYप्रति छात्र पाठ्यक्रम पर एक तैयार की गई खोज है - AKA एक कवरिंग इंडेक्स ,

  • यह उन छात्रों और छात्रों के बिना पाठ्यक्रम खोजने के लिए तुच्छ है जो कोई पाठ्यक्रम नहीं ले रहे हैं!

    - db-fiddle उदाहरण पीके बाधा क्रिएट टेबल में मुड़ा हुआ है - यह किसी भी तरह से किया जा सकता है। मैं क्रिएट टेबल स्टेटमेंट में सब कुछ रखना पसंद करता हूं।


ALTER TABLE course_student 
ADD CONSTRAINT course_student_pk 
PRIMARY KEY (cs_course_id, cs_student_id);

अब, आप कर सकते हैं, यदि आप पा रहे थे कि निश्चित रूप से छात्र की खोज धीमी थी, तो UNIQUE INDEXऑन (sc_student_id, sc_course_id) का उपयोग करें।

ALTER TABLE course_student 
ADD CONSTRAINT course_student_sc_uq  
UNIQUE (cs_student_id, cs_course_id);

नहीं है कोई अनुक्रमणिका जोड़ने के लिए चांदी की गोली - वे होगा बनाने INSERTऔर UPDATEधीमी है, लेकिन बेहद के महान लाभ में कमी आतीSELECT बार! यह डेवलपर पर निर्भर है कि वह अपने ज्ञान और अनुभव को देखते हुए अनुक्रमणिका तय करे, लेकिन यह कहना कि कंपोजिट PRIMARY KEYएस हमेशा खराब होता है, केवल सादा गलत है।

तालिकाओं में शामिल होने के मामले में, वे आमतौर पर एकमात्र हैं PRIMARY KEY जो समझ में आते हैं! जॉइनिंग टेबल भी अक्सर मॉडलिंग का एकमात्र तरीका है जो व्यवसाय या प्रकृति या वास्तव में हर क्षेत्र में होता है जिसके बारे में मैं सोच सकता हूं!

यह पीके भी उपयोग के रूप में है covering indexजो खोजों को गति देने में मदद कर सकता है। इस मामले में, यह विशेष रूप से उपयोगी होगा यदि कोई नियमित रूप से (कोर्स_ड, स्टूडेंट_ड) पर खोज कर रहा था, जो कि कल्पना करेगा, अक्सर ऐसा हो सकता है!

यह सिर्फ एक छोटा सा उदाहरण है जहां एक समग्र PRIMARY KEYएक बहुत अच्छा विचार हो सकता है, और वास्तविकता को मॉडल करने का एकमात्र तरीका है! मेरे सिर के ऊपर से, मैं कई और अधिक के बारे में सोच सकता हूं ।

मेरे अपने काम से एक उदाहरण!

फ्लाइट टेबल पर विचार करें, जिसमें फ़्लाइट_आईडी, प्रस्थान और आगमन हवाई अड्डों की सूची और प्रासंगिक समय हो और फिर क्रू सदस्यों के साथ एक केबिन_ क्रू टेबल भी हो!

एकमात्र ऐसा तरीका जिसे मॉडलिंग किया जा सकता है, उसके पास उड़ान_ के साथ एक उड़ान_ क्रू टेबल है और चालक दल के रूप में एटिब्यूट्स और एकमात्र फलक PRIMARY KEYदो क्षेत्रों की समग्र कुंजी का उपयोग करना है!


2
पाठ्यक्रम और छात्रों के उदाहरण में, course_student के लिए idप्राथमिक कुंजी और एक अद्वितीय अनुक्रमणिका cs_student_id cs_course_idके समान परिणाम होना संभव है?
हैकवान

2
संसाधनों को बर्बाद क्यों कर रहे हो? पीके (कोर्स_ड, स्टूडेंट_आईडी) के साथ, परिभाषा के अनुसार आपके पास पहले से ही उन क्षेत्रों पर एक अद्वितीय सूचकांक है! एक विशिष्ट अनुक्रमणिका (student_id, course_id) खोज को गति देने में उपयोग की जा सकती है - यह कहें कि यदि आप ऐसे छात्रों की तलाश कर रहे थे जो कोई पाठ्यक्रम नहीं ले रहे थे, लेकिन यह निर्णय एक परिचालन हो सकता है, लेकिन अपेक्षाकृत सस्ते भंडारण के इन दिनों में, मैं इसे फिर से तैयार करूंगा, खासकर जब से एक को लगता है कि तालिका को बहुत बार अद्यतन नहीं किया जाएगा।
वेर्रेस

1
लिंक टेबलों के लिए पूरी तरह से सहमत - मैं अभी कई के साथ काम कर रहा हूं। हालाँकि, जब मैं अपनी C # टोपी लगाता हूं, तो मैं अगली लेयर अप के लिए रिवर्सेपोको जनरेटर के साथ काम कर रहा हूं और उपयोगी कक्षाएं (ढूंढना, सहेजना आदि) तैयार कर रहा हूं। मैंने एक बड़ी समस्या का सामना किया - किसी भी सामान्य सेव / कोड को खोजने के लिए कंपोजिट कुंजी एक PITA बन जाती है। हां, शायद मैं ईडीएमएक्स फाइलों पर वापस जा सकता हूं, लेकिन मुझे अभी भी विशेष केस कोड (पेक कॉलम गिनना) के आसपास काम करने की आवश्यकता है या कृत्रिम सरोगेट कुंजी जोड़ें (पसंद नहीं है और अतिरिक्त विशिष्टता की कमी की जरूरत है :() तो, मुझे लगता है। लोगों को कंपोजिट पसंद नहीं है जो ऐप लेयर कोड से बोल रहे हैं।
रिचर्ड ग्रिफिथ्स

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

जब कोई छात्र पाठ्यक्रम दोहराता है तो क्या होता है? फिर जब तक समय में अलग-अलग पाठ्यक्रमों को अलग-अलग आईडी नहीं मिलते हैं - तब तक आपके पास एक और मानचित्रण तालिका है। या पाठ्यक्रम की तारीख के लिए एक फ़ील्ड जोड़ें जो अब कुंजी में जोड़ा जाना चाहिए।
इहानी

3

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

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

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

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

https://www.techopedia.com/definition/5547/primary-key यह चुनने का एक उदाहरण बताता है कि क्या किसी ग्राहक की सामाजिक सुरक्षा संख्या के साथ डेटा को सभी डेटा तालिकाओं में ग्राहक कुंजी के रूप में संग्रहीत करना है, या जब आप एक मनमाना customer_id उत्पन्न करना चाहते हैं उन्हें पंजीकृत करें। वास्तव में, यह SSN का घोर दुरुपयोग है, इससे अलग कि यह काम करता है या नहीं; यह एक व्यक्तिगत और गोपनीय डेटा मूल्य है।

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

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


1
मैं विशेष रूप से अवलोकन की सराहना करता हूं कि ग्राहक डेटा के आधार पर एक महत्वपूर्ण, यहां तक ​​कि ज्ञात ग्राहक डेटा (यहां, एसएसएन) के आधार पर, यदि उस डेटा को कभी भी ठीक करने की आवश्यकता होती है, तो वह टूट जाता है।
टूलमेकर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.