Frage

Wenn ich möchte, dass eine Spalte unterschiedliche Werte hat, kann ich entweder eine Einschränkung verwenden

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

Oder ich kann einen eindeutigen Index verwenden

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

create unique index I_t2 on t2(code);

Spalten mit einzigartigen Einschränkungen scheinen gute Kandidaten für eindeutige Indizes zu sein.

Gibt es bekannte Gründe, einzigartige Einschränkungen zu verwenden und stattdessen keine eindeutigen Indizes zu verwenden?

War es hilfreich?

Lösung

Unter der Haube wird eine eindeutige Einschränkung genauso implementiert wie ein eindeutiger Index - ein Index ist erforderlich, um die Anforderung zur Durchsetzung der Einschränkung effizient zu erfüllen. Selbst wenn der Index als Ergebnis einer eindeutigen Einschränkung erstellt wird, kann der Abfrageplaner ihn wie jeder andere Index verwenden, wenn er es als den besten Weg ansieht, um sich einer bestimmten Abfrage zu nähern.

Für eine Datenbank, die beide Funktionen unterstützt, wird die Wahl, deren Auswahl verwendet wird, häufig auf bevorzugten Stil und Konsistenz.

Wenn Sie vorhaben, den Index als Index zu verwenden (dh Ihr Code kann sich auf das Suchen/Sortieren/Filterung in diesem Feld verlassen, um schnell zu sein), würde ich explizit einen eindeutigen Index (und kommentieren die Quelle kommentieren) und nicht eine Einschränkung verwenden, um dies zu machen Klar - Auf diese Weise werden die Einzigartigkeitsanforderung in einer späteren Überarbeitung der Anwendung geändert, die Sie (oder ein anderer Coder) wissen, um sicherzustellen der Index vollständig). Ein spezifischer Index kann auch in einem Index -Hinweis genannt werden (dh mit (index (ix_index_name)), was ich für den Index, der hinter den Kulissen erstellt wurde, um die Einzigartigkeit zu verwalten, nicht der Fall ist, da Sie wahrscheinlich nicht seinen Namen kennen.

Ebenso, wenn Sie nur die Einzigartigkeit als Geschäftsregel durchsetzen müssen, anstatt das Feld, das für die Sortierung durchsucht oder verwendet werden muss, würde ich die Einschränkung verwenden, um die beabsichtigte Verwendung offensichtlicher zu machen, wenn jemand anderes Ihre Tischdefinition betrachtet.

Beachten Sie, dass die Datenbank, wenn Sie sowohl eine eindeutige Einschränkung als auch einen eindeutigen Index auf demselben Feld verwenden, nicht hell genug ist, um die Duplikation zu erkennen. Sie erhalten also zwei Indizes, die zusätzlichen Speicherplatz verbrauchen und die Zeileneinsätze/-aktualisierungen verlangsamen.

Andere Tipps

Zusätzlich zu den Punkten in anderen Antworten finden Sie hier einige wichtige Unterschiede zwischen den beiden.

Hinweis: Die Fehlermeldungen stammen von SQL Server 2012.

Fehler

Verstoß gegen eine eindeutige Einschränkung gibt Fehler 2627 zurück.

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.

Verstöße gegen einen eindeutigen Index gibt Fehler 2601 zurück.

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.

Deaktivierung

Eine einzigartige Einschränkung kann nicht deaktiviert werden.

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.

Der eindeutige Index hinter einer primären Schlüsselbeschränkung oder einer eindeutigen Einschränkung kann jedoch deaktiviert werden, ebenso wie jeder eindeutige Index. Hat-Tip Brain2000.

ALTER INDEX P1_u ON dbo.P1 DISABLE ;

Beachten Sie die übliche Warnung, dass die Deaktivierung eines Clustered -Index die Daten unzugänglich macht.

Optionen

Einzigartige Einschränkungen unterstützen Indexierungsoptionen wie FILLFACTOR und IGNORE_DUP_KEY, Obwohl dies für alle Versionen von SQL Server nicht der Fall war.

Enthalten Spalten

Nicht klusterierte Indizes können nicht indizierte Spalten enthalten (als Decking-Index bezeichnet, ist dies eine wichtige Leistungsverbesserung). Die Indizes hinter dem Primärschlüssel und eindeutige Einschränkungen können nicht Spalten enthalten. Hat-Tip @ypercube.

Filterung

Eine einzigartige Einschränkung kann nicht gefiltert werden.

Ein eindeutiger Index kann gefiltert werden.

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

Ausländische Schlüsselbeschränkungen

Eine fremde Schlüsselbeschränkung kann keinen gefilterten eindeutigen Index verweisen, obwohl sie einen nicht filterierten eindeutigen Index verweisen kann (ich glaube, dies wurde in SQL Server 2005 hinzugefügt).

Benennung

Beim Erstellen von Einschränkungen ist die Angabe eines Einschränkungsnamens optional (für alle fünf Arten von Einschränkungen). Wenn Sie keinen Namen angeben, generiert MSSQL einen für Sie.

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

Beim Erstellen von Indizes müssen Sie einen Namen angeben.

Hat-Tip @i-One.

Links

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

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

MSDN als maßgebliche Quelle zu zitieren:

Es gibt keine signifikanten Unterschiede zwischen der Erstellung einer eindeutigen Einschränkung und einem einzigartigen Index, der unabhängig von einer Einschränkung ist. Die Datenvalidierung erfolgt auf die gleiche Weise, und der Abfrageoptimierer unterscheidet nicht zwischen einem eindeutigen Index, der durch eine Einschränkung erstellt oder manuell erstellt wurde. Das Erstellen einer eindeutigen Einschränkung in der Spalte macht das Ziel des Index klar ... Weitere Informationen hier

Und...

Die Datenbank -Engine erstellt automatisch einen eindeutigen Index, um die Einzigartigkeit der eindeutigen Einschränkung durchzusetzen. Wenn ein Versuch, eine doppelte Zeile einzufügen, durchgeführt wird, gibt die Datenbank -Engine eine Fehlermeldung zurück, in der die eindeutige Einschränkung verletzt wurde und die Zeile nicht zur Tabelle hinzugefügt wird. Sofern ein Clustered -Index nicht explizit angegeben ist, wird standardmäßig ein eindeutiger, nicht klusterer Index erstellt, um die eindeutige Einschränkung durchzusetzen ... Weitere Informationen hier

Andere in:: https://technet.microsoft.com/en-us/library/aa224827%28v=sql.80%29.aspx

Einer der Hauptunterschiede zwischen einer eindeutigen Einschränkung und einem eindeutigen Index besteht darin, dass eine fremde Schlüsselbeschränkung in einer anderen Tabelle Spalten verweisen kann, die eine eindeutige Einschränkung ausmachen. Dies gilt nicht für eindeutige Indizes. Darüber hinaus werden eindeutige Einschränkungen als Teil des ANSI -Standards definiert, während Indizes dies nicht tun. Schließlich ist eine eindeutige Einschränkung, in der man sich im Bereich des logischen Datenbankdesigns (das von verschiedenen DB -Motoren unterschiedlich implementiert werden kann), während der Index physischer Aspekt ist. Daher ist einzigartige Einschränkungen deklarativer. Ich würde in fast allen Fällen einzigartige Einschränkungen bevorzugen.

In Oracle können Sie einen wesentlichen Unterschied darin bestehen, einen Funktionseinheitsindex zu erstellen, der mit einzigartigen Einschränkungen nicht machbar ist:

Zum Beispiel

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

So fk_xyz ist nur einzigartig für Aufzeichnungen, die haben amount != 0.

Eindeutige Einschränkung wird gegenüber einem eindeutigen Index bevorzugt. Wenn die Einschränkung nicht eindeutig ist, müssen Sie einen regulären oder nicht eindeutigen Index verwenden. Einschränkung ist auch eine andere Art von Index. Der Index wird für einen schnelleren Zugriff verwendet.

Einzigartige Indizes können dort anhand von Klauseln verfügen. Sie können beispielsweise Indizes für jedes Jahr basierend auf der Datumsspalte erstellen

WHERE Sale_Date BETWEEN '2012-01-01' AND '2012-12-31'
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top