मुझे एक अनन्य सूचकांक के बजाय एक अद्वितीय बाधा का उपयोग कब करना चाहिए?


194

जब मैं एक कॉलम को अलग मान देना चाहता हूं, तो मैं या तो एक बाधा का उपयोग कर सकता हूं

create table t1(
id int primary key,
code varchar(10) unique NULL
);
go

या मैं एक अद्वितीय सूचकांक का उपयोग कर सकता हूं

create table t2(
id int primary key,
code varchar(10) NULL
);
go

create unique index I_t2 on t2(code);

अद्वितीय बाधाओं के साथ कॉलम अद्वितीय अनुक्रमितों के लिए अच्छे उम्मीदवार प्रतीत होते हैं।

क्या अद्वितीय बाधाओं का उपयोग करने और इसके बजाय अद्वितीय अनुक्रमित का उपयोग न करने के लिए कोई ज्ञात कारण हैं?


9
क्या वे वास्तव में अलग हैं? मुझे लगता है कि कुछ डेटाबेस में जैसे postgresql, एक अद्वितीय बाधा बस एक अद्वितीय सूचकांक बनाता है। मैं जवाब नहीं दे रहा हूं क्योंकि मुझे sql सर्वर के बारे में कुछ नहीं पता है।
xenoterracide

6
Postgresql में, आप एक अद्वितीय सूचकांक में अभिव्यक्ति का उपयोग कर सकते हैं लेकिन एक अद्वितीय बाधा में नहीं।
नील मैकगिगन

1
MS SQL पर, वे समान हैं। एक ही डेटा के साथ दो तालिकाओं को बनाने का प्रयास करें, एक अद्वितीय बाधा के साथ, दूसरा एक अद्वितीय सूचकांक के साथ। वे इंडेक्स स्पेस की समान मात्रा का उपयोग करेंगे, और दोनों अद्वितीय इंडेक्स के खिलाफ तलाश करने में सक्षम होंगे जो (व्यवहार में) दोनों तरह से बनाया गया है।
जॉन ऑफ ऑल ट्रेड्स

जवाबों:


153

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

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

यदि आप एक सूचकांक के रूप में सूचकांक का उपयोग करने की योजना बना रहे हैं (यानी आपका कोड त्वरित होने के लिए उस क्षेत्र पर खोज / छँटाई / छानने पर भरोसा कर सकता है) तो मैं स्पष्ट रूप से एक अद्वितीय सूचकांक का उपयोग करूंगा (और स्रोत पर टिप्पणी कर सकता हूं) स्पष्ट - इस तरह यदि आप (या कुछ अन्य कोडर) के बाद के संशोधन में विशिष्टता की आवश्यकता को बदल दिया जाता है, तो यह सुनिश्चित करने के लिए पता चल जाएगा कि एक अद्वितीय के स्थान पर एक गैर-अद्वितीय सूचकांक रखा गया है (बस एक अद्वितीय बाधा को हटा देगा) सूचकांक पूरी तरह से)। इंडेक्स हिंट (इंडेक्स (ix_index_name) के साथ) में भी एक विशिष्ट इंडेक्स का नाम दिया जा सकता है, जो मुझे नहीं लगता कि अनूठेपन को प्रबंधित करने के लिए पर्दे के पीछे बनाए गए इंडेक्स के लिए मामला है क्योंकि आपको इसका नाम पता होने की संभावना नहीं है।

इसी तरह यदि आपको केवल खोज करने या छँटने के लिए उपयोग किए जाने वाले क्षेत्र की आवश्यकता के बजाय एक व्यावसायिक नियम के रूप में विशिष्टता लागू करने की आवश्यकता है, तो मैं बाधा का उपयोग करूँगा, फिर से इच्छित उपयोग को और स्पष्ट करने के लिए जब कोई और आपकी तालिका परिभाषा को देखता है।

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


1
मैं "डेटाबेस पर्याप्त उज्ज्वल नहीं होगा" के बारे में सोच रहा हूं? क्या यह सभी RDBMS के लिए सही है? क्या यह SQL-Standard द्वारा अनिवार्य है? और यहां तक ​​कि अगर यह है (और मुझे आश्चर्य होगा कि यह क्यों होना चाहिए), तो क्या सभी कार्यान्वयन इसे इस तरह से लागू करते हैं? या: क्यों एक DB "उज्ज्वल" पर्याप्त नहीं हो सकता है?
जुरगेन ए। इरहार्ड

4
@jae: एक DBMS निश्चित रूप से काफी उज्ज्वल हो सकता है, लेकिन आपको यह देखने के लिए प्रत्येक DBMS के साथ जांचना होगा कि क्या यह है। यदि आप MSSQL को दो समान इंडेक्स बनाने के लिए कहते हैं, तो यह दो नामों से संदर्भित एक के बजाय दो बना देगा (कम से कम यह पिछली बार था जब मैंने इस तरह की स्थिति देखी थी (मेरे हिस्से में कॉपी + पेस्ट त्रुटि के कारण),) इसलिए मुझे लगता है कि यदि कोई एक बाधा के कारण मौजूद है, तो यही स्थिति है।
डेविड स्पिललेट 12

3
+1 @ डेविड स्पिलेट मुझे लगता है कि मूल रूप से डीबीएमएस आपको मानता है कि आप क्या कर रहे हैं; अगर आपको ऐसा लगता है कि एक ही सूचकांक को दो बार बनाना है, तो यह उस पर सवाल नहीं करता है।
एंड्रयू बार्बर

2
बहुत ही सुखद। क्या आपको पता है कि यह व्यवहार MySQL और Apache Derby में भी है?
corsiKa

5
आप एक बाधा का नाम दे सकते हैं और इसे एक सूचकांक संकेत में उपयोग कर सकते हैंCREATE TABLE #T(X INT CONSTRAINT PK PRIMARY KEY NONCLUSTERED);SELECT * FROM #T WITH(INDEX(PK)) WHERE X = 1। अनुक्रमणिका अधिक लचीली हो सकती है, हालांकि उस अवरोध में सभी अनुक्रमणिका विकल्पों का समर्थन नहीं करते हैं जैसे कि INCLUDEडी कॉलम या फ़िल्टर किए गए अनुक्रमणिका।
मार्टिन स्मिथ

101

अन्य उत्तरों में अंकों के अलावा, यहाँ दोनों के बीच कुछ महत्वपूर्ण अंतर हैं।

नोट: त्रुटि संदेश SQL सर्वर 2012 से हैं।

त्रुटियाँ

एक अद्वितीय बाधा का उल्लंघन 2627 त्रुटि देता है।

Msg 2627, Level 14, State 1, Line 1
Violation of UNIQUE KEY constraint 'P1U_pk'. Cannot insert duplicate key in object 'dbo.P1U'. The duplicate key value is (1).
The statement has been terminated.

एक अद्वितीय सूचकांक रिटर्न का उल्लंघन त्रुटि 2601।

Msg 2601, Level 14, State 1, Line 1
Cannot insert duplicate key row in object 'dbo.P1' with unique index 'P1_u'. The duplicate key value is (1).
The statement has been terminated.

अक्षम करना

एक अद्वितीय बाधा को अक्षम नहीं किया जा सकता है।

Msg 11415, Level 16, State 1, Line 1
Object 'P1U_pk' cannot be disabled or enabled. This action applies only to foreign key and check constraints.
Msg 4916, Level 16, State 0, Line 1
Could not enable or disable the constraint. See previous errors.

लेकिन प्राथमिक कुंजी बाधा या एक अद्वितीय बाधा के पीछे अद्वितीय सूचकांक को किसी भी अद्वितीय सूचकांक के रूप में अक्षम किया जा सकता है। हैट-टिप ब्रेन २००।

ALTER INDEX P1_u ON dbo.P1 DISABLE ;

सामान्य चेतावनी पर ध्यान दें कि क्लस्टर किए गए इंडेक्स को अक्षम करने से डेटा अप्राप्य हो जाता है।

विकल्प

अद्वितीय बाधाएँ अनुक्रमण विकल्पों को पसंद करती हैं FILLFACTORऔर जैसे IGNORE_DUP_KEYकि, SQL सर्वर के हर संस्करण के लिए ऐसा नहीं है।

कॉलम शामिल हैं

गैर-अनुक्रमित सूचकांक में गैर-अनुक्रमित कॉलम (एक कवर इंडेक्स कहा जा सकता है, यह एक प्रमुख प्रदर्शन वृद्धि है) शामिल हो सकता है। प्राथमिक कुंजी और अद्वितीय बाधाओं के पीछे के सूचकांक में कॉलम शामिल नहीं हो सकते। हैट-टिप @ypercube।

छनन

एक अद्वितीय बाधा को फ़िल्टर नहीं किया जा सकता है।

एक अद्वितीय सूचकांक फ़िल्टर किया जा सकता है।

CREATE UNIQUE NONCLUSTERED INDEX Students6_DrivesLicence_u 
ON dbo.Students6( DriversLicenceNo ) WHERE DriversLicenceNo is not null ;

विदेशी कुंजी बाधाओं

एक विदेशी कुंजी बाधा एक फ़िल्टर किए गए अनन्य इंडेक्स का संदर्भ नहीं दे सकती है, हालांकि यह एक गैर-फ़िल्टर किए गए अनन्य इंडेक्स को संदर्भित कर सकता है (मुझे लगता है कि यह SQL सर्वर 2005 में जोड़ा गया था)।

नामकरण

बाधा बनाते समय, एक बाधा नाम निर्दिष्ट करना वैकल्पिक है (सभी पांच प्रकार की बाधाओं के लिए)। यदि आप एक नाम निर्दिष्ट नहीं करते हैं तो MSSQL आपके लिए एक उत्पन्न करेगा।

CREATE TABLE dbo.T1 (
    TID int not null PRIMARY KEY
) ;
GO
CREATE TABLE dbo.T2 (
    TID int not null CONSTRAINT T2_pk PRIMARY KEY
) ;

इंडेक्स बनाते समय, आपको एक नाम निर्दिष्ट करना होगा।

हैट-टिप @ आई-वन।

लिंक

http://technet.microsoft.com/en-us/library/aa224827(v=SQL.80).aspx

http://technet.microsoft.com/en-us/library/ms177456.aspx


एक अद्वितीय बाधा को एक सूचकांक के रूप में उसी विधि के माध्यम से अक्षम और सक्षम किया जा सकता है: uconstraint DISABLE पर ALTER INDEX tbl, ALTER INDEX tbl ON uconstraint REBUILD
Brain2000

धन्यवाद @ ब्रेन २०० संयोग से, मैंने इस टिप्पणी को पढ़ने से ठीक पहले आज सुबह अनुक्रमित को अक्षम करने पर एक खंड सिखाया।
ग्रीनस्टोन वाकर

10

एक आधिकारिक स्रोत के रूप में MSDN को उद्धृत करने के लिए:

UNIQUE बाधा बनाने और एक अद्वितीय सूचकांक बनाने के बीच कोई महत्वपूर्ण अंतर नहीं हैं जो एक बाधा से स्वतंत्र है । डेटा सत्यापन एक ही तरीके से होता है, और क्वेरी ऑप्टिमाइज़र एक बाधा या मैन्युअल रूप से निर्मित एक अद्वितीय सूचकांक के बीच अंतर नहीं करता है। हालांकि, कॉलम पर एक UNIQUE बाधा बनाने से सूचकांक का उद्देश्य स्पष्ट हो जाता है ... अधिक जानकारी यहां

तथा...

डेटाबेस इंजन स्वचालित रूप से UNIQUE बाधा की विशिष्टता आवश्यकता को लागू करने के लिए एक अद्वितीय सूचकांक बनाता है। इसलिए, यदि डुप्लिकेट पंक्ति सम्मिलित करने का प्रयास किया जाता है, तो डेटाबेस इंजन एक त्रुटि संदेश देता है जो बताता है कि UNIQUE की बाधा का उल्लंघन किया गया है और पंक्ति को तालिका में नहीं जोड़ा गया है। जब तक एक क्लस्टर सूचकांक स्पष्ट रूप से निर्दिष्ट नहीं किया जाता है, तब तक एक अद्वितीय, गैर-अनुक्रमित सूचकांक डिफ़ॉल्ट रूप से UNIQUE बाधा को लागू करने के लिए बनाया जाता है ... अधिक जानकारी यहाँ

अन्य में: https://technet.microsoft.com/en-us/library/aa224827%28v=sql.80%29.aspx


6

एक अद्वितीय बाधा और एक अद्वितीय सूचकांक के बीच प्रमुख अंतर यह है कि एक अन्य मेज पर एक विदेशी कुंजी बाधा स्तंभों को संदर्भित कर सकती है जो एक अद्वितीय बाधा बनाते हैं। यह अद्वितीय अनुक्रमितों के लिए सही नहीं है। इसके अलावा, अद्वितीय बाधाओं को एएनएसआई मानक के हिस्से के रूप में परिभाषित किया गया है, जबकि सूचकांक नहीं हैं। अंत में, तार्किक डेटाबेस डिजाइन (जो अलग-अलग डीबी इंजनों द्वारा अलग-अलग लागू किया जा सकता है) के दायरे में रहने के लिए माना जाने वाला अद्वितीय अवरोध है जबकि सूचकांक भौतिक पहलू है। इसलिए, अद्वितीय बाधा अधिक घोषित है। मैं लगभग सभी मामलों में अद्वितीय बाधा चाहता हूं।


8
-1 SQL सर्वर में निम्नलिखित गलत है: "किसी अन्य तालिका पर एक विदेशी कुंजी बाधा स्तंभों को संदर्भित कर सकती है जो एक अद्वितीय बाधा बनाते हैं। यह अद्वितीय अनुक्रमित के लिए सही नहीं है"। SQL सर्वर में, हम FK बाधाओं को अद्वितीय अनुक्रमित में संदर्भित कर सकते हैं।
एके

4
एक अद्वितीय सूचकांक को संदर्भित करने के लिए एक विदेशी कुंजी बाधा की क्षमता थी, मुझे लगता है, SQL Server 2005 में जोड़ा गया है। बीओएल में कुछ पृष्ठों सहित कई स्रोतों, परिवर्तनों को प्रतिबिंबित करने के लिए अद्यतन नहीं किया गया है, इसलिए मुझे नहीं लगता कि दिमित्री का उत्तर चढ़ाव के पात्र हैं। उनका बाकी जवाब हाजिर है - अड़चनें एएनएसआई-मानक हैं, सूचकांक नहीं हैं।
ग्रीनस्टोन वाकर

इन के बावजूद मेरी पसंदीदा उत्तर downvotes।
चमत्कार 173

मानक महत्वपूर्ण हैं। यदि एएनएसआई मानकों को एक अद्वितीय बाधा का उपयोग करना है, तो हमें एक अद्वितीय बाधा का उपयोग करना चाहिए।
रिहायस

1

ओरेकल में एक बड़ा अंतर यह है कि आप एक फ़ंक्शन-यूनिक इंडेक्स बना सकते हैं, जो अद्वितीय बाधाओं के साथ उल्लेखनीय नहीं है:

उदाहरण के लिए

create unique index ux_test on my_table (case when amount != 0 then fk_xyz end);

तो fk_xyzकेवल रिकॉर्ड के लिए अद्वितीय है जो है amount != 0


7
SQL सर्वर (प्रश्न का टैग) में, अनुक्रमित को एक WHEREखंड के साथ फ़िल्टर किया जा सकता है । CREATE UNIQUE NONCLUSTERED INDEX P4_U ON DBO.P4 ( PID ) WHERE TXT = 'qwert' ;
ग्रीनस्टोन वाकर

-3

UNIQUE इंडेक्स पर UNIQUE बाधा को प्राथमिकता दी जाती है। जब बाधा अद्वितीय नहीं होती है तो आपको एक नियमित या गैर अद्वितीय सूचकांक का उपयोग करने की आवश्यकता होती है। बाधा भी एक अन्य प्रकार का सूचकांक है। इंडेक्स का उपयोग तेज पहुंच के लिए किया जाता है।

यूनिक इंडेक्स में क्लॉस हो सकते हैं। उदाहरण के लिए, आप हर साल दिनांक कॉलम के आधार पर अनुक्रमित बना सकते हैं

WHERE Sale_Date BETWEEN '2012-01-01' AND '2012-12-31'

यह देखने के लिए अच्छा है कि खंड का उल्लेख कहाँ किया गया है।
क्रुकसेक

3
"बाधा भी एक अन्य प्रकार का सूचकांक है।" नहीं, यह नहीं है। कुछ अड़चनें (पीके, यूक्यू, एफके) को अक्सर इंडेक्स के उपयोग द्वारा लागू किया जा सकता है। हालांकि जरूरी नहीं कि और सभी DBMS में डिफ़ॉल्ट रूप से हो।
ypercube y
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.