विदेशी कुंजी कॉलम को प्राथमिक कुंजी के सबसे बाएं उपसर्ग या मूल तालिका में एक अद्वितीय कुंजी वाले कॉलम का संदर्भ देना चाहिए।
दूसरे शब्दों में, निम्नलिखित उदाहरण InnoDB में काम करते हैं:
CREATE TABLE Foo ( a INT, b INT, c INT, PRIMARY KEY (a,b,c) );
CREATE TABLE Bar ( x INT, y INT );
ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(b,c); -- WRONG
ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(a,c); -- WRONG
ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(a,b); -- RIGHT
ALTER TABLE Bar ADD FOREIGN KEY (x) REFERENCES Foo(b); -- WRONG
ALTER TABLE Bar ADD FOREIGN KEY (x) REFERENCES Foo(a); -- RIGHT
आपको एक त्रुटि मिली क्योंकि आप (x) संदर्भ Foo(b) के समकक्ष करने का प्रयास कर रहे हैं।
आपका कॉलम कोडमेनूइटम पैरेंट की प्राथमिक कुंजी में तीन स्तंभों में से दूसरा है।
यह काम करेगा अगर smenuitememp.codemenuitem
संदर्भ के लिए थे smenuitem.codmodulo
, क्योंकि वह स्तंभ पैरेंट तालिका की प्राथमिक कुंजी में सबसे बाईं ओर का स्तंभ है।
अपना अनुवर्ती प्रश्न पुनः करें:
विदेशी चाबियों के काम करने के तरीके को ध्यान में रखें। हर बार जब आप चाइल्ड टेबल में एक पंक्ति डालते हैं या अपडेट करते हैं, तो उसे यह सत्यापित करने के लिए मूल तालिका में एक पंक्ति देखने की आवश्यकता होती है कि मान संदर्भित कॉलम में मौजूद है। यदि कॉलम को अनुक्रमित नहीं किया गया है, तो इस लुकअप को प्राप्त करने के लिए उसे एक टेबल-स्कैन करना होगा, और यह बहुत महंगा होगा, यह मानते हुए कि आपकी मूल तालिका बढ़ती है।
यदि आप एक बहु-स्तंभ अनुक्रमणिका के मध्य स्तंभ के आधार पर एक पंक्ति को देखने का प्रयास करते हैं, तो अनुक्रमणिका आपकी सहायता नहीं करती है। सादृश्य से, यह एक निश्चित मध्य नाम वाले सभी लोगों के लिए एक टेलीफोन बुक खोजने जैसा है।
मानक एएनएसआई एसक्यूएल की आवश्यकता है कि संदर्भित कॉलम प्राथमिक कुंजी या अद्वितीय कुंजी का हिस्सा हो, और इसके लिए आवश्यक है कि विदेशी कुंजी कॉलम सभी से मेल खाते हों पैरेंट में प्राथमिक या अद्वितीय बाधा के स्तंभ।
लेकिन InnoDB अधिक अनुमेय है। यह अभी भी आवश्यक है कि मूल तालिका में संदर्भित कॉलम को अनुक्रमित किया जाए ताकि लुकअप कुशल हो, और कि संदर्भित स्तंभ अनुक्रमणिका में सबसे बाईं ओर हों। लेकिन एक गैर-अद्वितीय अनुक्रमणिका ठीक है; इसे संदर्भित करने के लिए एक विदेशी कुंजी की अनुमति है।
इससे चाइल्ड रो जैसे अजीब मामले हो सकते हैं जो पैरेंट में एक से अधिक पंक्तियों को संदर्भित करता है, लेकिन यह उम्मीद की जाती है कि आप ऐसी विसंगतियों को संभाल लेंगे।
मैं अंतिम बिंदु पर जोर देने की जरूरत महसूस करता हूं। आप करेंगे यदि आप माता-पिता में गैर-विशिष्ट अनुक्रमित स्तंभों के लिए विदेशी कुंजियों को परिभाषित करते हैं, तो विषम डेटा प्राप्त करें। जब आप जॉइन करते हैं तो यह संभवतः आपके प्रश्नों को पंक्तियों की कई बार रिपोर्ट करने का कारण बनेगा। आपको InnoDB के इस व्यवहार का उपयोग नहीं करना चाहिए; आपको विदेशी कुंजियों को केवल उन मूल स्तंभों के लिए परिभाषित करना चाहिए जो अद्वितीय हैं।