Unique Indeksi i NULL vrednosti
Tuesday, 25.03.2008 – ZidarNa sajtu elitesecurity.org povremeno se pojave mozgalice – nesvakidašnji zadaci koje treba rešiti primenom SQL jezika. Jedna od prvih mozgalica bila je “Kako obezbediti jedinstvenost ako su dozvoljene NULL vrednosti u koloni”. Drugim rečima, ako vrednost nije NULL onda mora biti jedinstvena, a višestruke NULL vrednosti su dozvoljene. U nekim sistemima rešenje je trivijalno, jer se indeksi ignorisu NULL vrednosti . MS SQL to ne dozvoljava (iako recimo Access, takodje MS proizvod, to naprimer dozvoljava).
U verzijama MS SQL zaključno sa 2005 morali smo da pribegavamo trikovima. Triggeri, inedksirani view ili korisničke funkcija su korišćeni da se problem reši. MS SQL 2008 uvodi novinu – “filtered indexing”.
U Microsoft SQL Server 2008 problem se rešava elegantno i efikasno definsanjem objekta koji se zove “unique filtered index” koji moze da isključi NULL vrednosti. Neka je data tabela:
CREATE TABLE dbo.T1(col1 INT NULL, col2 VARCHAR(10) NOT NULL);
Pretpostavimo da želimo da obezbedimo jedinstvenost za podatke u koloni col1, a da dozvolimo visetruke NULL vrednosti. Dovoljno je da ovako definišete indeks:
CREATE UNIQUE NONCLUSTERED INDEX idx_col1_notnull ON dbo.T1(col1) WHERE col1 IS NOT NULL;
Da testiramo index, pokušajmo da unesemo sledeće:
INSERT INTO dbo.T1(col1, col2) VALUES(1, 'a'); INSERT INTO dbo.T1(col1, col2) VALUES(1, 'a');
Drugi INSERT naravno ne prolazi. Međutim, nećete imati problema da unesete više redova sa NULL u col1:
INSERT INTO dbo.T1(col1, col2) VALUES(NULL, 'a'); INSERT INTO dbo.T1(col1, col2) VALUES(NULL, 'a');
Negde sam pročitao i da su uvedeni i novi tipovi (podtipovi?) podataka – DateOnly i TimeOnly koji rade upravo to – čuvaj samo vreme i samo datumski deo. Cool, eh ….
🙂