फ़िल्टर्ड यूनिक इंडेक्स एक शानदार विचार है, लेकिन इसका एक मामूली नुकसान है - कोई फर्क नहीं पड़ता कि आप WHERE identity_column > <current value>
स्थिति का उपयोग करते हैं या WHERE identity_column NOT IN (<list of ids for duplicate values here>)
।
पहले दृष्टिकोण के साथ, आप अभी भी भविष्य में डुप्लिकेट डेटा, मौजूदा (अब) डेटा के डुप्लिकेट को सम्मिलित करने में सक्षम होंगे। उदाहरण के लिए, यदि आपके पास (यहां तक कि केवल एक) पंक्ति है CompanyName = 'Software Inc.'
, तो सूचकांक आपके कंपनी के नाम के साथ एक और पंक्ति के सम्मिलन को मना नहीं करेगा। यदि आप दो बार कोशिश करते हैं तो यह केवल इसे मना करेगा।
दूसरे दृष्टिकोण के साथ एक सुधार है, ऊपर काम नहीं करेगा (जो अच्छा है।) हालांकि, आप अभी भी अधिक डुप्लिकेट या मौजूदा डुप्लिकेट सम्मिलित कर पाएंगे। उदाहरण के लिए, यदि आपके पास अब (दो या अधिक) पंक्तियाँ हैं CompanyName = 'DoubleData Co.'
, तो सूचकांक आपके कंपनी नाम के साथ एक और पंक्ति के सम्मिलन की मनाही नहीं करेगा। यदि आप दो बार कोशिश करते हैं तो यह केवल इसे मना करेगा।
(अपडेट) इसे सही किया जा सकता है यदि प्रत्येक डुप्लिकेट नाम के लिए, आप अपवर्जन सूची एक आईडी से बाहर रहते हैं। यदि, उपरोक्त उदाहरण की तरह, डुप्लिकेट CompanyName = DoubleData Co.
और आईडी के साथ 4 पंक्तियाँ हैं 4,6,8,9
, तो बहिष्करण सूची में इन ID में से केवल 3 होनी चाहिए।
दूसरे दृष्टिकोण के साथ एक और नुकसान बोझिल स्थिति है (कितना बोझिल इस बात पर निर्भर करता है कि पहली बार में कितने डुप्लिकेट हैं), चूंकि SQL-Server फ़िल्टर किए गए अनुक्रमित NOT IN
के WHERE
हिस्से में ऑपरेटर का समर्थन नहीं करता है। एसक्यूएल-फिडल देखें । इसके बजाय WHERE (CompanyID NOT IN (3,7,4,6,8,9))
, आपको कुछ ऐसा करना होगा जैसे कि WHERE (CompanyID <> 3 AND CompanyID <> 7 AND CompanyID <> 4 AND CompanyID <> 6 AND CompanyID <> 8 AND CompanyID <> 9)
मुझे यकीन नहीं है कि ऐसी स्थिति के साथ दक्षता के निहितार्थ हैं, अगर आपके पास सैकड़ों डुप्लिकेट नाम हैं।
एक अन्य समाधान (@Alex Kuznetsov के समान) एक और कॉलम जोड़ने के लिए है, इसे रैंक संख्याओं के साथ पॉप्युलेट करें और इस कॉलम सहित एक अद्वितीय सूचकांक जोड़ें:
ALTER TABLE Company
ADD Rn TINYINT DEFAULT 1;
UPDATE x
SET Rn = Rnk
FROM
( SELECT
CompanyID,
Rn,
Rnk = ROW_NUMBER() OVER (PARTITION BY CompanyName
ORDER BY CompanyID)
FROM Company
) x ;
CREATE UNIQUE INDEX CompanyName_UQ
ON Company (CompanyName, Rn) ;
फिर, डुप्लिकेट नाम के साथ एक पंक्ति सम्मिलित करना DEFAULT 1
संपत्ति और अद्वितीय सूचकांक के कारण विफल हो जाएगा । यह अभी भी 100% मूर्ख नहीं है (जबकि एलेक्स है)। यदि विवरण Rn
में स्पष्ट रूप से सेट किया गया INSERT
है या Rn
मान दुर्भावनापूर्ण रूप से अपडेट किए गए हैं , तो डुप्लिकेट अभी भी खिसक जाएगा ।
एसक्यूएल-फिडल -2