it-swarm.dev

Kiedy powinienem zastosować unikalne ograniczenie zamiast unikalnego indeksu?

Gdy chcę, aby kolumna miała odrębne wartości, mogę użyć ograniczenia

create table t1(
id int primary key,
code varchar(10) unique NULL
);
go

lub mogę użyć unikalnego indeksu

create table t2(
id int primary key,
code varchar(10) NULL
);
go

create unique index I_t2 on t2(code);

Kolumny z unikalnymi ograniczeniami wydają się być dobrymi kandydatami na unikalne indeksy.

Czy istnieją znane powody, aby używać unikalnych ograniczeń i zamiast tego używać unikalnych indeksów?

210
bernd_k

Pod maską stosowane jest unikalne ograniczenie w taki sam sposób, jak unikalny indeks - indeks jest potrzebny, aby skutecznie spełnić wymóg wymuszenia ograniczenia. Nawet jeśli indeks został utworzony w wyniku ograniczenia UNIKALNEGO, planista zapytań może go używać tak jak każdego innego indeksu, jeśli uzna to za najlepszy sposób podejścia do danego zapytania.

Dlatego w przypadku bazy danych obsługującej obie funkcje wybór opcji często sprowadza się do preferowanego stylu i spójności.

Jeśli planujesz używać indeksu jako indeksu (tzn. Twój kod może polegać na szybkim wyszukiwaniu/sortowaniu/filtrowaniu tego pola), wolałbym wyraźnie użyć unikalnego indeksu (i skomentować źródło) niż ograniczenia, aby to zrobić jasne - w ten sposób, jeśli wymóg unikatowości zostanie zmieniony w późniejszej wersji aplikacji, którą ty (lub inny koder) będziesz wiedział, aby upewnić się, że indeks unikalny zostanie wstawiony zamiast unikalnego (usunięcie pojedynczego ograniczenia spowoduje usunięcie indeks całkowicie). Określony indeks można również nazwać wskazówką dotyczącą indeksu (tj. Z (INDEX (ix_index_name)), co nie wydaje mi się, że ma to miejsce w przypadku indeksu utworzonego za kulisami do zarządzania wyjątkowością, ponieważ prawdopodobnie nie znasz jego nazwy.

Podobnie, jeśli potrzebujesz tylko wymusić unikalność jako regułę biznesową, a nie pole, które trzeba przeszukać lub użyć do sortowania, użyłbym ograniczenia, ponownie, aby uczynić zamierzone użycie bardziej oczywistym, gdy ktoś inny patrzy na twoją definicję tabeli.

Zauważ, że jeśli użyjesz zarówno unikalnego ograniczenia, jak i unikalnego indeksu w tym samym polu, baza danych nie będzie wystarczająco jasna, aby zobaczyć duplikację, więc otrzymasz dwa indeksy, które zajmą dodatkowe miejsce i spowolnią wstawianie/aktualizację wierszy.

165
David Spillett

Oprócz punktów w innych odpowiedziach, oto kilka kluczowych różnic między nimi.

Uwaga: komunikaty o błędach pochodzą z SQL Server 2012.

Błędy

Naruszenie ograniczenia unikalnego zwraca błąd 2627.

Msg 2627, Level 14, State 1, Line 1
Violation of UNIQUE KEY constraint 'P1U_pk'. Cannot insert duplicate key in object 'dbo.P1U'. The duplicate key value is (1).
The statement has been terminated.

Naruszenie unikalnego indeksu zwraca błąd 2601.

Msg 2601, Level 14, State 1, Line 1
Cannot insert duplicate key row in object 'dbo.P1' with unique index 'P1_u'. The duplicate key value is (1).
The statement has been terminated.

Wyłączanie

Unikalne ograniczenie nie może zostać wyłączone.

Msg 11415, Level 16, State 1, Line 1
Object 'P1U_pk' cannot be disabled or enabled. This action applies only to foreign key and check constraints.
Msg 4916, Level 16, State 0, Line 1
Could not enable or disable the constraint. See previous errors.

Ale unikalny indeks stojący za ograniczeniem klucza podstawowego lub unikatowy może zostać wyłączony, podobnie jak każdy unikalny indeks. Czapka Brain2000.

ALTER INDEX P1_u ON dbo.P1 DISABLE ;

Zwróć uwagę na zwykłe ostrzeżenie, że wyłączenie indeksu klastrowego powoduje, że dane są niedostępne.

Opcje

Unikalne ograniczenia obsługują opcje indeksowania, takie jak FILLFACTOR i IGNORE_DUP_KEY, chociaż nie było tak w przypadku wszystkich wersji SQL Server.

Zawarte kolumny

Indeksy nieklastrowane mogą zawierać nieindeksowane kolumny (nazywane indeksem kryjącym, jest to znaczące zwiększenie wydajności). Indeksy stojące za ograniczeniami PRIMARY KEY i UNIQUE nie mogą zawierać kolumn. Hat-tip @ypercube.

Filtracja

Ograniczenia unikatowego nie można filtrować.

Unikalny indeks można filtrować.

CREATE UNIQUE NONCLUSTERED INDEX Students6_DrivesLicence_u 
ON dbo.Students6( DriversLicenceNo ) WHERE DriversLicenceNo is not null ;

Ograniczenia klucza obcego

Ograniczenie klucza obcego nie może odwoływać się do przefiltrowanego indeksu unikalnego, ale może odwoływać się do niefiltrowanego indeksu unikalnego (myślę, że został on dodany w SQL Server 2005).

Nazewnictwo

Podczas tworzenia wiązania określenie nazwy wiązania jest opcjonalne (dla wszystkich pięciu typów wiązań). Jeśli nie podasz nazwy, MSSQL wygeneruje ją dla Ciebie.

CREATE TABLE dbo.T1 (
    TID int not null PRIMARY KEY
) ;
GO
CREATE TABLE dbo.T2 (
    TID int not null CONSTRAINT T2_pk PRIMARY KEY
) ;

Podczas tworzenia indeksów musisz podać nazwę.

Hat-tip @ i-one.

Spinki do mankietów

http://technet.Microsoft.com/en-us/library/aa224827 (v = SQL.80) .aspx

http://technet.Microsoft.com/en-us/library/ms177456.aspx

107

Aby zacytować MSDN jako wiarygodne źródło:

Nie ma znaczących różnic między tworzeniem ograniczenia UNIKALNEGO a tworzeniem unikalnego indeksu niezależnego od ograniczenia . Sprawdzanie poprawności danych odbywa się w ten sam sposób, a optymalizator zapytań nie rozróżnia unikalnego indeksu utworzonego przez ograniczenie lub utworzonego ręcznie. Jednak utworzenie ograniczenia UNIQUE w kolumnie sprawia, że ​​cel indeksu jest jasny ... więcej informacji tutaj

I ...

Aparat baz danych automatycznie tworzy indeks UNIQUE, aby wymusić wymóg unikatowości ograniczenia UNIQUE. Dlatego, jeśli podjęta zostanie próba wstawienia duplikatu wiersza, Aparat baz danych zwraca komunikat o błędzie z informacją, że naruszenie UNIKALNE zostało naruszone i nie dodaje wiersza do tabeli. O ile indeks klastrowany nie jest wyraźnie określony, domyślnie tworzony jest unikalny indeks nieklastrowany, aby wymusić ograniczenie UNIKALNE ... więcej informacji tutaj

Inne do: https://technet.Microsoft.com/en-us/library/aa224827%28v=sql.80%29.aspx

10
user919426

Jedną z głównych różnic między ograniczeniem unikalnym a indeksem jest to, że ograniczenie klucza obcego w innej tabeli może odwoływać się do kolumn tworzących ograniczenie unikalne. Nie dotyczy to unikalnych indeksów. Ponadto unikalne ograniczenia są zdefiniowane jako część standardu ANSI, podczas gdy indeksy nie. Wreszcie, uważa się, że istnieje unikalne ograniczenie w dziedzinie logicznego projektowania baz danych (które mogą być wdrażane inaczej przez różne silniki DB), podczas gdy indeks jest aspektem fizycznym. Dlatego unikalne ograniczenie jest bardziej deklaratywne. Wolę unikalne ograniczenie w prawie wszystkich przypadkach.

7
Dmitry Frenkel

W Oracle główna różnica polega na tym, że można utworzyć indeks unikalny dla funkcji, którego nie da się zrobić przy unikalnych ograniczeniach:

Na przykład

create unique index ux_test on my_table (case when amount != 0 then fk_xyz end);

Więc fk_xyz jest unikalny tylko dla rekordów, które mają amount != 0.

1
Amir Pashazadeh