SQL सर्वर 2008 और ऊपर
बस एक अद्वितीय सूचकांक फ़िल्टर करें:
CREATE UNIQUE NONCLUSTERED INDEX UQ_Party_SamAccountName
ON dbo.Party(SamAccountName)
WHERE SamAccountName IS NOT NULL;
लोअर संस्करणों में, एक भौतिकीकृत दृश्य अभी भी आवश्यक नहीं है
SQL Server 2005 और उससे पहले के लिए, आप इसे बिना किसी दृश्य के कर सकते हैं। मैंने सिर्फ एक अनोखी बाधा जोड़ी है जैसे आप मेरी एक टेबल के लिए पूछ रहे हैं। यह देखते हुए कि मैं कॉलम में विशिष्टता चाहता हूं SamAccountName
, लेकिन मैं कई NULLs की अनुमति देना चाहता हूं, मैंने एक भौतिककृत कॉलम के बजाय एक भौतिक कॉलम का उपयोग किया है:
ALTER TABLE dbo.Party ADD SamAccountNameUnique
AS (Coalesce(SamAccountName, Convert(varchar(11), PartyID)))
ALTER TABLE dbo.Party ADD CONSTRAINT UQ_Party_SamAccountName
UNIQUE (SamAccountNameUnique)
आपको बस गणना किए गए कॉलम में कुछ डालना होगा जो वास्तविक वांछित अद्वितीय कॉलम NULL होने पर पूरे तालिका में अद्वितीय की गारंटी होगी। इस स्थिति में, PartyID
एक पहचान स्तंभ है और संख्यात्मक होना कभी भी मेल नहीं खाएगा SamAccountName
, इसलिए इसने मेरे लिए काम किया। आप अपनी स्वयं की विधि आज़मा सकते हैं - सुनिश्चित करें कि आप अपने डेटा के डोमेन को समझ रहे हैं ताकि वास्तविक डेटा के साथ अंतरंगता की कोई संभावना न हो। यह इस तरह एक विभेदक चरित्र प्रस्तुत करने के रूप में सरल हो सकता है:
Coalesce('n' + SamAccountName, 'p' + Convert(varchar(11), PartyID))
भले ही PartyID
किसी दिन गैर-सांख्यिक बन गया हो और संयोग सेSamAccountName
, अब इससे कोई फर्क नहीं पड़ेगा।
ध्यान दें कि गणना किए गए कॉलम सहित एक सूचकांक की उपस्थिति से प्रत्येक अभिव्यक्ति का परिणाम तालिका में अन्य डेटा के साथ डिस्क पर सहेजने का कारण बनता है, जो अतिरिक्त डिस्क स्थान लेता है।
ध्यान दें कि यदि आप एक सूचकांक नहीं चाहते हैं, तो आप अभी भी सीपीयू को कीवर्ड जोड़कर डिस्क पर पूर्व-निर्धारित किया जा सकता है PERSISTED
कॉलम को एक्सप्रेशन के अंत में ।
SQL Server 2008 और ऊपर में, निश्चित रूप से फ़िल्टर किए गए समाधान का उपयोग करें यदि आप संभवतः कर सकते हैं!
विवाद
कृपया ध्यान दें कि कुछ डेटाबेस पेशेवर इसे "सरोगेट नल" के मामले के रूप में देखेंगे, जिसमें निश्चित रूप से समस्याएं हैं (ज्यादातर मुद्दों के कारण यह निर्धारित करने की कोशिश कर रहे हैं कि कुछ वास्तविक मूल्य है या लापता डेटा के लिए एक सरोगेट मूल्य है। , तो समस्याएँ भी हो सकती हैं; गैर-पूर्ण सरोगेट मूल्यों की संख्या के साथ पागल की तरह गुणा करना)।
हालांकि, मेरा मानना है कि यह मामला अलग है। मेरे द्वारा जोड़ा गया गणना किया गया कॉलम कभी भी कुछ भी निर्धारित करने के लिए उपयोग नहीं किया जाएगा। इसका खुद का कोई मतलब नहीं है, और ऐसी कोई जानकारी नहीं है जो पहले से ही अन्य, ठीक से परिभाषित स्तंभों में अलग से नहीं मिली है। इसका चयन या उपयोग कभी नहीं किया जाना चाहिए।
तो, मेरी कहानी यह है कि यह एक सरोगेट NULL नहीं है, और मैं इसे चिपका रहा हूँ! चूंकि हम वास्तव में किसी भी उद्देश्य के लिए गैर-पूर्ण मूल्य नहीं चाहते हैं, इसके अलावा छल करने के लिएUNIQUE
NULLs को अनदेखा करने के अनुक्रमणिका को छलने के , इसलिए हमारे उपयोग के मामले में सामान्य सरोगेट NULL निर्माण के साथ आने वाली समस्याओं में से कोई भी नहीं है।
सभी ने कहा, मुझे इसके बजाय अनुक्रमित दृश्य का उपयोग करने में कोई समस्या नहीं है - लेकिन यह कुछ मुद्दों को साथ लाता है जैसे कि उपयोग करने की आवश्यकता SCHEMABINDING
। अपने बेस टेबल में एक नया कॉलम जोड़ने का आनंद लें (आपको कम से कम सूचकांक को छोड़ना होगा, और फिर दृश्य को छोड़ना होगा या स्कीमा बाध्य नहीं होने के लिए दृश्य को बदलना होगा)। SQL सर्वर (2005) (बाद के संस्करण), (2000) में अनुक्रमित दृश्य बनाने के लिए आवश्यकताओं की पूरी (लंबी) सूची देखें ।
अपडेट करें
यदि आपका कॉलम संख्यात्मक है, तो यह सुनिश्चित करने की चुनौती हो सकती है कि अद्वितीय अवरोध का उपयोग करने Coalesce
से टकराव नहीं होता है। उस मामले में, कुछ विकल्प हैं। एक नकारात्मक संख्या का उपयोग करने के लिए हो सकता है, "सरोगेट NULLs" को केवल नकारात्मक सीमा में डालने के लिए, और "वास्तविक मान" केवल सकारात्मक सीमा में। वैकल्पिक रूप से, निम्न पैटर्न का उपयोग किया जा सकता है। तालिका में Issue
(जहां IssueID
है PRIMARY KEY
), वहाँ हो सकता है या नहीं भी हो सकता है TicketID
, लेकिन अगर वहाँ एक है, तो यह अद्वितीय होना चाहिए।
ALTER TABLE dbo.Issue ADD TicketUnique
AS (CASE WHEN TicketID IS NULL THEN IssueID END);
ALTER TABLE dbo.Issue ADD CONSTRAINT UQ_Issue_Ticket_AllowNull
UNIQUE (TicketID, TicketUnique);
यदि अंक 1 में टिकट 123 है, तो UNIQUE
अवरोध मूल्यों (123, NULL) पर होगा। यदि अंक 2 में कोई टिकट नहीं है, तो यह (NULL, 2) पर होगा। कुछ विचार से पता चलेगा कि इस बाधा को तालिका में किसी भी पंक्ति के लिए दोहराया नहीं जा सकता है, और फिर भी कई NULLs की अनुमति देता है।