2013-12-09 3 views
8

SQL सर्वर में प्राथमिक कुंजी के लिए कौन सा सबसे अच्छा विकल्प है?अनोखा पहचानकर्ता बनाम पहचान बनाम सामग्री कोड - प्राथमिक कुंजी के लिए सबसे अच्छा विकल्प कौन सा है?

Uniqueidentifiers

उदहारण के लिए:
कुछ उदाहरण कोड रहे हैं

CREATE TABLE new_employees 
    (employeeId UNIQUEIDENTIFIER  DEFAULT NEWID(), 
    fname  VARCHAR(20)) 
GO 
INSERT INTO new_employees(fname) VALUES ('Karin') 
GO 

Identity columns

उदा

CREATE TABLE new_employees 
(
    employeeId int IDENTITY(1,1), 
    fname varchar (20) 
); 

INSERT new_employees 
    (fname) 
VALUES 
    ('Karin'); 

[सामग्री कोड] (या व्यवसाय के कोड है, जो एक सामग्री की पहचान। जैसे ग्राहक पहचानकर्ता)

उदा

CREATE TABLE new_employees(
    [ClientId] [varchar](20) NOT NULL, 
    [fName] [varchar](20) NULL  
) 

INSERT new_employees 
    (ClientID, fname) 
VALUES 
    ('C0101000001',--customer identifier,e.g.'C0101000001' a user-defined code. 
    'Karin'); 

मुझे तीन प्रकार पहचान स्तंभों, या अन्य विकल्पों में से प्राथमिक कुंजी चुनने के लिए कुछ सलाह दे।

धन्यवाद!

उत्तर

14

GUID आपकी प्राथमिक कुंजी के लिए एक प्राकृतिक विकल्प प्रतीत हो सकता है - और यदि आपको वास्तव में जरूरी है, तो आप शायद तालिका के प्राथमिक कुंजी के लिए इसका उपयोग करने का बहस कर सकते हैं। कॉल करने के लिए कॉलमक्लस्टरिंग कुंजी, जो SQL सर्वर डिफ़ॉल्ट रूप से करता है, जब तक आप इसे विशेष रूप से नहीं बताते हैं, तब तक कॉलम का उपयोग करने की दृढ़ता से अनुशंसा करते हैं।

आप वास्तव में दो मुद्दों के अलावा रखने की जरूरत है:

  1. प्राथमिक कुंजी एक तार्किक निर्माण है - उम्मीदवार कुंजी है जो विशिष्ट और मज़बूती से अपनी तालिका में प्रत्येक पंक्ति की पहचान करता है में से एक। यह कुछ भी हो सकता है, वास्तव में - INT, एक GUID, एक स्ट्रिंग - जो आपके परिदृश्य के लिए सबसे अधिक समझ में आता है चुनें।

  2. क्लस्टरिंग कुंजी (स्तंभ या स्तंभों कि मेज पर "क्लस्टर सूचकांक" को परिभाषित) - यह एक शारीरिक भंडारण से संबंधित बात यहाँ, एक छोटे से, स्थिर, बढ़ती डेटा है, और टाइप आपके सबसे अच्छे विकल्प के रूप में - INT या BIGINT है।

डिफ़ॉल्ट रूप से, SQL सर्वर तालिका पर प्राथमिक कुंजी क्लस्टरिंग कुंजी के रूप में भी उपयोग की जाती है - लेकिन उस तरह से होने की आवश्यकता नहीं है! पिछली GUID- आधारित प्राथमिक/क्लस्टर कुंजी को दो अलग-अलग कुंजियों में विभाजित करते समय मैंने व्यक्तिगत प्रदर्शन लाभ व्यक्तिगत रूप से देखा है - GUID पर प्राथमिक (तार्किक) कुंजी, और अलग INT IDENTITY(1,1) कॉलम पर क्लस्टरिंग (ऑर्डरिंग) कुंजी।

Kimberly Tripp के रूप में - अनुक्रमण की रानी - और दूसरों के लिए एक महान कई बार कहा है - एक GUID के रूप में क्लस्टरिंग कुंजी इष्टतम नहीं है, अपने अनियमितता के कारण के बाद से, यह बड़े पैमाने पर पेज और सूचकांक विखंडन और को बढ़ावा मिलेगा आम तौर पर खराब प्रदर्शन के लिए।

हां, मुझे पता है - एसक्यूएल सर्वर 2005 और 0 में newsequentialid() है - लेकिन यह भी वास्तव में और पूरी तरह अनुक्रमिक नहीं है और इस प्रकार GUID जैसी ही समस्याओं से पीड़ित है - बस थोड़ा सा प्रमुख।

फिर विचार करने के लिए एक और मुद्दा है: तालिका पर क्लस्टरिंग कुंजी आपके टेबल पर प्रत्येक और गैर-क्लस्टर इंडेक्स पर प्रत्येक प्रविष्टि में भी जोड़ा जाएगा - इस प्रकार आप वास्तव में यह सुनिश्चित करना चाहते हैं कि यह छोटा हो मुमकिन। आम तौर पर, INT तालिकाओं के विशाल बहुमत के लिए 2+ अरब पंक्तियों के साथ पर्याप्त होना चाहिए - और क्लस्टरिंग कुंजी के रूप में GUID की तुलना में, आप डिस्क पर और सर्वर मेमोरी में सैकड़ों मेगाबाइट स्टोरेज को बचा सकते हैं।

त्वरित गणना - प्राथमिक और क्लस्टरिंग कुंजी के रूप में INT बनाम GUID का उपयोग कर:

  • 1'000'000 पंक्तियों (3.8 एमबी बनाम 15.26 एमबी)
  • 6 nonclustered अनुक्रमणिका के साथ बेस तालिका (22.89 एमबी बनाम 91.55 एमबी)

कुल: 25 एमबी बनाम 106 एमबी - और कि बस एक ही मेज पर है!

विचार के लिए कुछ और खाना - Kimberly Tripp द्वारा उत्कृष्ट सामग्री - इसे पढ़ें, इसे फिर से पढ़ें, इसे पचाना! यह वास्तव में एसक्यूएल सर्वर अनुक्रमण सुसमाचार है।

जब तक आप एक बहुत अच्छे कारण के है, मैं लगभग हर "वास्तविक" डेटा तालिका के लिए एक INT IDENTITY उपयोग करने के लिए लोगों का तर्क था उनकी प्राथमिक कुंजी के लिए डिफ़ॉल्ट के रूप में - यह अद्वितीय है, यह स्थिर है (कभी नहीं बदलता), यह नरक है ओउ, यह हमेशा बढ़ रहा है - सभी अच्छी संपत्ति कि आप अपने SQL सर्वर टेबल के तेज़ और विश्वसनीय प्रदर्शन के लिए क्लस्टरिंग कुंजी में रखना चाहते हैं!

यदि आपके पास कुछ "प्राकृतिक" कुंजी मान है जिसमें उन सभी गुण भी हैं, तो आप सरोगेट कुंजी के बजाय इसका भी उपयोग कर सकते हैं। लेकिन दो अधिकतम की चर-लंबाई तार। 20 वर्ण प्रत्येक मेरी आवश्यकताओं में उन आवश्यकताओं को पूरा नहीं करते हैं।

1

GUID बड़े हैं लेकिन हर जगह अद्वितीय होने का लाभ है: यह तालिका या वह, यह सर्वर या यदि आपके पास GUID है तो बाकी सब कुछ जानकार है। यदि यह आपके लिए उपयोगी है, तो बढ़िया है, लेकिन आप इसके लिए ओवरहेड में भुगतान करेंगे, और भुगतान करना जारी रखेंगे, भुगतान करेंगे और भुगतान करेंगे ....

सामग्री कोड केवल छोटे अपरिवर्तनीय कुंजी के लिए काम करते हैं, जैसे रंग या वर्गीकरण कोड और पसंद है। आर हमेशा लाल होगा, जी हरा होगा, यह एक बाइट इत्यादि है।

सामग्री कॉलम होने पर पहचान कॉलम स्वयं में आते हैं, या प्राकृतिक कुंजी कई सामग्री कोडों से बना है, या प्राकृतिक कुंजी पहले से ही अन्य पहचान कॉलम और/या GUID, या प्राकृतिक से बना है कुंजी mutable है। हां आप एक GUID का उपयोग कर सकते हैं लेकिन एक पूर्णांक कॉलम सभी संबंधों में अधिक कुशल है।

एसक्यूएल 2012 में उपलब्ध एक और विकल्प अनुक्रम, डेटाबेस-स्तर पहचान कॉलम की तरह है। यह GUIDs और पहचान कॉलम के बीच एक अच्छा आधा घर है, इस अर्थ में कि कई तालिकाओं में एक अनुक्रम का उपयोग किया जा सकता है, ताकि किसी दिए गए मान से, केवल पंक्ति ही जानकार न हो, लेकिन तालिका भी - लेकिन आप अभी भी उपयोग कर सकते हैं एक आईएनटी या बिगिनट (या स्मॉलिंट!) यदि आपको लगता है कि यह आपके डेटा के लिए पर्याप्त होगा। कुछ उद्देश्यों के लिए यह निफ्टी है, ओओ दुनिया में ऑब्जेक्ट आईडी की तरह।

ध्यान रखें कि कई या हल्के वजन वाले ओआरएम टेबल की अपेक्षा करते हैं कि एक कॉलम प्राथमिक कुंजी हो, अधिमानतः एक पूर्णांक कॉलम हो, और किसी भी चीज़ के साथ अच्छी तरह से खेल न सके, लेकिन एक पहचान पहचान पीके।

2

एक चीज जिसे आपको अपनी टेबल डिज़ाइन करने पर विचार करने की आवश्यकता होगी, यदि आपको अपने डेटा को एक स्थान से दूसरे स्थान पर दोहराने, शेड करने या अन्यथा स्थानांतरित करने की आवश्यकता होगी। हो सकता है कि डेटा अन्य अनुप्रयोगों द्वारा उत्पन्न किया जा रहा है और जिसे आपके साथ सिंक में रखा जाना चाहिए। इसका एक उदाहरण एक मोबाइल ऐप होगा जो डेटा बनाता है और फिर उसे सर्वर से सिंक करता है। अगर ऐसा कुछ भी सच है या हो सकता है तो UNIQUEIDENTIFIER आपकी प्राथमिक कुंजी के लिए उपयोग करने के लिए अच्छी पसंद का उपयोग किया जाएगा।

UNIQUEIDENTIFIER डेटा प्रकार क्लस्टर्ड इंडेक्स के रूप में उपयोग किए जाने पर प्रदर्शन के लिए भयानक है। हां, आप newsequentialid() का उपयोग कर सकते हैं, लेकिन यह अन्य डिवाइसों पर मान उत्पन्न होने पर आपकी सहायता नहीं करता है। आम सहमति यह प्रतीत होती है कि क्लस्टर इंडेक्स का अनुक्रमिक और संकीर्ण डेटा प्रकार जैसे INT या BIGINT के साथ सबसे अच्छा उपयोग किया जाता है।

आप संग्रहण स्थान मुद्दों से संबंधित नहीं रहे हैं तो आप दोनों एक IDENTITYक्लस्टर कुंजी और UNIQUEIDENTIFIER प्राथमिक कुंजी के संयोजन का उपयोग करने की कोशिश हो सकती है। क्लस्टर कुंजीIDENTITY कॉलम बनाएं और इसे अपने क्लस्टर इंडेक्स (लेकिन प्राथमिक कुंजी के रूप में नहीं) के लिए उपयोग करें। सम्मिलन अभी भी अनुक्रमिक रूप से किए जाएंगे और यह एक संकीर्ण डेटा प्रकार होने की इच्छा को पूरा करता है। अब आप अपनी प्राथमिक कुंजी के रूप में UNIQUEIDENTIFIER का उपयोग कर सकते हैं। जब आपको आवश्यकता हो तो यह आपको अपने डेटा को स्थानांतरित करने, दोहराने और/या shard करने की अनुमति देगा।

क्लस्टर कुंजी कोई अन्य अन्य अपने आवेषण अनुक्रमिक रखने के लिए की तुलना में और होना करने के लिए क्या अन्य सभी गैर-क्लस्टर अनुक्रमित जब किसी क्वेरी के लिए डेटा को देख को इंगित उद्देश्य है। क्लस्टर कुंजी पूरी तरह से फेंक दिया जाता है और जब डेटा को स्थानांतरित किया जाता है, दोहराया जाता है, और/या sharded किया जाता है, तो विशिष्टता UNIQUEIDENTIFIER प्राथमिक कुंजी द्वारा संभाली जाती है।

यहां एक अच्छा आलेख है जो दर्शाता है कि आपके क्लस्टर इंडेक्स के लिए एक पहचान बनाम पहचानकर्ता का उपयोग करते समय आंतरिक रूप से क्या होता है।

4

पहचान

पेशेवरों

  1. छोटे भंडारण पदचिह्न;
  2. इष्टतम जॉइन/इंडेक्स प्रदर्शन (उदाहरण के लिए समय सीमा प्रश्नों के लिए, हाल ही में डाली गई अधिकांश पंक्तियां पृष्ठों की एक सीमित संख्या पर होंगी);
  3. डेटा वेयरहाउसिंग के लिए अत्यधिक उपयोगी;
  4. ओएस के मूल डेटा प्रकार, और सभी भाषाओं में काम करने में आसान;
  5. डीबग करने में आसान;
  6. स्वचालित रूप से जेनरेट किया गया (असाइन किए गए के बजाय SCOPE_IDENTITY() के माध्यम से पुनर्प्राप्त);
  7. अपडेट करने योग्य नहीं है (हालांकि कुछ इसे एक नुकसान, अजीब रूप से पर्याप्त मानते हैं)।

कान्स

  1. अनुप्रयोगों द्वारा मज़बूती से नहीं किया जा सकता "भविष्यवाणी" - केवल सम्मिलित करने के बाद पुनः प्राप्त किया जा सकता है;
  2. बहु-सर्वर वातावरण में एक जटिल योजना की आवश्यकता है, क्योंकि प्रतिकृति के कुछ रूपों में पहचान की अनुमति नहीं है;
  3. डुप्लीकेट किया जा सकता है, अगर स्पष्ट रूप से प्राथमिक कुंजी पर सेट नहीं किया गया है।
  4. यदि तालिका पर क्लस्टर किए गए इंडेक्स का हिस्सा है, तो यह एक सम्मिलित हॉट-स्पॉट बना सकता है;
  5. स्वामित्व और सीधे पोर्टेबल नहीं;
  6. केवल एक ही तालिका में अद्वितीय;
  7. अंतराल हो सकता है (उदाहरण के लिए एक लुढ़का हुआ बैक लेनदेन के साथ), और इससे चिकन छोटे-शैली वाले अलार्म हो सकते हैं।

GUID

पेशेवरों

  1. के बाद से वे कर रहे हैं {कम या ज्यादा} अद्वितीय, कई टेबल/डेटाबेस/उदाहरणों/सर्वर/नेटवर्क/डेटा केंद्रों होने की गारंटी कर सकते हैं उन्हें स्वतंत्र रूप से उत्पन्न करें, फिर बिना संघर्ष के विलय करें;

  2. प्रतिकृति के कुछ रूपों के लिए आवश्यक है;

  3. डेटाबेस के बाहर उत्पन्न किया जा सकता है (उदाहरण के लिए एक आवेदन द्वारा);
  4. वितरित मूल्य हॉट-स्पॉट को रोकते हैं (जब तक आप इस कॉलम को क्लस्टर नहीं करते हैं, जिससे असामान्य रूप से उच्च विखंडन हो सकता है)।

कान्स

  1. व्यापक डेटाप्रकार सूचकांक प्रदर्शन में गिरावट की ओर जाता है, और भंडारण आवश्यकताओं में वृद्धि हुई है (यदि क्लस्टर, प्रत्येक लगभग 'गंदा' एक अलग पेज की गारंटी डालें);
  2. डीबग करने के लिए बोझिल (जहां userid = {BAE7DF4-DDF-3RG-5TY3E3RF456AS10});
  3. अद्यतन करने योग्य (परिवर्तनों को प्रचारित करने की आवश्यकता है, या गतिविधि को पूरी तरह से रोकें);
  4. कुछ वातावरण में समय-समय पर रोलबैक के प्रति संवेदनशील (उदा। डेलाइट बचत समय रोलबैक);
  5. ग्रुप बाय और अन्य सेट ऑपरेशंस को अक्सर CAST/CONVERT की आवश्यकता होती है;
  6. सभी भाषाओं और वातावरण सीधे GUID का समर्थन नहीं करते हैं;
  7. उत्पन्न होने वाले मान को निर्धारित करने के लिए SCOPE_GUID() जैसे कोई विवरण नहीं है, उदा। NEWID द्वारा();
संबंधित मुद्दे

 संबंधित मुद्दे