it-swarm.com.de

Eindeutiger Schlüssel im Vergleich zum eindeutigen Index für SQL Server 2008

Ich habe eine Tabelle namens countries und definiere die country_name-Spalte als eindeutig, indem ich einen Index/Schlüssel vom Typ "Eindeutiger Schlüssel" in SQL Server 2008 R2 erstellt. 

Ich habe aber folgende Fragen:

  1. erstellt das Erstellen eines Index/Schlüssels vom Typ "Eindeutiger Schlüssel" automatisch einen nicht gruppierten Index für diese Spalte?
  2. wenn ich den Typ von "Eindeutiger Schlüssel" in "Index" ändere und den Wert für IsUnique auf "Ja" belasse, gibt es dann Unterschiede?
  3. warum gibt es zwei Optionen: "Eindeutiger Schlüssel" und "Index". Ich denke, die beiden sind gleich?
46
john Gu

Hinter den Kulissen wird eine eindeutige Einschränkung als eindeutiger Index implementiert. Es spielt also keine Rolle, wie Sie ihn festlegen. Ich neige dazu, es einfach zu implementieren als:

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

Einige Leute erstellen stattdessen einen eindeutigen Index, z.

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

Der Unterschied liegt in der Absicht: Wenn Sie die Einschränkung zum Erzwingen von Eindeutigkeits-/Geschäftsregeln erstellen, erstellen Sie eine Einschränkung. Wenn Sie dies tun, um die Abfrageleistung zu verbessern, ist es logischer, einen eindeutigen Index zu erstellen. Auch hier ist die gleiche Implementierung, aber der Weg, den Sie dahin bringen, kann Ihre Absicht dokumentieren.

Ich denke, dass es mehrere Optionen gibt, um sowohl die vorherige Sybase-Funktionalität als auch den ANSI-Standard zu beachten (obwohl eindeutige Einschränkungen nicht den Standard 100% entsprechen, da sie nur einen NULL-Wert zulassen - einen eindeutigen Index, auf) Auf der anderen Seite können Sie dies umgehen, indem Sie eine WHERE-Klausel (WHERE col IS NOT NULL) für SQL Server 2008 und höher hinzufügen.

63
Aaron Bertrand

Zu erwähnen ist noch Folgendes: Wenn Sie einen Index erstellen, können Sie eingeschlossene Spalten angeben. Dies kann dazu beitragen, dass Ihr SQL-Code schneller arbeitet, wenn nach country_name gesucht wird.

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'

Der SQL Server speichert "foo_other_column" im Index selbst. Im Falle einer eindeutigen Einschränkung wird zuerst der Index von 'test' gefunden, dann wird nach einer Zeile in der Tabelle foo gesucht und nur dort wird "foo_other_column" verwendet.

13

Wenn Sie SqlMetal.exe verwenden, um DBML- oder LinqToSql-Entitäten auszugeben:

  • Wenn ein Fremdschlüssel einen eindeutigen Schlüssel verwendet, erhalten Sie wie erwartet eine Zuordnung.
  • Wenn ein Fremdschlüssel einen eindeutigen Index verwendet, wird er nicht angezeigt.

Der Grund liegt in der Implementierung von SqlMetal. Es fragt das Datenbankinformationsschema ab, insbesondere die Verwendung der Schlüsselspalten. Dort werden eindeutige Schlüssel dargestellt, eindeutige Indizes jedoch nicht.

SELECT TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME, ORDINAL_POSITION
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE;
0
Tomas Karban

Es gibt keinen Unterschied zwischen einem eindeutigen Index oder einer eindeutigen Einschränkung und auch keinen Leistungsunterschied. Es gibt jedoch einige Unterschiede bei der Erstellung, bei denen einige Indexerstellungsoptionen für eindeutige Einschränkungen nicht verfügbar sind.

0
Noah

Einer der wichtigsten Punkte ist die Annahme, dass Sie den Spaltenwert auf Null halten möchten, um die Eindeutigkeit beizubehalten. Dies ist mit einer eindeutigen Schlüsseleinschränkung nicht möglich. Mit einem eindeutigen Schlüsselindex können Sie den Spaltenwert auf Null halten, um die Eindeutigkeit beizubehalten. Wenn Sie also eine eindeutige Spalte mit dem Typ "Eindeutiger Index" benötigen, ist eine eindeutige Schlüsselbedingung erforderlich, wenn Sie eine nicht nullfähige Spalte benötigen.

0
Amit

Abgesehen von den hervorragenden Antworten oben würde ich hier meine 2 Cent hinzufügen.

Der eindeutige Schlüssel ist eine Einschränkung und er verwendet den eindeutigen Index, um sich durchzusetzen. So wie der Primärschlüssel normalerweise von einem gruppierten eindeutigen Index erzwungen wird. Eine Einschränkung und ein Index sind logischerweise zwei verschiedene Dinge. In RDBMS kann eine Einschränkung jedoch physisch über einen Index implementiert werden.

Wenn eine Tabelle mit einer eindeutigen Einschränkung in SQL Server erstellt wird, sehen Sie sowohl mit dem Einschränkungsobjekt als auch mit einen eindeutigen 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;

wir erhalten folgendes (eine Einschränkung und einen Index)

 enter image description here

Wenn Sie jedoch keine Einschränkung erstellen, sondern nur einen eindeutigen Index wie folgt

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

Sie werden sehen, dass KEIN Constraint-Objekt erstellt wurde (nur ein Index wurde erstellt).

 enter image description here

Aus "theoretischer" Perspektive ist eine Einschränkung in SQL Server ein Objekt mit dem object_id-Wert und ist schematgebunden, während ein Index kein Objekt ist und keinen object_id-Wert und kein Schema hat.

0
jyao

Eine dritte Option, um die Eindeutigkeit zu erzwingen, ist die Verwendung eines gefilterten eindeutigen Index , um einen nullbaren eindeutigen Index zuzulassen.
Dies wird nicht mit Unique-Constraints funktionieren.
Angenommen, Sie haben eine Spalte, in der Sie nur eindeutige Werte zulassen möchten.
, Möchten aber dennoch mehrere NULL-Werte unterstützen, wenn sie nicht vorhanden sind.
Nur ein gefilterter Unique-Index würde funktionieren:

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.

Derzeit können Sie in SSMS noch keinen gefilterten Index erstellen, während Sie eine Tabelle mit der GUI bearbeiten.
Sie können jedoch alle geöffneten Tabellen-Designer schließen und dann die Eigenschaften des Index selbst im Objekt-Explorer öffnen, wenn Sie die GUI durchgehen möchten, anstatt den Index manuell zu erstellen (wie oben). .

0
MikeTeeVee