विदेशी कुंजी कॉलम/बाधाओं की अस्पष्टता
मान लें कि आप विदेशी कुंजी बाधाओं की बात कर रहे हैं , संक्षिप्त उत्तर होगा आप उनका उपयोग नहीं करते हैं ।
और यहाँ सबसे लंबा आता है:
हम कॉलम विदेशी कुंजी होने . को संदर्भित करने के अभ्यस्त हैं अन्य तालिकाओं के लिए। विशेष रूप से सामान्यीकरण प्रक्रिया के दौरान, "user_purchase.i_id
जैसे वाक्यांश items
. के लिए एक विदेशी कुंजी है टेबल" बहुत आम होगा। हालांकि यह रिश्ते का वर्णन करने का एक पूरी तरह से मान्य तरीका है, लेकिन जब हम कार्यान्वयन के चरण में पहुंच जाते हैं तो यह थोड़ा अस्पष्ट हो सकता है।
मान लीजिए आपने अपनी टेबल बिना . बनाई है FOREIGN KEY
खंड:
CREATE TABLE user(
id INT(11) NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(20) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE items(
i_id INT(11) NOT NULL AUTO_INCREMENT,
name TINYTEXT NOT NULL,
price DECIMAL(8,2) NOT NULL,
PRIMARY KEY (i_id)
);
CREATE TABLE user_purchase(
i_id INT(11) NOT NULL,
name TINYTEXT NOT NULL,
id INT(11) NOT NULL,
);
ध्यान दें कि, संबंध-वार, विदेशी कुंजी कॉलम अभी भी लागू हैं . एक कॉलम है जो user
. का संदर्भ देता है तालिका (id
) और दूसरा जो items
. का संदर्भ देता है तालिका (i_id
) -- चलिए name
डालते हैं एक पल के लिए अलग कॉलम। निम्नलिखित डेटा पर विचार करें:
user user_purchase items
| id username | | id i_id | | i_id name price |
| 23 john | | 55 10 | | 10 chocolate bar 3.42 |
| 55 mary | | 70 10 | | 33 mobile phone 82.11 |
| 70 fred | | 70 33 | | 54 toothpaste 8.67 |
| 55 10 | | 26 toy car 6.00 |
| 70 26 |
रिश्ता वहीं है। इसे user_purchase
. के माध्यम से क्रियान्वित किया जाता है तालिका, जिसमें जानकारी होती है कि किसने क्या खरीदा . यदि हम किसी प्रासंगिक रिपोर्ट के लिए डेटाबेस से पूछताछ करते हैं, तो हम करेंगे:
select * from user_purchase p
join user u on (p.id=u.id)
join items i on (p.i_id=i.i_id)
और इसी तरह हम संबंध और विदेशी कुंजी कॉलम . का उपयोग करते हैं शामिल।
अब, अगर हम ऐसा करें:
insert into user_purchase (id,i_id) values (23,99)
जाहिर है, यह एक अमान्य प्रविष्टि है। हालांकि id=23
. वाला एक उपयोगकर्ता है , i_id=99
के साथ कोई आइटम नहीं है . RDBMS ऐसा होने देगा, क्योंकि यह इससे बेहतर नहीं जानता . अभी तक।
यहीं पर विदेशी कुंजी बाधाएं आओ, खेल में शामिल हो। FOREIGN KEY (i_id) REFERENCES items(i_id)
निर्दिष्ट करके user_purchase
. में तालिका परिभाषा, हम अनिवार्य रूप से आरडीबीएमएस को पालन करने के लिए एक नियम देते हैं:i_id
के साथ प्रविष्टियां वे मान जो items.i_id
. में शामिल नहीं हैं कॉलम स्वीकार्य नहीं हैं . दूसरे शब्दों में, जबकि एक विदेशी कुंजी कॉलम संदर्भ को लागू करता है , एक विदेशी कुंजी बाधा संदर्भात्मक अखंडता को लागू करता है ।
हालांकि, ध्यान दें कि उपरोक्त select
नहीं बदलेगा, सिर्फ इसलिए कि आपने एक FK बाधा को परिभाषित किया है। इस प्रकार, आप FK बाधाओं का उपयोग न करें, RDBMS आपके डेटा की सुरक्षा के लिए करता है।
अतिरेक
अपने आप से पूछें:आप ऐसा क्यों चाहेंगे? यदि दो विदेशी कुंजी एक ही उद्देश्य की पूर्ति के लिए हैं, तो अतिरेक अंततः आपको परेशानी में डाल देगा। निम्नलिखित डेटा पर विचार करें:
user_purchase items
| id i_id name | | i_id name price |
| 55 10 chocolate bar | | 10 chocolate bar 3.42 |
| 70 10 chocolate bar | | 33 mobile phone 82.11 |
| 70 33 mobile phone | | 54 toothpaste 8.67 |
| 55 10 toothpaste | | 26 toy car 6.00 |
| 70 26 toy car |
इस तस्वीर में क्या ग़लती है? क्या उपयोगकर्ता 55
दो चॉकलेट बार, या एक चॉकलेट बार और एक टूथपेस्ट खरीदें? इस प्रकार की अस्पष्टता डेटा को इन-सिंक रखने के लिए बहुत प्रयास कर सकती है, जो अनावश्यक होगा यदि हम केवल एक विदेशी कुंजी रखते हैं। वास्तव में, क्यों न name
को छोड़ दिया जाए कॉलम पूरी तरह से, क्योंकि यह संबंध द्वारा निहित है।
बेशक, हम PRIMARY KEY(i_id,name)
सेट करके, एक समग्र विदेशी कुंजी को लागू करके इसे हल कर सकते हैं items
. के लिए तालिका (या एक अतिरिक्त UNIQUE(i_id,name)
defining को परिभाषित करना इंडेक्स, यह वास्तव में कोई फर्क नहीं पड़ता) और फिर एक FOREIGN KEY(i_id,name) REFERENCES items(i_id,name)
सेट करना . इस तरह, केवल (i_id,name) जोड़े जो items
. में मौजूद हैं तालिका user_purchases
के लिए मान्य होगी . इस तथ्य के अलावा कि आपके पास अभी भी एक . होगा विदेशी कुंजी , यह दृष्टिकोण पूरी तरह से अनावश्यक है, बशर्ते कि i_id
कॉलम पहले से ही किसी आइटम की पहचान करने के लिए पर्याप्त है (name
. के लिए ऐसा नहीं कह सकता कॉलम...)।
हालांकि, किसी तालिका में एकाधिक विदेशी कुंजियों का उपयोग करने के विरुद्ध कोई नियम नहीं है। वास्तव में, ऐसी परिस्थितियां हैं जो इस तरह के दृष्टिकोण की मांग करती हैं। एक person(id,name)
पर विचार करें तालिका और एक parent(person,father,mother)
एक, निम्न डेटा के साथ:
person parent
| id name | | person father mother |
| 14 John | | 21 14 59 |
| 43 Jane | | 14 76 43 |
| 21 Mike |
| 76 Frank |
| 59 Mary |
जाहिर है, parent
. के सभी तीन कॉलम तालिका person
. के लिए विदेशी कुंजी है . एक ही संबंध के लिए नहीं , हालांकि, लेकिन तीन अलग-अलग वाले . के लिए :चूंकि किसी व्यक्ति के माता-पिता भी व्यक्ति होते हैं, इसलिए दो संगत स्तंभों को एक ही तालिका person
का संदर्भ देना चाहिए करता है। हालांकि, ध्यान दें कि तीन फ़ील्ड न केवल कर सकते हैं लेकिन यह भी करना होगा अलग person
का संदर्भ लें एक ही parent
में s पंक्ति, क्योंकि कोई भी उसका अपना माता-पिता नहीं है और किसी का पिता उसकी माँ भी नहीं है।