GUIDs आपकी प्राथमिक कुंजी के लिए एक स्वाभाविक पसंद हो सकता है - और यदि आपको वास्तव में चाहिए, तो आप संभवतः तालिका के प्राथमिक कुंजी के लिए इसका उपयोग करने का तर्क दे सकते हैं। जब तक मैं दृढ़ता से अनुशंसा नहीं करूँगा कि क्लस्टर कुंजी के रूप में GUID कॉलम का उपयोग करें , जो कि SQL सर्वर डिफ़ॉल्ट रूप से करता है, जब तक कि आप विशेष रूप से इसे नहीं बताते हैं।
आपको वास्तव में दो मुद्दों को अलग रखने की आवश्यकता है:
प्राथमिक कुंजी एक तार्किक निर्माण है - उम्मीदवार कुंजी है जो विशिष्ट और मज़बूती से अपनी तालिका में प्रत्येक पंक्ति की पहचान करता है में से एक। यह कुछ भी हो सकता है, वास्तव में - INT
ए GUID
, ए, स्ट्रिंग - अपने परिदृश्य के लिए सबसे अधिक समझ में आता है।
क्लस्टरिंग कुंजी (स्तंभ या स्तंभों कि मेज पर "संकुल अनुक्रमणिका" को परिभाषित) - यह एक है भौतिक भंडारण से संबंधित बात यहाँ है, और एक छोटे से, स्थिर, बढ़ती डेटा प्रकार अपने बेहतरीन पिकअप है - INT
या BIGINT
के रूप में अपने डिफ़ॉल्ट विकल्प।
डिफ़ॉल्ट रूप से, SQL सर्वर तालिका पर प्राथमिक कुंजी को क्लस्टरिंग कुंजी के रूप में भी उपयोग किया जाता है - लेकिन उस तरह से होने की आवश्यकता नहीं है! जब मैंने GUID-आधारित प्राथमिक / क्लस्टर कुंजी को दो अलग-अलग कुंजी - GUID पर प्राथमिक (तार्किक) कुंजी और एक अलग INT IDENTITY(1,1)
कॉलम पर क्लस्टरिंग (ऑर्डरिंग) कुंजी को तोड़ते समय व्यक्तिगत रूप से बड़े पैमाने पर प्रदर्शन लाभ देखा है ।
जैसा कि किम्बर्ली ट्रिप - इंडेक्सिंग की रानी - और अन्य लोगों ने कई बार कहा है - GUID
जैसे कि क्लस्टरिंग कुंजी इष्टतम नहीं है, क्योंकि इसकी यादृच्छिकता के कारण, यह बड़े पैमाने पर पृष्ठ और सूचकांक विखंडन और आम तौर पर खराब प्रदर्शन को बढ़ावा देगा।
हाँ, मुझे पता है - newsequentialid()
एसक्यूएल सर्वर 2005 और ऊपर में है - लेकिन यह भी सही मायने में और पूरी तरह से अनुक्रमिक नहीं है और इस तरह भी वही समस्याओं से ग्रस्त है GUID
- बस थोड़ा कम प्रमुखता से।
फिर विचार करने के लिए एक और मुद्दा है: एक मेज पर क्लस्टरिंग कुंजी को प्रत्येक और प्रत्येक गैर-क्लस्टर इंडेक्स पर प्रत्येक प्रविष्टि के साथ-साथ आपकी तालिका में भी जोड़ा जाएगा - इस प्रकार आप वास्तव में यह सुनिश्चित करना चाहते हैं कि यह यथासंभव छोटा है। आमतौर पर, INT
बड़ी संख्या में तालिकाओं के लिए 2+ बिलियन पंक्तियों के साथ पर्याप्त होना चाहिए - और GUID
क्लस्टरिंग कुंजी के रूप में तुलना करने पर , आप डिस्क पर और सर्वर मेमोरी में सैकड़ों मेगाबाइट भंडारण कर सकते हैं।
त्वरित गणना - INT
बनाम GUID
प्राथमिक और क्लस्टरिंग कुंजी के रूप में उपयोग करना :
- आधार तालिका 1'000'000 पंक्तियों (3.8 MB बनाम 15.26 MB) के साथ
- 6 गैर-अनुक्रमित सूचकांक (22.89 एमबी बनाम 91.55 एमबी)
कुल: 25 एमबी बनाम 106 एमबी - और यह सिर्फ एक मेज पर है!
विचार के लिए कुछ और भोजन - किम्बर्ली ट्रिप द्वारा उत्कृष्ट सामान - इसे पढ़ें, इसे फिर से पढ़ें, इसे पचाएं! यह SQL सर्वर अनुक्रमण सुसमाचार है, वास्तव में।
पुनश्च: बेशक, अगर आप सिर्फ कुछ सौ या कुछ हजार पंक्तियों के साथ काम कर रहे हैं - तो इनमें से अधिकांश तर्कों का वास्तव में आप पर अधिक प्रभाव नहीं पड़ेगा। हालांकि: यदि आप दसियों या सैकड़ों हजारों पंक्तियों में आते हैं, या आप लाखों में गिनती शुरू करते हैं - तो उन बिंदुओं को समझना बहुत महत्वपूर्ण और बहुत महत्वपूर्ण हो जाता है।
अद्यतन: यदि आप अपने PKGUID
कॉलम को अपनी प्राथमिक कुंजी के रूप में रखना चाहते हैं (लेकिन आपकी क्लस्टरिंग कुंजी नहीं), और एक अन्य कॉलम MYINT
( INT IDENTITY
) आपकी क्लस्टरिंग कुंजी के रूप में है - तो इसका उपयोग करें:
CREATE TABLE dbo.MyTable
(PKGUID UNIQUEIDENTIFIER NOT NULL,
MyINT INT IDENTITY(1,1) NOT NULL,
.... add more columns as needed ...... )
ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable
PRIMARY KEY NONCLUSTERED (PKGUID)
CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)
मूल रूप से: आपको बस स्पष्ट रूप से PRIMARY KEY
बाधा को बताना होगा कि यह NONCLUSTERED
(अन्यथा यह आपके क्लस्टर इंडेक्स के रूप में बनाया गया है, डिफ़ॉल्ट रूप से) - और फिर आप एक दूसरा इंडेक्स बनाते हैं जिसे इस रूप में परिभाषित किया गया हैCLUSTERED
यह काम करेगा - और यह एक वैध विकल्प है यदि आपके पास एक मौजूदा प्रणाली है जिसे प्रदर्शन के लिए "फिर से इंजीनियर" होने की आवश्यकता है। एक नई प्रणाली के लिए, यदि आप स्क्रैच से शुरू करते हैं, और आप प्रतिकृति परिदृश्य में नहीं हैं, तो मैं हमेशा ID INT IDENTITY(1,1)
अपनी क्लस्टर की गई प्राथमिक कुंजी के रूप में चुनूंगा - किसी भी चीज़ की तुलना में अधिक कुशल!