क्या एक विदेशी कुंजी NULL और / या डुप्लिकेट हो सकती है?


325

कृपया मेरे लिए दो बातें स्पष्ट करें:

  1. क्या विदेशी कुंजी NULL हो सकती है?
  2. क्या एक फॉरेन कुंजी डुप्लिकेट हो सकती है?

जैसा कि मुझे पता है, NULLविदेशी कुंजियों में उपयोग नहीं किया जाना चाहिए, लेकिन मेरा कुछ आवेदन NULLओरेकल और एसक्यूएल सर्वर दोनों में इनपुट करने में सक्षम है , और मुझे नहीं पता कि क्यों।


1
@ एड्रियन: मेरी अधिकांश जानकारी विदेशी कुंजी शून्य नहीं हो सकती है, लेकिन यह sql सर्वर और ऑरेकल में शून्य ले रही है। क्या आप व्यख्या कर सकते हैं?
जाम

@ जेम्स - मेरे उत्तर में लिंक पढ़ें।
JNK

11
इसे हटाया नहीं जा सकता क्योंकि उत्तर और प्रश्न उपयोगी हैं। इसे बेहतर बनाने के लिए प्रश्न को संपादित करने के लिए स्वतंत्र महसूस करें।
जेफ एटवुड

कृपया डुप्लिकेट के बारे में प्रश्न को विभाजित करें। NULLs के बारे में केवल एक ही नीचे दिया जा रहा है।
रिस्टोरियरपोस्ट

जवाबों:


527

संक्षिप्त उत्तर: हां, यह NULL या डुप्लिकेट हो सकता है।

मैं यह समझाना चाहता हूं कि विदेशी कुंजी को अशक्त होने की आवश्यकता क्यों हो सकती है या उसे विशिष्ट या अद्वितीय नहीं होने की आवश्यकता हो सकती है। सबसे पहले एक विदेशी कुंजी को याद रखें कि उस क्षेत्र में मूल्य पहले एक अलग तालिका (मूल तालिका) में मौजूद होना चाहिए। यह सब एफके परिभाषा के अनुसार है। परिभाषा द्वारा अशक्त मूल्य नहीं है। नल का मतलब है कि हम अभी तक नहीं जानते हैं कि मूल्य क्या है।

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

यह अद्वितीय है या नहीं, इसका संबंध इस बात से है कि तालिका का एक-एक या माता-पिता के संबंध का एक-एक संबंध है या नहीं। अब यदि आपके पास एक-एक संबंध है, तो यह संभव है कि आपके पास सभी डेटा एक तालिका में हो सकते हैं, लेकिन यदि तालिका बहुत चौड़ी हो रही है या यदि डेटा किसी भिन्न विषय पर है (कर्मचारी - बीमा उदाहरण @tbone ने दिया है उदाहरण के लिए), तो आप एक FK के साथ अलग टेबल चाहते हैं। फिर आप इस FK को या तो PK (जो विशिष्टता की गारंटी देते हैं) बनाना चाहते हैं या उस पर एक अद्वितीय बाधा डालेंगे।

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


13
तो इसका उद्देश्य "अनसाइनड" नामक नकली बिक्री वाले व्यक्ति से बेहतर होना है?
थॉमस वेलर

8
एक टिप्पणी। Nulls क्वेरी में त्रुटियों के लिए बहुत सारे कमरे छोड़ देते हैं, जो नहीं जानते कि SQL (mis) 3VL को कैसे संभालता है। अगर एक विक्रेता एक निश्चित आर-टेबल के लिए वास्तव में आवश्यक नहीं है, तो आप उस रिकॉर्ड को शामिल नहीं करते हैं। एक अलग तालिका उपयुक्त प्रस्ताव के साथ "प्रस्ताव प्रस्तावित" या कुछ इस तरह की हो सकती है। एक क्वेरी लेखक तब उस तालिका में शामिल हो सकता है, और जब भी कोई प्रस्ताव विक्रेता के पास नहीं होता है, तो हम जो भी करना चाहते हैं, उसके लिए अपने तर्क की आपूर्ति करते हैं। NULL का अर्थ केवल यह नहीं है कि "हम नहीं जानते" - इसका उपयोग बहुत सी चीजों के लिए किया जा सकता है (यही वजह है कि यह लगभग हमेशा एक बुरा विचार है)
N West

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

28
@ThomasWeller एक नकली विक्रेता ("अनइज़्ड") का संदर्भ देते हुए समस्या को और बदतर बना देता है। मुझे लगता है कि आपकी विक्रेता तालिका में कई कॉलम हैं ...? क्या श्री Unassigned सामाजिक बीमा नंबर? वह किस विभाग को सौंपा गया है? उसका मालिक कौन है? मुझे आशा है कि आपको मेरी बात मिल जाएगी: जब आप एक "अनसाइनड" विक्रेता बनाते हैं, तो आपको जल्दी से पता चलता है कि आपने NULLएक तालिका NULLमें एक अलग तालिका में कई एस के लिए कारोबार किया है ।
गिली

1
@ThomasWeller आपको अपने इंटरफ़ेस को स्थानीय बनाने की आवश्यकता होने पर भी समस्या होगी।
टोबिव डे


45

घोड़े के मुंह से:

विदेशी कुंजियाँ उन प्रमुख मानों को अनुमति देती हैं जो सभी NULL हैं, भले ही कोई मिलान PRIMARY या UNIQUE कुंजियाँ न हों

फॉरेन की पर कोई अड़चन नहीं

जब कोई अन्य बाधाओं को विदेशी कुंजी पर परिभाषित नहीं किया जाता है, तो चाइल्ड टेबल में किसी भी संख्या में पंक्तियां समान मूल कुंजी मान को संदर्भित कर सकती हैं। यह मॉडल विदेशी कुंजी में नल की अनुमति देता है। ...

विदेशी कुंजी पर पूर्ण बाधा नहीं

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

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

विदेशी कुंजी पर अद्वितीय बाधा

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

यह मॉडल माता-पिता और विदेशी कुंजी के बीच एक-से-एक संबंध स्थापित करता है जो विदेशी कुंजी में अनिर्धारित मूल्यों (नल) की अनुमति देता है। उदाहरण के लिए, मान लें कि कर्मचारी तालिका में कंपनी बीमा योजना में कर्मचारी सदस्यता संख्या का जिक्र करते हुए कोमारो नाम का एक कॉलम था। इसके अलावा, INSURANCE नामक तालिका में प्राथमिक नाम KomNO है, और तालिका के अन्य स्तंभों में कर्मचारी बीमा पॉलिसी से संबंधित संबंधित जानकारी रहती है। कर्मचारी तालिका में सदस्य कोई विदेशी कुंजी और विशिष्ट कुंजी दोनों होनी चाहिए:

  • EMP_TAB और बीमा तालिकाओं के बीच संदर्भात्मक अखंडता नियमों को लागू करने के लिए (FOREIGN KEY बाधा)

  • यह गारंटी देने के लिए कि प्रत्येक कर्मचारी के पास एक विशिष्ट सदस्यता संख्या (UNIQUE प्रमुख बाधा) है

विदेशी कुंजी पर अद्वितीय और पूर्ण बाधा नहीं

जब UNIQUE और NOT NULL बाधा दोनों को विदेशी कुंजी पर परिभाषित किया जाता है, तो चाइल्ड टेबल में केवल एक पंक्ति किसी दिए गए मूल कुंजी का संदर्भ दे सकती है, और क्योंकि NULL मान को विदेशी कुंजी में अनुमति नहीं है, चाइल्ड टेबल में प्रत्येक पंक्ति को स्पष्ट संदर्भ देना चाहिए मूल कुंजी में एक मान।

यह देखो:

Oracle 11g लिंक


16

हाँ विदेशी कुंजी को वरिष्ठ प्रोग्रामर द्वारा बताई गई अशक्त किया जा सकता है ... मैं एक और परिदृश्य जोड़ूंगा जहां विदेशी कुंजी को शून्य होना आवश्यक है .... मान लीजिए कि हमारे पास एक आवेदन में तालिका टिप्पणियां, चित्र और वीडियो हैं जो चित्रों पर टिप्पणियों की अनुमति देता है। वीडियो। टिप्पणियों की तालिका में हमारे पास दो मुख्य कुंजी PicturesId, और VideosId के साथ प्राथमिक कुंजी CommentId हो सकता है। इसलिए जब आप किसी वीडियो पर टिप्पणी करते हैं तो केवल VideoId की आवश्यकता होगी और PictureId अशक्त होगा ... और यदि आप किसी चित्र पर टिप्पणी करते हैं, तो केवल PictureId की आवश्यकता होगी और VideosId रिक्त हो जाएगा ...


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

4
@ अभिकर्मक: हमारे पास उत्पादन उपयोग में यह "समाधान" है। यह मत करो, यह भयानक है। प्रश्न बनाना यह गड़बड़ करता है, "यदि यह टाइप 1 है, तो इस तालिका में शामिल हों, अन्यथा इस में शामिल हों"। यह हमारे लिए एक बुरा सपना था। हमने यह करना समाप्त कर दिया कि यह उत्तर क्या कहता है और प्रत्येक प्रकार के जुड़ने के लिए एक नया स्तंभ बनाया है। कॉलम बनाना सस्ता है। बहुत ज्यादा यह केवल दोष है कि बहुत सारे कॉलम टॉड का उपयोग करना कठिन बनाते हैं, लेकिन यह सिर्फ टॉड का दोष है।
user128216

1
@ फाइटरजेट रेल एक महान ओआरएम फ्रेमवर्क प्रदान करता है जो इस समाधान के साथ जटिल प्रश्नों को भी संभालता है।
Agent47DarkSoul

2
@ अभिक: हो सकता है ... लेकिन अगर आप इसे सरल बना सकते हैं, तो इसे जटिल क्यों बनायें? और शायद "बुरा सपना" का उपयोग करने के लिए गलत शब्द था: यह सिर्फ बहुत असुविधाजनक था। हम डेटा अखंडता समस्याओं (बहुत) से पीड़ित नहीं थे।
user128216

7

यह इस बात पर निर्भर करता है कि यह foreign keyआपके संबंध में क्या भूमिका निभाता है।

  1. यदि यह आपके संबंध में foreign keyभी है key attribute, तो यह पूर्ण नहीं हो सकता है
  2. यदि यह foreign keyआपके संबंध में एक सामान्य विशेषता है, तो यह NULL हो सकता है।

3

यहां Oracle सिंटैक्स का उपयोग करके एक उदाहरण दिया गया है:
पहले एक टेबल COUNTRY बनाएं

CREATE TABLE TBL_COUNTRY ( COUNTRY_ID VARCHAR2 (50) NOT NULL ) ;
ALTER TABLE TBL_COUNTRY ADD CONSTRAINT COUNTRY_PK PRIMARY KEY ( COUNTRY_ID ) ;

तालिका बनाएँ

CREATE TABLE TBL_PROVINCE(
PROVINCE_ID VARCHAR2 (50) NOT NULL ,
COUNTRY_ID  VARCHAR2 (50)
);
ALTER TABLE TBL_PROVINCE ADD CONSTRAINT PROVINCE_PK PRIMARY KEY ( PROVINCE_ID ) ;
ALTER TABLE TBL_PROVINCE ADD CONSTRAINT PROVINCE_COUNTRY_FK FOREIGN KEY ( COUNTRY_ID ) REFERENCES TBL_COUNTRY ( COUNTRY_ID ) ;

यह ओरेकल में पूरी तरह से ठीक चलता है। दूसरी तालिका में COUNTRY_ID विदेशी कुंजी पर ध्यान दें "NULL NULL" नहीं है।

अब PROVINCE तालिका में एक पंक्ति सम्मिलित करने के लिए, यह केवल PROVINCE_ID निर्दिष्ट करने के लिए पर्याप्त है। हालाँकि, यदि आपने COUNTRY_ID को भी निर्दिष्ट करना चुना है, तो यह COUNTRY तालिका में पहले से मौजूद होना चाहिए।


1

डिफ़ॉल्ट रूप से विदेशी कुंजी पर कोई बाधा नहीं होती है, विदेशी कुंजी शून्य और नकली हो सकती है।

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


0

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

अब, गैर-पहचान वाले संबंध का उदाहरण जहां कार्डिनैलिटी "शून्य" (गैर-पहचान) हो सकती है, जब हम कहते हैं कि एक इकाई-ए "ए" या "नहीं" में रिकॉर्ड / ऑब्जेक्ट का रिकॉर्ड के संदर्भ में मान हो सकता है / दूसरे एंटिटी-बी में।

के रूप में, इकाई-ए के एक रिकॉर्ड के लिए अन्य एंटिटी-बी के रिकॉर्ड के लिए खुद को पहचानने की संभावना है, इसलिए एंटिटी-बी के रिकॉर्ड के पहचान-मूल्य के लिए एंटिटी-बी में एक कॉलम होना चाहिए। यह कॉलम "Null" हो सकता है यदि Entity-A में कोई रिकॉर्ड Entity-B में रिकॉर्ड / s (या, ऑब्जेक्ट / s) की पहचान नहीं करता है।

ऑब्जेक्ट ओरिएंटेड (वास्तविक दुनिया) प्रतिमान में, ऐसी परिस्थितियां होती हैं जब क्लास-बी का कोई ऑब्जेक्ट जरूरी नहीं होता है (दृढ़ता से युग्मित) अपने अस्तित्व के लिए क्लास-ए की वस्तु पर निर्भर करता है, जिसका मतलब है कि क्लास-बी क्लास के लिए शिथिल-युग्मित है कक्षा-ए की वस्तु के विपरीत क्लास-ए में "कंटेनर" (कंटेंट) हो सकता है, क्योंकि क्लास-ए के ऑब्जेक्ट की अवधारणा के विपरीत क्लास-ए का ऑब्जेक्ट होना चाहिए, (क्लास की वस्तु) बी) निर्माण।

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


-1

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

लेकिन जवाब यह है कि यह सब व्यापार पर निर्भर करता है।


-3

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


यह "कुछ नहीं" का संदर्भ दे सकता है या आप अभी तक इसके मूल्य को नहीं जानते हैं NULL, लेकिन संदर्भात्मक अखंडता क्या कहती है कि अगर यह "कुछ" का संदर्भ देता है तो इसे होना चाहिए।
यक्ष

-7

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

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