मुझे ALTER TABLE ADD FOREIGN KEY
. के साथ भी यही समस्या थी ।
एक घंटे के बाद, मैंने पाया कि 150 त्रुटि न मिलने के लिए इन शर्तों को पूरा किया जाना चाहिए:
-
इससे पहले कि आप इसे संदर्भित करने के लिए किसी विदेशी कुंजी को परिभाषित करें, मूल तालिका मौजूद होनी चाहिए। आपको टेबल को सही क्रम में परिभाषित करना होगा:पहले पैरेंट टेबल, फिर चाइल्ड टेबल। यदि दोनों टेबल एक-दूसरे को संदर्भित करते हैं, तो आपको FK बाधाओं के बिना एक तालिका बनानी होगी, फिर दूसरी तालिका बनाएं, फिर FK बाधा को पहली तालिका में
ALTER TABLE
के साथ जोड़ें। . -
दोनों तालिकाओं को दोनों विदेशी कुंजी बाधाओं का समर्थन करना चाहिए, अर्थात
ENGINE=InnoDB
. अन्य स्टोरेज इंजन चुपचाप विदेशी कुंजी परिभाषाओं को अनदेखा करते हैं, इसलिए वे कोई त्रुटि या चेतावनी नहीं देते हैं, लेकिन FK बाधा सहेजी नहीं जाती है। -
पेरेंट टेबल में संदर्भित कॉलम एक कुंजी के सबसे बाएं कॉलम होने चाहिए। सबसे अच्छा अगर जनक में कुंजी
PRIMARY KEY
है याUNIQUE KEY
। -
FK परिभाषा को PK कॉलम (स्तंभों) को उसी क्रम में संदर्भित करना चाहिए जिस क्रम में PK परिभाषा है। उदाहरण के लिए, यदि FK
REFERENCES Parent(a,b,c)
तो माता-पिता के पीके को(a,c,b)
क्रम में कॉलम पर परिभाषित नहीं किया जाना चाहिए । -
पेरेंट तालिका में पीके कॉलम वही डेटा प्रकार होना चाहिए जो चाइल्ड टेबल में एफके कॉलम (ओं) के रूप में होना चाहिए। उदाहरण के लिए, अगर पेरेंट टेबल में PK कॉलम
UNSIGNED
. है ,UNSIGNED
. को परिभाषित करना सुनिश्चित करें चाइल्ड टेबल फ़ील्ड में संबंधित कॉलम के लिए।अपवाद:तारों की लंबाई भिन्न हो सकती है। उदाहरण के लिए,
VARCHAR(10)
संदर्भ कर सकते हैंVARCHAR(20)
या इसके विपरीत। -
किसी भी स्ट्रिंग-प्रकार के FK कॉलम में एक ही वर्ण सेट और संबंधित PK कॉलम के समान संयोजन होना चाहिए।
-
यदि चाइल्ड टेबल में पहले से ही डेटा है, तो एफके कॉलम में प्रत्येक मान पेरेंट टेबल पीके कॉलम में एक मान से मेल खाना चाहिए। इसे इस तरह की क्वेरी से जांचें:
SELECT COUNT(*) FROM Child LEFT OUTER JOIN Parent ON Child.FK = Parent.PK WHERE Parent.PK IS NULL;
इसे शून्य (0) बेजोड़ मान वापस करना होगा। जाहिर है, यह प्रश्न एक सामान्य उदाहरण है; आपको अपने टेबल नामों और कॉलम नामों को प्रतिस्थापित करना होगा।
-
न तो पैरेंट टेबल और न ही चाइल्ड टेबल
TEMPORARY
हो सकती है टेबल। -
न तो पैरेंट टेबल और न ही चाइल्ड टेबल एक
PARTITIONED
हो सकता है टेबल। -
अगर आप
ON DELETE SET NULL
. के साथ FK घोषित करते हैं विकल्प है, तो FK कॉलम अशक्त होना चाहिए। -
यदि आप एक विदेशी कुंजी के लिए एक बाधा नाम घोषित करते हैं, तो बाधा नाम पूरे स्कीमा में अद्वितीय होना चाहिए, न कि केवल उस तालिका में जिसमें बाधा परिभाषित की गई है। हो सकता है कि एक ही नाम के साथ दो तालिकाओं की अपनी बाधा न हो।
-
यदि अन्य तालिकाओं में कोई अन्य FK है जो उसी फ़ील्ड की ओर इशारा करता है जिसके लिए आप नया FK बनाने का प्रयास कर रहे हैं, और वे विकृत हैं (अर्थात अलग-अलग संयोजन), तो उन्हें पहले सुसंगत बनाने की आवश्यकता होगी। यह पिछले परिवर्तनों का परिणाम हो सकता है जहां
SET FOREIGN_KEY_CHECKS = 0;
गलती से परिभाषित असंगत संबंध के साथ उपयोग किया गया था। FK की इन समस्याओं की पहचान कैसे करें, इस पर निर्देशों के लिए नीचे दिए गए @andrewdotn का उत्तर देखें।
आशा है कि यह मदद करता है।