it-swarm-eu.dev

Kdy bych měl použít jedinečné omezení místo jedinečného indexu?

Když chci, aby sloupec měl odlišné hodnoty, mohu použít omezení

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

nebo mohu použít jedinečný index

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

create unique index I_t2 on t2(code);

Sloupce s jedinečnými omezeními se zdají být dobrými kandidáty na jedinečné indexy.

Existují nějaké známé důvody, proč používat jedinečná omezení a místo toho nepoužívat jedinečné indexy?

210
bernd_k

Pod kapotou je jedinečné omezení implementováno stejným způsobem jako unikátní index - pro efektivní splnění požadavku na vynucení omezení je zapotřebí index. I když je index vytvořen v důsledku omezení UNIQUE, plánovač dotazů ho může použít jako jakýkoli jiný index, pokud to považuje za nejlepší způsob, jak přistupovat k danému dotazu.

Takže pro databázi, která podporuje obě funkce, bude volba, kterou použít, často klesnout na preferovaný styl a konzistenci.

Pokud plánujete používat index jako index (tj. Váš kód se může spolehnout na rychlé/rychlé vyhledávání/třídění/filtrování v tomto poli), použil bych výslovně jedinečný index (a komentoval zdroj), nikoli omezení, abych to udělal clear - tímto způsobem, pokud se požadavek na jedinečnost změní v pozdější revizi aplikace, kterou vy (nebo nějaký jiný kodér) budete vědět, abyste zajistili, že místo jedinečného bude vložen nejedinečný index (pouze odstranění jedinečného omezení by odstranilo index zcela). V náznaku indexu může být také pojmenován konkrétní index (tj. WITH (INDEX (ix_index_name)), což podle mě není případ indexu vytvořeného za scénami pro správu jedinečnosti, protože jeho název pravděpodobně neznáte.

Stejně tak pokud potřebujete pouze vynutit jedinečnost jako obchodní pravidlo, nikoli pole, které je třeba prohledat nebo použít pro třídění, pak bych použil omezení, znovu, aby se zamýšlené použití stalo viditelnějším, když se někdo podívá na definici vaší tabulky.

Všimněte si, že pokud použijete jedinečné omezení i jedinečný index ve stejném poli, databáze nebude dostatečně jasná, aby viděla duplicitu, takže skončí se dvěma indexy, které zabírají více místa a zpomalí vkládání/aktualizace řádků.

165
David Spillett

Kromě bodů v jiných odpovědích jsou zde i některé klíčové rozdíly mezi nimi.

Poznámka: Chybové zprávy jsou z SQL Server 2012.

Chyby

Porušení jedinečného omezení vrátí chybu 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.

Porušení jedinečného indexu vrátí chybu 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.

Zakázání

Jedinečné omezení nelze zakázat.

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.

Jedinečný index za omezením primárního klíče nebo jedinečným omezením však lze zakázat, stejně jako jakýkoli jedinečný index. Hat-tip Brain2000.

ALTER INDEX P1_u ON dbo.P1 DISABLE ;

Všimněte si obvyklého varování, že deaktivace seskupeného indexu způsobí, že data nebudou přístupná.

Možnosti

Unikátní omezení podporují možnosti indexování jako FILLFACTOR a IGNORE_DUP_KEY, ačkoli tomu tak nebylo u všech verzí serveru SQL.

Zahrnuté sloupce

Nonclustered indexy mohou zahrnovat neindexované sloupce (nazývané krycí index, to je hlavní vylepšení výkonu). Indexy za omezeními PRIMARY KEY a UNIQUE nemohou obsahovat sloupce. Hat-tip @ypercube.

Filtrování

Jedinečné omezení nelze filtrovat.

Jedinečný index lze filtrovat.

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

Omezení cizího klíče

Omezení cizího klíče nemůže odkazovat na filtrovaný jedinečný index, ačkoli může odkazovat na nefiltrovaný jedinečný index (myslím, že to bylo přidáno v SQL Server 2005).

Pojmenování

Při vytváření omezení je zadání názvu omezení volitelné (pro všech pět typů omezení). Pokud nezadáte jméno, vygeneruje pro vás MSSQL.

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

Při vytváření indexů musíte zadat název.

Hat-tip @ i-one.

Odkazy

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

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

107
Greenstone Walker

Citace MSDN jako autoritativního zdroje:

Neexistují žádné významné rozdíly mezi vytvořením omezení UNIQUE a vytvořením jedinečného indexu, který je nezávislý na omezení . Ověření dat probíhá stejným způsobem a optimalizátor dotazů nerozlišuje mezi jedinečným indexem vytvořeným omezením nebo ručně vytvořeným. Vytvořením omezení UNIQUE ve sloupci je však cíl indexu jasný ... více informací zde

A ...

Databázový stroj automaticky vytvoří index UNIQUE pro vynucení požadavku jedinečnosti omezení UNIQUE. Pokud tedy dojde k pokusu o vložení duplicitní řádky, Databázový stroj vrátí chybovou zprávu, která uvádí, že bylo porušeno omezení UNIQUE a nepřidá řádek do tabulky. Pokud není explicitně specifikován seskupený index, je ve výchozím nastavení vytvořen jedinečný neclusterovaný index pro vynucení omezení UNIQUE ... více informací zde

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

10
user919426

Jedním z hlavních rozdílů mezi jedinečným omezením a jedinečným indexem je to, že omezení cizího klíče v jiné tabulce může odkazovat na sloupce, které tvoří jedinečné omezení. To neplatí pro jedinečné indexy. Kromě toho jsou jedinečná omezení definována jako součást standardu ANSI, zatímco indexy nejsou. A konečně, jedinečné omezení, o kterém se uvažuje, že bude žít v oblasti designu logické databáze (které může být implementováno odlišně různými stroji DB), zatímco index je fyzický aspekt. Proto je jedinečné omezení deklarativnější. Upřednostňuji jedinečné omezení téměř ve všech případech.

7
Dmitry Frenkel

V Oracle je hlavní rozdíl v tom, že si můžete vytvořit index unikátní funkce, který nelze provést s jedinečnými omezeními:

Například

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

Tak fk_xyz je jedinečné pouze pro záznamy, které mají amount != 0.

1
Amir Pashazadeh