एक समग्र प्राथमिक कुंजी एक प्राथमिक कुंजी है जिसमें कई कॉलम होते हैं। Microsoft आमतौर पर अपने दस्तावेज़ीकरण में इन्हें बहु-स्तंभ प्राथमिक कुंजियों के रूप में संदर्भित करता है।
यह आलेख SQL सर्वर में Transact-SQL का उपयोग करके एक समग्र प्राथमिक कुंजी बनाने का एक उदाहरण प्रदान करता है।
आप एक संयुक्त प्राथमिक कुंजी बना सकते हैं जैसे आप एक प्राथमिक कुंजी बनाते हैं, सिवाय इसके कि केवल एक कॉलम निर्दिष्ट करने के बजाय, आप अल्पविराम द्वारा अलग किए गए दो या अधिक कॉलम का नाम प्रदान करते हैं।
इस तरह:
CONSTRAINT PK_Name PRIMARY KEY (Column1, Column2)
उदाहरण 1 - एक समग्र प्राथमिक कुंजी बनाएं
मिश्रित प्राथमिक कुंजी का उपयोग करने वाले डेटाबेस का एक उदाहरण यहां दिया गया है।
इस उदाहरण के लिए, मैं PK_Test . नामक एक डेटाबेस बनाऊंगा :
CREATE DATABASE PK_Test;
अब जब डेटाबेस बन गया है, तो चलिए आगे बढ़ते हैं और टेबल बनाते हैं।
USE PK_Test; CREATE TABLE Musician ( MusicianId int NOT NULL, FirstName varchar(60), LastName varchar(60), CONSTRAINT PK_Musician PRIMARY KEY (MusicianID) ); CREATE TABLE Band ( BandId int NOT NULL, BandName varchar(255), CONSTRAINT PK_Band PRIMARY KEY (BandId) ); CREATE TABLE BandMember ( MusicianId int NOT NULL, BandId int NOT NULL, CONSTRAINT PK_BandMember PRIMARY KEY (MusicianID, BandId), CONSTRAINT FK_BandMember_Band FOREIGN KEY (BandId) REFERENCES Band(BandId), CONSTRAINT FK_BandMember_Musician FOREIGN KEY (MusicianId) REFERENCES Musician(MusicianId) );
इस उदाहरण में, BandMember
तालिका में एक बहु-स्तंभ प्राथमिक कुंजी है। इस मामले में प्राथमिक कुंजी का प्रत्येक स्तंभ किसी अन्य तालिका की प्राथमिक कुंजी के लिए एक विदेशी कुंजी भी है, लेकिन यह कोई आवश्यकता नहीं है।
उपरोक्त डेटाबेस डिज़ाइन के पीछे तर्क यह है कि, एक संगीतकार संभावित रूप से कई बैंड का सदस्य हो सकता है। साथ ही, प्रत्येक बैंड में कई संगीतकार हो सकते हैं। इसलिए हमारे बीच कई-से-अनेक संबंध हैं। यही कारण है कि BandMember
तालिका बनाई जाती है - इसका उपयोग Musician
. के बीच एक क्रॉस-रेफरेंस तालिका के रूप में किया जाता है टेबल और Band
टेबल।
यह विशेष मामला एक समग्र प्राथमिक कुंजी का समर्थन करता है, क्योंकि एक बैंड का सदस्य होने के नाते एक संगीतकार एक अनूठी घटना होनी चाहिए। दूसरे शब्दों में, हम एक संगीतकार के साथ एक ही बैंड के सदस्य होने के साथ कई पंक्तियाँ नहीं चाहते हैं। यह डेटा अखंडता का उल्लंघन करेगा। यह तब भी कहर पैदा कर सकता है जब हम इस तालिका और दूसरे (जो हम यहां करते हैं) के बीच एक संबंध बनाते हैं, यहां तक कि संदर्भात्मक अखंडता बनाए रखने की कोशिश करते हैं।
उदाहरण 2 - डेटा डालें
उपरोक्त कोड को चलाने के बाद, अब मैं डेटाबेस को डेटा के साथ लोड कर सकता हूं:
INSERT INTO Musician VALUES ( 1, 'Ian', 'Paice' ), ( 2, 'Roger', 'Glover' ), ( 3, 'Richie', 'Blackmore' ), ( 4, 'Rod', 'Evans' ), ( 5, 'Ozzy', 'Osbourne' ); INSERT INTO Band VALUES ( 1, 'Deep Purple' ), ( 2, 'Rainbow' ), ( 3, 'Whitesnake' ), ( 4, 'Iron Maiden' ); INSERT INTO BandMember VALUES ( 1, 1 ), ( 1, 3 ), ( 2, 1 ), ( 2, 2 ), ( 3, 1 ), ( 3, 2 ), ( 4, 1 );
उदाहरण 3 - मूल प्रश्न
अब वह डेटा हमारे डेटाबेस में है, आइए उस डेटा में से कुछ को वापस करने के लिए एक क्वेरी चलाते हैं।
यहां एक बुनियादी सवाल है:
SELECT CONCAT(m.FirstName, ' ', m.LastName) AS 'Musician', b.BandName AS 'Band' FROM Musician m JOIN BandMember bm ON m.MusicianId = bm.MusicianId JOIN Band b ON b.BandId = bm.BandId AND m.MusicianId = bm.MusicianId;
परिणाम:
+------------------+-------------+ | Musician | Band | |------------------+-------------| | Ian Paice | Deep Purple | | Ian Paice | Whitesnake | | Roger Glover | Deep Purple | | Roger Glover | Rainbow | | Richie Blackmore | Deep Purple | | Richie Blackmore | Rainbow | | Rod Evans | Deep Purple | +------------------+-------------+
इसलिए जैसा कि अपेक्षित था, यह केवल उन्हीं संगीतकारों और बैंडों को लौटाता है जिनकी BandMember
में प्रविष्टि है संदर्भ तालिका।
उदाहरण 4 - थोड़ा संशोधित क्वेरी
यहां उपरोक्त क्वेरी का एक संशोधित संस्करण दिया गया है जो परिणामों को एक अलग तरीके से प्रस्तुत करता है:
SELECT b.BandName AS 'Band', STRING_AGG(CONCAT(m.FirstName, ' ', m.LastName), ', ') AS 'Musicians' FROM Musician m JOIN BandMember bm ON m.MusicianId = bm.MusicianId JOIN Band b ON b.BandId = bm.BandId AND m.MusicianId = bm.MusicianId GROUP BY b.BandName;
परिणाम:
+-------------+------------------------------------------------------+ | Band | Musicians | |-------------+------------------------------------------------------| | Deep Purple | Ian Paice, Roger Glover, Richie Blackmore, Rod Evans | | Rainbow | Roger Glover, Richie Blackmore | | Whitesnake | Ian Paice | +-------------+------------------------------------------------------+
यहां परिणाम बैंड द्वारा समूहीकृत किए जाते हैं, और प्रत्येक बैंड के सभी संगीतकार एक ही फ़ील्ड में अल्पविराम से अलग की गई सूची के रूप में प्रदर्शित होते हैं।
ऐसा करने के लिए मैं STRING_AGG()
. का उपयोग करता हूं संगीतकारों को जोड़ने का कार्य करता है।
समग्र विदेशी कुंजी
उपरोक्त उदाहरण के साथ समस्या यह है कि अधिकांश डेटा पुराना है। इनमें से कुछ संगीतकारों ने वास्तव में उन बैंडों को छोड़ दिया है। और कुछ चले गए हैं और फिर बाद की तारीख में लौट आए हैं।
हम इससे कैसे निपट सकते हैं?
हम उस समयावधि को रिकॉर्ड करने के लिए एक और संदर्भ तालिका बना सकते हैं जब प्रत्येक संगीतकार प्रत्येक बैंड का सदस्य हो। ऐसी तालिका को BandMember
. को संदर्भित करने की आवश्यकता होगी एक विदेशी कुंजी के माध्यम से तालिका। और यह देखते हुए कि इस तालिका में एक समग्र प्राथमिक कुंजी है, हमें नई तालिका पर एक समग्र विदेशी कुंजी का उपयोग करने की आवश्यकता होगी जो इसका संदर्भ देती है।
उदाहरण के लिए SQL सर्वर में एक समग्र विदेशी कुंजी कैसे बनाएं देखें। वह लेख ऊपर के समान उदाहरण का उपयोग करता है, सिवाय एक समग्र विदेशी कुंजी के साथ एक अतिरिक्त तालिका को छोड़कर जो उपरोक्त समग्र प्राथमिक कुंजी का संदर्भ देता है।