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:
IsUnique
auf "Ja" belasse, gibt es dann Unterschiede?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.
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.
Wenn Sie SqlMetal.exe verwenden, um DBML- oder LinqToSql-Entitäten auszugeben:
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;
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.
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.
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)
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).
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.
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). .