Unieke sleutel Vs. Unieke index op SQL Server 2008

Ik heb een tabel met de naam countriesen ik definieer de country_namekolom om uniek te zijn door een “index / sleutel” van het type “unieke toets” op SQL Server 2008 te maken R2.

Maar ik heb de volgende vragen:

  1. Krijgt “Index / Key” van de unieke toets “Unique” automatisch een niet-geclusterde index op deze kolom?
  2. Als ik het type verander van “Unieke sleutel” naar “Index” en houd ik de IsUniqueWaarde om “Ja” te zijn, dan zijn er verschillende verschillen?
  3. Dus waarom zijn er twee opties “unieke sleutel” en “index”, ik denk dat de twee hetzelfde zijn?

Antwoord 1, Autoriteit 100%

Een unieke beperking wordt achter de scènes geïmplementeerd als een unieke index, dus het maakt niet uit hoe u het opgeeft. Ik heb de neiging om het eenvoudig te implementeren als:

ALTER TABLE dbo.foo ADD CONSTRAINT UQ_bar UNIQUE(bar);

Sommige mensen maken in plaats daarvan een unieke index, b.g

CREATE UNIQUE INDEX IX_UQ_Bar ON dbo.foo(bar);

Het verschil is in de intentie – als u de beperking maakt om unieke / bedrijfsregels af te dwingen, maakt u een beperking, als u dit doet om de queryprestaties te helpen, kan het meer logisch zijn om een ​​unieke index te maken. Nogmaals, onder de deksels is het dezelfde implementatie, maar de weg die u neemt om er te komen, kan u helpen uw intentie te documenteren.

Ik denk dat er meerdere opties zijn om te voldoen aan zowel de vorige sybase-functionaliteit en om zich aan de ANSI-norm te hechten (hoewel unieke beperkingen zich niet houden aan de standaard 100%, omdat ze slechts één null-waarde toestaan ​​- een uniek Index, aan de andere kant, kan dit hier omheen werken door een WHEREClausule (WHERE col IS NOT NULL) op SQL Server 2008 en groter te zijn).


Antwoord 2, Autoriteit 18%

Een extra ding om te vermelden, is dat als u index maakt, u opgenomen kolommen kunt specificeren, dit kan uw SQL-code helpen sneller te werken als er een zoekopdracht is op basis van Country_Name.

CREATE UNIQUE NONCLUSTERED INDEX IX_UQ_Bar
ON dbo.foo (
    bar
)
INCLUDE (foo_other_column)
GO
SELECT foo_other_column FROM Foo WHERE bar = 'test'

SQL Server slaat “foo_other_column” in index zelf op. In het geval van unieke beperking zal het eerst index van ‘Test’ vinden, dan zoekt u naar de rij in de foo-tabel en alleen daar zal het “FOO_OTHER_COLUMM” nemen.


Antwoord 3, Autoriteit 3%

Anders dan de uitstekende antwoorden hierboven, zou ik hier mijn 2 cent hier toevoegen.

Unieke sleutel is een beperking en het gebruikt unieke index om zichzelf te handhaven. Net zoals de primaire sleutel meestal wordt afgedwongen door een geclusterde unieke index.
Logisch gezien zijn een beperking en een index twee verschillende dingen. Maar in RDBMS kan een beperking fysiek worden geïmplementeerd via een index.

Als een tabel is gemaakt met een unieke beperking in SQL Server, ziet u zowel een constraint-object en een unieke index

create table dbo.t (id  int constraint my_unique_constraint unique (id));
select [Constraint]=name from sys.key_constraints 
where parent_object_id = object_id('dbo.t');
select name, index_id, type_desc from sys.indexes
where object_id = object_id('dbo.t')
and index_id > 0;

We krijgen het volgende (een beperking en een index)

Als we echter geen beperking vormen, maar slechts een unieke index als de volgende

create table dbo.t2 (id int );
create unique index my_unique_constraint on dbo.t2 (id);
select [Constraint]=name from sys.key_constraints 
where parent_object_id = object_id('dbo.t2');
select name, index_id, type_desc from sys.indexes
where object_id = object_id('dbo.t2')
and index_id > 0

Je zult zien dat er GEEN beperkingsobject is gemaakt (alleen een index gemaakt).

Vanuit “theoretisch” perspectief, in SQL Server, is een beperking een object met object_id-waarde en is schemagebonden, terwijl een index geen object is en geen object_id-waarde heeft en geen schema-gerelateerd.


Antwoord 4

Er is geen verschil tussen een unieke index of een unieke beperking en er is ook geen prestatieverschil. Er zijn echter enkele verschillen voor het maken waar sommige opties voor het maken van indexen niet beschikbaar zijn voor unieke beperkingen.


Antwoord 5

Als u SqlMetal.exe gebruikt om DBML- of LinqToSql-entiteiten uit te voeren:

  • Als een externe sleutel een unieke sleutel gebruikt, krijgt u een koppeling zoals verwacht.
  • Als een externe sleutel een unieke index gebruikt, wordt deze niet weergegeven.

De reden ligt in de implementatie van SqlMetal. Het bevraagt ​​het database-informatieschema, met name het gebruik van sleutelkolommen. Unieke sleutels worden daar weergegeven, maar unieke indexen niet.

SELECT TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME, ORDINAL_POSITION
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE;

Antwoord 6

Een derde optie om uniciteit af te dwingen, is het gebruik van een gefilterde unieke indexom een ​​nullable unieke index toe te staan.
Dit werkt nietmet Unique-Constraints.
Stel dat u bijvoorbeeld een kolom heeft waarin u alleen unieke waarden wilt toestaan,
   maar wil toch meerdere NULL-waarden ondersteunen als ze niet bestaan.
Alleen een Gefilterde Unieke Indexzou werken:

CREATE UNIQUE NONCLUSTERED INDEX [UF_Employee_UserID] ON [dbo].[Employee]
(
    [UserID] ASC--Not all Employees have a UserID to log into the System.
)
WHERE ([UserID] IS NOT NULL)--Enforce Uniqueness when not null.

Op dit moment kunt u nog steeds geen gefilterde index maken in SSMS terwijl u een tabel bewerkt met behulp van de GUI.
U kunt echter al uw geopende tabelontwerpers sluiten en vervolgens de eigenschappen van de index zelf openen in de objectverkenner, als u door de GUI wilt gaan in plaats van de index met de hand te maken (zoals hierboven).


Antwoord 7

Een van de belangrijkste punten is dat u de kolomwaarde null wilt houden met behoud van uniciteit. Dit kunt u niet doen met unieke sleutelbeperkingen, maar met unieke sleutelindex kunt u de kolomwaarde null houden met behoud van uniciteit.
dus als je een kolom uniek nodig hebt met een Null-able type Unieke index vereist, anders als je een kolom nodig hebt die niet null-able is, dan is een unieke sleutelbeperking vereist.

Other episodes