संबंधपरक डेटाबेस में संबंध बनाने के लिए विदेशी कुंजी एक अभिन्न अंग हैं। यहां बताया गया है कि उन्हें क्यों और कैसे बनाया जाता है।
इसलिए हमने स्थापित किया है कि प्राथमिक कुंजी तालिका के लिए एक विशिष्ट पहचानकर्ता प्रदान करती है। लेकिन प्राथमिक कुंजी केवल "कुंजी" प्रकार नहीं हैं। हमारे डेटाबेस में विदेशी कुंजियाँ भी हो सकती हैं।
विदेशी कुंजी क्या है?
एक विदेशी कुंजी एक तालिका में एक स्तंभ (या स्तंभों का संग्रह) है जो विशिष्ट रूप से किसी अन्य तालिका की एक पंक्ति की पहचान करता है। यह दो तालिकाओं के बीच संबंध को परिभाषित करता है।
एक विदेशी कुंजी आपको तालिकाओं में संबंधित डेटा को क्रॉस-रेफरेंस करने की अनुमति देती है। यह तब काम आता है जब किसी कॉलम में डेटा होता है जिसे किसी अन्य तालिका में दर्शाया जाता है।
उदाहरण
यहां हमारे फलों की दुकान का आरेख है डेटाबेस फलों . के बीच संबंध दिखा रहा है तालिका और इकाइयाँ टेबल।
दो तालिकाओं को जोड़ने वाली काली रेखा एक विदेशी कुंजी को इंगित करती है। UnitId फल . पर फ़ील्ड तालिका UnitId . के लिए एक विदेशी कुंजी है इकाइयों . पर फ़ील्ड टेबल। इसलिए, जो मान हम Fruit.UnitId . में डालते हैं Units.UnitId . में मान के अनुरूप होना चाहिए . यह Fruit.UnitId . को सक्षम करता है उस रिकॉर्ड के लिए अन्य कॉलम में डेटा को संदर्भित करने के लिए (यानी वह रिकॉर्ड जिसमें संबंधित UnitId है )।
डेटा
तो अगर हमारे फल तालिका में इस तरह का एक रिकॉर्ड होता है:
FruitId | फलों का नाम | इन्वेंट्री | UnitId | तारीख दर्ज | तारीख अपडेट किया गया |
---|---|---|---|---|---|
1 | Apple | 10 | 3 | 2012-11-27 12:42:10 | 2012-11-27 12:42:10 |
और हमारी इकाइयाँ तालिका में निम्नलिखित रिकॉर्ड हैं:
UnitId | <थ>इकाई का नामतारीख दर्ज | तारीख अपडेट किया गया | |
---|---|---|---|
1 | टुकड़ा | 2011-12-30 12:46:15 | 2011-12-30 12:46:15 |
2 | बंच | 2011-12-30 12:46:15 | 2011-12-30 12:46:15 |
3 | किलोग्राम | 2011-12-30 12:46:15 | 2011-12-30 12:46:15 |
4 | कंटेनर | 2011-12-30 12:46:15 | 2011-12-30 12:46:15 |
5 | पाउंड | 2011-12-30 12:46:15 | 2011-12-30 12:46:15 |
6 | औंस | 2011-12-30 12:46:15 | 2011-12-30 12:46:15 |
आप देख सकते हैं कि
Fruit.UnitId
फ़ील्ड में एक 3
होता है . अब
इकाइयों
को देखें रिकॉर्ड के लिए तालिका जिसमें 3
. है
UnitId
. में खेत। आप देख सकते हैं कि यह रिकॉर्ड
किलोग्राम
. का प्रतिनिधित्व करता है . इसलिए, अब हम जानते हैं कि सेब को किलोग्राम में मापा जाता है।
इस तरह से डेटाबेस स्थापित करने के बारे में अच्छी बात यह है कि, हमें उस इकाई का उपयोग करने वाले प्रत्येक रिकॉर्ड के लिए "किलोग्राम" दोहराने की आवश्यकता नहीं है। दोहराव को कम करना संबंधपरक डेटाबेस प्रबंधन प्रणालियों का एक प्रमुख लाभ है।
फलों . में जितने रिकॉर्ड देखे तालिका समान इकाई नाम साझा करेगी (उदाहरण के लिए, "किलोग्राम", "कंटेनर", "बंच", आदि), हमें अपने डेटाबेस में डुप्लिकेट जोड़ने से पहले ध्यान से सोचना चाहिए। एक विदेशी कुंजी संबंध का उपयोग किए बिना, हम केवल इकाई नाम सीधे फलों में लिख सकते हैं तालिका (और शायद कॉलम "यूनिट", "यूनिट टाइप" या "यूनिटनाम" को कॉल करें)। तब हम इकाई नाम कॉलम के लिए समान मान साझा करने वाले कई रिकॉर्ड के साथ समाप्त होंगे। हम देखेंगे कि "किलोग्राम" कई रिकॉर्ड के खिलाफ बार-बार दोहराया जाता है। हम बार-बार "बंच" और किसी अन्य लोकप्रिय इकाई प्रकार को भी देखेंगे।
हालांकि ऐसा करना "गलत" नहीं है, आम तौर पर उन प्रत्येक इकाई नामों के लिए एक रिकॉर्ड को एक अलग तालिका में संग्रहीत करना अधिक कुशल होता है, फिर उस तालिका को UnitId के माध्यम से संदर्भित करें। कॉलम। ऐसा करना फलों में बनाए गए प्रत्येक रिकॉर्ड के लिए उन इकाई नामों को बार-बार दोहराने से अधिक कुशल है टेबल। यदि हम कभी भी किसी इकाई का नाम अपडेट करने का निर्णय लेते हैं तो यह और भी आसान हो जाता है (उदाहरण के लिए "किलोग्राम" को "किलो" में बदलें)। यदि हम किसी इकाई का नाम अपडेट करते हैं, तो यह फल . को प्रभावित नहीं करेगा तालिका क्योंकि UnitId वही रहेगा। साथ ही यह हमारे डेटाबेस में असंगत डेटा को आने से रोकने में भी मदद करता है।
विदेशी कुंजी प्रतिबंध
एक विदेशी कुंजी बाधा एक डेटाबेस ऑब्जेक्ट है जो आपके विदेशी कुंजी डेटा को सुसंगत रखने में सहायता करती है। आप संदर्भात्मक अखंडता बनाए रखने के लिए एक विदेशी कुंजी बाधा बनाते हैं। एक विदेशी कुंजी बाधा बनाकर, आप MySQL को डेटा पर कुछ नियम लागू करने के लिए कह रहे हैं। जब डेटा डाला जाता है, हटाया जाता है या अपडेट किया जाता है, तो MySQL जांच करेगा कि यह आपके द्वारा टेबल के बीच बनाई गई विदेशी कुंजी का पालन करता है। यदि नहीं, तो यह डेटा को लिखे/ओवरराइट/हटाए जाने से रोकेगा, इस प्रकार संदर्भात्मक अखंडता को बनाए रखेगा।
उदाहरण के लिए, यदि कोई उपयोगकर्ता Fruit.UnitId में UnitId मान दर्ज करने का प्रयास करता है कॉलम लेकिन Units.UnitId . में कोई संगत रिकॉर्ड नहीं है कॉलम, तो MySQL उपयोगकर्ता को उस मान में प्रवेश करने से रोकेगा।
जब हमने अपनी दो तालिकाएँ बनाईं, तो हमने फलों . में एक विदेशी कुंजी बाधा जोड़ी टेबल। यहाँ वह कोड है जिसका उपयोग हम बाधा उत्पन्न करने के लिए करते हैं:
CONSTRAINT fkFruitUnits FOREIGN KEY (UnitId) REFERENCES Units (UnitId) ON DELETE RESTRICT ON UPDATE CASCADE
जब आप बाईं ओर के नोड्स को विस्तृत करते हैं SCHEMAS टैब, आप हमारे द्वारा बनाई गई विदेशी कुंजी (साथ ही प्राथमिक कुंजी) देख सकते हैं:
यदि आप ऐसा डेटा डालने का प्रयास करते हैं जो विदेशी कुंजी बाधा के अनुरूप नहीं है, तो आपको एक त्रुटि मिलनी चाहिए।
उदाहरण के लिए, अगर मैं फलों . में एक रिकॉर्ड डालने का प्रयास करता हूं UnitId . का उपयोग करके तालिका मान जो इकाइयों . में मौजूद नहीं है तालिका, मुझे निम्न त्रुटि प्राप्त होती है:
ऐसा इसलिए होता है क्योंकि मैं 5
. का मान डालने का प्रयास कर रहा हूं
UnitId
. में कॉलम जब
Units.UnitId
. में कोई संगत मान नहीं है फ़ील्ड.
इसके सफल होने के लिए, मुझे यह सुनिश्चित करना होगा कि
इकाइयों
. में एक रिकॉर्ड है
UnitId
. के साथ तालिका का 5
।
विदेशी कुंजी काम नहीं कर रही है?
आपको कभी-कभी ऐसी स्थिति का सामना करना पड़ सकता है जहां एक विदेशी कुंजी काम नहीं करती है। उदाहरण के लिए, आप तालिका में सफलतापूर्वक डेटा सम्मिलित कर सकते हैं, भले ही कोई विदेशी कुंजी हो जो उस डेटा को सम्मिलित होने से रोके।
इस स्थिति में आप कुछ चीजों की जांच कर सकते हैं।
- सुनिश्चित करें कि आपने
ON DELETE
जोड़ दिया है औरON UPDATE
आपके कोड में खंड। उदाहरण के लिए,ON DELETE RESTRICT ON UPDATE CASCADE
. इस कोड को कब रखना है, इसके लिए हमारा CREATE TABLE उदाहरण देखें। - सुनिश्चित करें कि तालिका InnoDB है . आप
ENGINE=InnoDB
. जोड़कर ऐसा कर सकते हैं अपनेCREATE TABLE
. के अंत तक कथन (जब हमने अपनी तालिकाएँ बनाईं तब से मेरा उदाहरण देखें)। कुछ इंजन (जैसे MyISAM .) ) विदेशी कुंजी बाधाओं का समर्थन नहीं करते हैं, लेकिन जब आप अपनी विदेशी कुंजी बाधा बनाने का प्रयास करते हैं तो वे इस बारे में कोई चेतावनी नहीं देते हैं। यदि आपका डिफ़ॉल्ट इंजन InnoDB . नहीं है तो यह संभावना है कि आपकी विदेशी कुंजी समर्थित नहीं होगी। - सुनिश्चित करें कि MySQL वास्तव में विदेशी कुंजियों की जाँच कर रहा है। आप निम्न कोड चलाकर ऐसा कर सकते हैं:
SET FOREIGN_KEY_CHECKS=1
.
विदेशी कुंजी जांच अक्षम करें
ऐसे समय हो सकते हैं जब विदेशी कुंजी बाधाएं अनावश्यक रूप से प्रतिबंधित हो सकती हैं - उस बिंदु तक जहां वे डेटा लोड करने में आपके प्रयासों को गंभीर रूप से बाधित करते हैं। उदाहरण के लिए, जब आपने अभी-अभी एक डेटाबेस बनाया है और आपको प्रारंभिक डेटा लोड करने की आवश्यकता है। या यदि आपको तालिकाओं का एक गुच्छा छोड़ने और डेटा पुनः लोड करने की आवश्यकता है।
यदि आप डेटा को सही क्रम में लोड नहीं करते हैं, तो संभवतः आपको गलत क्रम में डेटा लोड होने के कारण विदेशी कुंजी त्रुटियां मिलती रहेंगी (यानी आप पैरेंट टेबल के होने से पहले चाइल्ड टेबल को लोड करने का प्रयास कर रहे हैं) डेटा लोड किया गया)।
यह केवल लोडिंग . के लिए एक समस्या नहीं है आंकड़ा। पहली बार में डेटाबेस बनाते समय भी आप इस समस्या का सामना कर सकते हैं। यदि आप सही क्रम में टेबल नहीं बनाते हैं तो आप किसी भी विदेशी कुंजी बाधाओं के कारण त्रुटियों का सामना कर सकते हैं।
यदि आप सही अभिभावक-बाल आदेश नहीं जानते हैं तो डेटाबेस बनाने या डेटा लोड करने के लिए सही क्रम स्थापित करने में संभवतः बहुत समय और प्रयास लग सकता है। ऐसे मामलों में, बेहतर होगा कि आप MySQL को अस्थायी रूप से अभी के लिए विदेशी कुंजियों की जांच न करने के लिए कहें।
आप निम्न कोड से विदेशी कुंजी जाँच को अक्षम कर सकते हैं:
FOREIGN_KEY_CHECKS=0
इसे फिर से सक्षम करने के लिए, यह करें:
FOREIGN_KEY_CHECKS=1