इस लेख में मैं प्रदर्शित करता हूं कि Transact-SQL का उपयोग करके SQL सर्वर में एक विदेशी कुंजी कैसे बनाई जाती है। मैं प्रदर्शित करता हूं कि तालिका बनाते समय एक विदेशी कुंजी कैसे बनाई जाती है (मौजूदा तालिका को अद्यतन करने के विपरीत)।
विदेशी कुंजी एक स्तंभ है जो किसी अन्य तालिका के प्राथमिक कुंजी स्तंभ को संदर्भित करता है। यह तालिकाओं के बीच संबंध बनाता है।
उदाहरण 1 - तैयारी
इस उदाहरण में मैं एक टेबल के साथ एक टेस्ट डेटाबेस बनाउंगा। इस तालिका में प्राथमिक कुंजी होगी जिसे हमारी विदेशी कुंजी संदर्भित करेगी।
डेटाबेस बनाएं:
डेटाबेस FK_Test बनाएं;
अब प्राथमिक कुंजी तालिका बनाएं:
एफके_टेस्ट का उपयोग करें; टेबल देश बनाएं (देश आईडी int पहचान (1,1) पूर्ण प्राथमिक कुंजी नहीं, देश का नाम nvarchar (60));
उदाहरण 2 - विदेशी कुंजी बनाएं
अब जबकि हमारे पास एक प्राथमिक कुंजी वाली तालिका है, आइए एक विदेशी कुंजी के साथ एक अन्य तालिका बनाएं जो उस प्राथमिक कुंजी को संदर्भित करती है।
टेबल सिटी बनाएं (सिटीआईडी इंट पहचान (1,1) न्यूल प्राइमरी की नहीं, कंट्रीआईड नॉट न्यूल रेफरेंस कंट्री (कंट्रीआईड), सिटीनाम nvarchar(60));
विदेशी कुंजी बनाने का यह सबसे आसान तरीका है। हम केवल REFERENCES
जोड़ते हैं क्लॉज (प्राथमिक कुंजी तालिका और कॉलम के साथ) उस कॉलम में जिसमें विदेशी कुंजी बाधा होगी।
स्पष्ट होने के लिए, विदेशी कुंजी को परिभाषित करने वाला भाग यह है:
संदर्भ देश(देश आईडी)
यह कॉलम परिभाषा में शामिल है और केवल यह बताता है कि यह कॉलम CountryId
. का संदर्भ देगा Country
में कॉलम टेबल।
इस मामले में, विदेशी कुंजी और प्राथमिक कुंजी, जिसका वह संदर्भ देती है, दोनों एक ही नाम साझा करते हैं (CountryId
) हालांकि, यह एक आवश्यकता नहीं है - आपके विदेशी कुंजी कॉलम में उस कॉलम का एक पूरी तरह से अलग नाम हो सकता है जिसका वह संदर्भ देता है (हालांकि विदेशी कुंजी संबंध में भाग लेने वाले सभी कॉलम समान लंबाई और पैमाने के साथ परिभाषित किए जाने चाहिए)।
यह उदाहरण SQL सर्वर को स्वचालित रूप से विदेशी कुंजी का नाम उत्पन्न करने का कारण बनता है। ऐसा इसलिए है क्योंकि मैंने कोई नाम नहीं दिया। यह देखने के लिए पढ़ें कि आप अपनी विदेशी कुंजी के लिए एक नाम कैसे बना सकते हैं।
लेकिन पहले, आइए हम अभी-अभी बनाई गई विदेशी कुंजी बाधा की जाँच करें।
उदाहरण 3 - विदेशी कुंजी प्रतिबंध की जांच करें
टी-एसक्यूएल का उपयोग करके एक विदेशी कुंजी वापस करने के कई तरीके हैं, और यहां उनमें से एक है:
EXEC sp_fkeys @fktable_name =शहर;
परिणाम (ऊर्ध्वाधर आउटपुट का उपयोग करके):
PKTABLE_QUALIFIER | FK_TestPKTABLE_OWNER | dboPKTABLE_NAME | देशPKCOLUMN_NAME | CountryIdFKTABLE_QUALIFIER | FK_TestFKTABLE_OWNER | dboFKTABLE_NAME | शहरFKCOLUMN_NAME | कंट्रीIdKEY_SEQ | 1UPDATE_RULE | 1DELETE_RULE | 1FK_NAME | FK__City__CountryId__38996AB5PK_NAME | PK__देश__10D1609FC8BFA7F2DEFERRABILITY | 7
sp_fkeys
सिस्टम संग्रहीत प्रक्रिया हमारी विदेशी कुंजी, उससे जुड़ी प्राथमिक कुंजी और अन्य प्रासंगिक विवरणों के बारे में जानकारी लौटाती है। आप केवल विदेशी कुंजी तालिका या प्राथमिक कुंजी तालिका के नाम से गुजरते हैं, और यह प्रासंगिक जानकारी लौटाएगा।
इस उदाहरण में, मैं विदेशी कुंजी तालिका का नाम पास करता हूं - City
. परिणामों में, हम
FK_NAME
. को देख सकते हैं कॉलम देखें कि इस तालिका में एक विदेशी कुंजी बाधा है जिसे
FK__City__CountryId__38996AB5
कहा जाता है . यह वही है जिसे हमने अभी बनाया है।
तो अब जबकि हमने विदेशी कुंजी बना ली है, जब भी हम City.CountryId
में कोई मान डालने या अपडेट करने का प्रयास करते हैं कॉलम में, विदेशी कुंजी बाधा केवल तभी अनुमति देगी जब Country.CountryId
में वही मान पहले से मौजूद हो कॉलम। यह सुनिश्चित करता है कि डेटाबेस के भीतर संदर्भात्मक अखंडता बनी रहे।
उदाहरण 4 - अधिक विकल्प
आपकी विदेशी कुंजी परिभाषा में और विकल्प जोड़ना संभव है।
उदाहरण के लिए आप विदेशी कुंजी के लिए एक नाम प्रदान कर सकते हैं। आप यह भी निर्दिष्ट कर सकते हैं कि इस कॉलम में मानों का क्या होना चाहिए यदि प्राथमिक कुंजी में संबंधित मान को अद्यतन या हटा दिया जाता है।
यहां, मैं फिर से दोनों टेबल बनाता हूं, लेकिन इस बार मैं इन विकल्पों को स्पष्ट रूप से निर्दिष्ट करता हूं (मैं प्राथमिक कुंजी के लिए भी ऐसा ही करता हूं):
टेबल कंट्री बनाएं (कंट्रीआईडी इंट पहचान (1,1) न्यूल नहीं, कॉन्स्ट्रेंट पीके_कंट्री_कंट्रीआईड प्राथमिक कुंजी क्लस्टर (कंट्रीआईडी), कंट्रीनाम nvarchar (60)); टेबल सिटी बनाएं (सिटीआईडी इंट पहचान (1,1) न्यूल नहीं, बाधा PK_City_CityId प्राथमिक कुंजी क्लस्टर (CityId), CountryId int NULL, CONSTRAINT FK_City_देश विदेशी कुंजी (देश आईडी) संदर्भ देश (देश आईडी) अद्यतन कैस्केड पर हटाए गए कैस्केड पर, शहर का नाम nvarchar (60));इस मामले में, विदेशी कुंजी परिभाषा
CONSTRAINT
. से शुरू होती है , उसके बाद विदेशी कुंजी का नाम, उसके बादFOREIGN KEY
, कॉलम के बाद विदेशी कुंजी बाधा को लागू किया जाएगा (कोष्ठकों में डाला गया)।फिर हम वही
REFERENCES
देखते हैं खंड जो हमने पिछले उदाहरण में देखा था।
ON DELETE CASCADE
औरON UPDATE CASCADE
क्लॉज़ का उपयोग यह सुनिश्चित करने के लिए किया जाता है किCountry
. में किए गए परिवर्तन तालिका स्वचालित रूप सेCity
में प्रचारित हो जाती है टेबल। उदाहरण के लिए, यदि पैरेंट (प्राथमिक कुंजी) तालिका से कोई पंक्ति हटा दी जाती है, तो संदर्भ (विदेशी कुंजी) तालिका से संबंधित पंक्तियों को हटा दिया जाता है।
ON DELETE
. के लिए डिफ़ॉल्ट मान औरON UPDATE
हैNO ACTION
. इस मामले में डेटाबेस इंजन एक त्रुटि उठाता है, और मूल तालिका में पंक्ति पर अद्यतन या हटाने की क्रिया वापस ले ली जाती है।आप
SET NULL
. का भी उपयोग कर सकते हैं विदेशी कुंजी कॉलम कोNULL
. पर सेट करने के लिए (विदेशी कुंजी कॉलम को अशक्त होने की आवश्यकता है), याSET DEFAULT
इसे इसके डिफ़ॉल्ट मान पर सेट करने के लिए (एक डिफ़ॉल्ट परिभाषा के लिए विदेशी कुंजी कॉलम की आवश्यकता होती है। यदि कोई कॉलम शून्य है, और कोई स्पष्ट डिफ़ॉल्ट मान सेट नहीं है,NULL
स्तंभ का अंतर्निहित डिफ़ॉल्ट मान बन जाता है)।इस उदाहरण में मैंने प्राथमिक कुंजियों को नाम देने का अवसर भी लिया। आप देख सकते हैं कि प्राथमिक कुंजी सिंटैक्स विदेशी कुंजी सिंटैक्स के समान है, लेकिन
REFERENCES
के बिना क्लॉज (और एक जोड़ाCLUSTERED
. के साथ) तर्क, जो प्राथमिक कुंजी के लिए डिफ़ॉल्ट है)।अब विदेशी कुंजी जांचें:
EXEC sp_fkeys @fktable_name =शहर;परिणाम:
PKTABLE_QUALIFIER | FK_TestPKTABLE_OWNER | dboPKTABLE_NAME | देशPKCOLUMN_NAME | CountryIdFKTABLE_QUALIFIER | FK_TestFKTABLE_OWNER | dboFKTABLE_NAME | शहरFKCOLUMN_NAME | कंट्रीIdKEY_SEQ | 1UPDATE_RULE | 0DELETE_RULE | 0FK_NAME | FK_City_CountryPK_NAME | PK_Country_CountryIdDEFERRABILITY | 7हम देख सकते हैं कि विदेशी कुंजी का नाम अब FK_City_Country है और कॉलम की प्राथमिक कुंजी बाधा जिसे वह संदर्भित करता है उसे PK_Country_CountryId कहा जाता है ।
उदाहरण 5 - एकाधिक स्तंभों पर विदेशी कुंजी
आप एक से अधिक स्तंभों पर एक विदेशी कुंजी भी बना सकते हैं जो एक बहु-स्तंभ प्राथमिक कुंजी का संदर्भ देता है। बहुस्तंभ प्राथमिक कुंजी को समग्र प्राथमिक कुंजी के रूप में भी जाना जाता है। एक समग्र विदेशी कुंजी बनाने के लिए, कुंजी को परिभाषित करते समय केवल कॉलम को अल्पविराम से अलग करें।
इस तरह:
CONSTRAINT FK_FKName विदेशी कुंजी (FKColumn1, FKColumn2)संदर्भ प्राथमिककीटेबल (PKColumn1, PKColumn2)अधिक विस्तृत उदाहरण के लिए SQL सर्वर में एक समग्र विदेशी कुंजी कैसे बनाएं देखें।
क्या प्राथमिक कुंजी वास्तव में आवश्यक है?
विदेशी कुंजी के लिए प्राथमिक कुंजी बिल्कुल आवश्यक नहीं है, क्योंकि आप एक अद्वितीय बाधा या अद्वितीय अनुक्रमणिका का उपयोग कर सकते हैं। विशेष रूप से, Microsoft दस्तावेज़ यह बताता है:
<ब्लॉकक्वॉट>
FOREIGN KEY
बाधाएंPRIMARY KEY
में केवल स्तंभों को संदर्भित कर सकती हैं याUNIQUE
संदर्भित तालिका में याUNIQUE INDEX
. में बाधाएं संदर्भित टेबल पर।इसलिए आम तौर पर सभी टेबलों पर प्राथमिक कुंजियाँ रखना एक अच्छा अभ्यास है, लेकिन आपकी विदेशी कुंजियाँ उन्हें संदर्भित करने के लिए बाध्य नहीं हैं।