Unique Indeksi i NULL vrednosti

Tuesday, 25.03.2008 – Zidar

Na 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 ….

🙂 

Post a Comment