Σε ένα προϊόν σαν τον SQL Server που είναι περίπλοκο και περιέχει αρκετή περιπτωσιολογία είναι φυσικό όσοι ασχολούνται περιστασιακά ή επιφανειακά μαζί του να μπερδεύουν κάποια πράγματα και να βγάζουν λάθος συμπεράσματα. Σε αυτή την περίπτωση καλό θα είναι να μπαίνουν όλα σε μια σειρά.
Πριν μερικές μέρες βρέθηκα σε μια συζήτηση στην οποία ένας συνάδελφος ανέφερε ότι από τον SQL Server 2008 και μετά ο SQL Server επιτρέπει σε ένα unique index να έχει περισσότερα από ένα NULL key values. Εντυπωσιάστηκα και ταυτόχρονα αναρωτήθηκα πως μου ξέφυγε αυτό. Φυσικά ρώτησα τον συνάδελφο για το τι ακριβώς εννοούσε ώστε να αποκλείσω οποιαδήποτε παρανόηση. Ο συνάδελφος μου είπε ότι ακριβώς ανέφερα και παραπάνω, φυσικά τον ρώτησα πως το κάνει αυτό και μου απάντησε με χαρά ότι το κάνει με filter index.
Οκ! Ας βάλουμε λίγο τα πράγματα σε μια σειρά.
Από τα BOL και συγκεκριμένα από το topic για το πώς μπορεί κάποιος να δημιουργήσει ένα Unique Index (http://msdn.microsoft.com/en-us/library/ms187019.aspx) αντιγράφω την χαρακτηριστική φράση
"A unique index guarantees that the index key contains no duplicate values and therefore every row in the table is in some way unique", να συμπληρώσω ότι αυτό αφορά και το NULL και έτσι μπορείς να έχεις μόνο μια εγγραφή που να έχει αυτή την τιμή στο πεδίο που έχεις σαν unique index.
Από τα BOL και συγκεκριμένα από το topic για τους Filtered Indexes (http://msdn.microsoft.com/en-us/library/cc280372.aspx) αντιγράφω
"A filtered index is an optimized nonclustered index especially suited to cover queries that select from a well-defined subset of data. It uses a filter predicate to index a portion of rows in the table. A well-designed filtered index can improve query performance as well as reduce index maintenance and storage costs compared with full-table indexes"
Φυσικά και μπορείς να έχεις filtered unique index στον οποίο να μην συμπεριλαμβάνονται NULL values και έτσι να μπορείς να ξεπερνάς αυτό που θεωρούσες σαν εμπόδιο στον unique index, αλλά είναι δύο διαφορετικά πράγματα και ανάλογα με την περίπτωση μπορείς να επιλέξεις τι θα χρησιμοποιήσεις.
Πρώτα από όλα θα πρέπει να απαντήσεις στο ερώτημα γιατί θέλεις την μοναδικότητα και αφού ζητάς αυτή γιατί επιτρέπεις να έχεις περισσότερα από ένα NULL key values, που πάει η μοναδικότητα τότε;
Από την άλλη θα πρέπει να καταλάβεις ότι όταν θα ψάχνεις να βρεις αυτά που έχουν null value δεν θα χρησιμοποιηθεί ο filter index που έχεις φτιάξει.
Άρα μιλάμε για δύο διαφορετικά features που σε καμία περίπτωση το ένα δεν ακυρώνει το άλλο ούτε συμπληρώνει το ένα το άλλο. Η επιχειρηματική σου λογική είναι αυτή που θα σε οδηγήσει στο τι θα χρησιμοποιήσεις και φυσικά οι παραδοχές που θα πρέπει να έχεις πάρει για το πώς θα διαβάζεις τα δεδομένα αυτά. Τέλος θα πρέπει να επισημάνω ότι αν βάλεις unique constraint αυτό ακολουθεί την λογική του unique index
Για όσους θέλουν αν πειραματιστούν ένα μικρό παράδειγμα.
create table N
(
id int
, col1 nvarchar(10) null
);
go
create unique nonclustered index UI_N_col1 on N(col1);
go
insert into N values (1,'antonis');
insert into N values (2,'mitsos');
insert into N values (3,null);
insert into N values (4,null); -- error
go
select * from N;
go
create table M
(
id int
, col1 nvarchar(10) null
);
go
create unique nonclustered index UI_M_col1 on M(col1)
where col1 is not null;
go
insert into N values (1,'antonis');
insert into N values (2,'mitsos');
insert into N values (3,null);
insert into N values (4,null);
go
select * from M;
go