एक बात पर विचार करना है कि एक प्राथमिक कुंजी और एक क्लस्टर सूचकांक एक ही बात नहीं है। एक प्राथमिक कुंजी एक बाधा है और उन नियमों से निपटती है जिनके द्वारा डेटा रहता है (यानी डेटा अखंडता); इसका दक्षता / प्रदर्शन से कोई लेना-देना नहीं है। एक प्राथमिक कुंजी के लिए आवश्यक है कि कुंजी कॉलम (संयोजन में) अनूठा हो और न ही NULL (व्यक्तिगत रूप से) हो। एक पीके को एक अद्वितीय सूचकांक के माध्यम से लागू किया जाता है, हालांकि यह क्लस्टर्ड या नॉन-क्लस्टर्ड हो सकता है।
एक क्लस्टर इंडेक्स भौतिक रूप से (डिस्क पर) एक साधन है जो तालिका में डेटा का आदेश देता है और प्रदर्शन से संबंधित है; इसका डेटा अखंडता से कोई लेना-देना नहीं है। एक संकुल सूचकांक कर सकते हैंआवश्यकता है कि कुंजी कॉलम (संयोजन में) अद्वितीय हो, लेकिन इसकी आवश्यकता नहीं है। हालांकि, चूंकि क्लस्टर्ड इंडेक्स डेटा का भौतिक क्रम है, इसलिए इसे प्रत्येक पंक्ति को विशिष्ट रूप से पहचानने की आवश्यकता है, चाहे कुछ भी हो। इसलिए यदि आप इसे विशिष्टता की आवश्यकता के लिए निर्धारित नहीं करते हैं, तो यह एक छिपे हुए 4-बाइट "यूनीकिफायर" कॉलम के माध्यम से अपनी विशिष्टता बनाएगा। वह कॉलम हमेशा नॉन-यूनिक क्लस्टर्ड इंडेक्स में होता है, लेकिन यह महत्वपूर्ण स्थान (संयोजन में) अद्वितीय होने पर कोई स्थान नहीं लेता है। पहले हाथ को देखने के लिए कि यह "विशिष्ट" कॉलम कैसे काम करता है (दोनों क्लस्टर इंडेक्स और गैर-क्लस्टर इंडेक्स पर प्रभाव), कृपया इस टेस्ट स्क्रिप्ट को देखें जो मैंने पेस्टिन पर पोस्ट किया था: यू -साइज़ का परीक्षण करने के लिए टी-एसक्यूएल स्क्रिप्ट ।
इसलिए, का मुख्य प्रश्न:
क्या यह एक ऑटो-इन्क्रीमेंट id
फ़ील्ड को जोड़ने के लिए अधिक कुशल होगा और company_id
प्राथमिक कुंजी के रूप में संयोजन के साथ उपयोग करेगा, या क्या यह अनावश्यक हेडहेड होगा
उन दो अवधारणाओं को भ्रमित कर रहा है, इसलिए उन्हें अलग से संबोधित करने की आवश्यकता है, हालांकि निश्चित रूप से कुछ ओवरलैप है।
क्या एक IDENTITY
स्तंभ जोड़ा जाना चाहिए या क्या यह अनावश्यक ओवरहेड होगा?
यदि आप एक INT IDENTITY
कॉलम जोड़ते हैं और इसका उपयोग पीके बनाने के लिए करते हैं, तो मान लें कि यह एक क्लस्टर किया गया पीके होगा, जो हर पंक्ति में 4 बाइट जोड़ता है। यह कॉलम प्रश्नों में दिखाई और प्रयोग करने योग्य है। यह एक विदेशी कुंजी के रूप में अन्य तालिकाओं में जोड़ा जा सकता है, हालांकि इस विशेष मामले में ऐसा नहीं होगा।
यदि आप INT IDENTITY
कॉलम नहीं जोड़ते हैं , तो आप इस तालिका पर PK नहीं बना सकते। हालाँकि, जब तक आप UNIQUE
विकल्प का उपयोग नहीं करते तब तक आप टेबल पर एक संकुल सूचकांक बना सकते हैं । इस स्थिति में, SQL सर्वर एक छुपा स्तंभ जोड़ देगा जिसे "विशिष्ट" कहा जाता है जो ऊपर वर्णित अनुसार व्यवहार करता है। क्योंकि स्तंभ छिपा हुआ है, इसका उपयोग प्रश्नों में या विदेशी कुंजी के संदर्भ के रूप में नहीं किया जा सकता है।
जहाँ तक दक्षता जाती है, ये विकल्प लगभग समान होते हैं। हां, कुछ पंक्तियों (प्रारंभिक अद्वितीय कुंजी मानों वाले) को 0 बाइट्स लेने के कारण गैर-अद्वितीय क्लस्टर इंडेक्स होने से थोड़ा कम स्थान लिया जाएगा, जबकि IDENTITY
/ PK में सभी पंक्तियों में 4 बाइट्स होंगे। लेकिन 0 बाइट पंक्तियों के लिए पर्याप्त नहीं होगा (विशेष रूप से अपेक्षित पंक्तियों की छोटी मात्रा के साथ) कभी अंतर पर ध्यान देने के लिए, अकेले ID
प्रश्नों में कॉलम का उपयोग करने में सक्षम होने की सुविधा को बाहर करने दें।
INT आइडेंटिटी कॉलम या पर्सेंटेड org_path
कम्प्यूटेड कॉलम का हैश ?
यह देखते हुए कि आप org_path
मूल्यों के आधार पर पंक्तियों को नहीं देख रहे हैं, तो यह समझ नहीं आता है कि परिकलित कॉलम के ओवरहेड को जोड़ने के लिए कम्प्यूटेड कॉलम के खिलाफ मिलान करने के लिए प्रश्नों में उस हैश की गणना करने की आवश्यकता है (यह मेरा था मूल सुझाव, यहाँ संशोधन इतिहास में उपलब्ध है , जो प्रश्न के प्रारंभिक शब्दों / विवरणों पर आधारित था)। इस विशेष मामले में, INT IDENTITY
"आईडी" कॉलम संभवतः सबसे अच्छा है।
प्रमुख स्तंभ आदेश
यह देखते हुए कि ID
कॉलम शायद ही कभी, यदि कभी प्रश्नों में उपयोग किया जाता है, और यह देखते हुए कि दो मुख्य उपयोग-मामलों को "सभी पंक्तियों" या "दिए गए सभी पंक्तियों" को प्राप्त company_id
करना है, तो मैं पीके पर बनाऊंगा company_id, id
। और इसका मतलब है कि पंक्तियों को क्रमिक रूप से नहीं डाला गया है, मैं FILLFACTOR
90 की संख्या निर्दिष्ट करूंगा। विखंडन को कम करने के लिए आपको नियमित सूचकांक रखरखाव करने की भी आवश्यकता होगी।
दूसरा सवाल
तथ्य यह है कि company_id एक अन्य तालिका में प्राथमिक कुंजी है, यहां कोई प्रभाव नहीं है
नहीं।
उत्प्रेरक
चूँकि org_path
मूल्य एक company_id
अद्वितीय हैं, इसलिए आपको इसे INSERT, UPDATE
लागू करने के लिए एक ट्रिगर बनाना चाहिए । उत्प्रेरक में, एक कर IF EXISTS
एक प्रश्न है कि शायद एक करता है के साथ COUNT(*)
और GROUP BY company_id, org_path
। यदि कुछ पाया जाता है, ROLLBACK
तो डीएमएल ऑपरेशन को रद्द करने के लिए जारी करें और फिर एक RAISERROR
कहावत है कि डुप्लिकेट हैं।
मिलान
मेरे प्रारंभिक उत्तर में (प्रश्न के मूल शब्दों / विरल विवरणों के आधार पर, और यहाँ संशोधन इतिहास में उपलब्ध है ), मैंने संभवतः एक बाइनरी (यानी _BIN2
) कॉलेशन का उपयोग करने का सुझाव दिया था । अब जब हमारे पास अंतर्दृष्टि है कि वास्तव में क्या org_path
है, तो मैं बाइनरी कोलेशन का उपयोग करने की सिफारिश नहीं करूंगा । चूँकि विशिष्ट अंक होंगे, आप भाषाई तुल्यता का उपयोग करना चाहते हैं।