Wann sollte ich eine eindeutige Einschränkung anstelle eines eindeutigen Index verwenden?

194

Wenn eine Spalte unterschiedliche Werte haben soll, 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 eindeutigen Einschränkungen scheinen gute Kandidaten für eindeutige Indizes zu sein.

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

bernd_k
quelle
9
sind sie eigentlich anders Ich denke, in einigen Datenbanken, z. B. postgresql, erstellt eine eindeutige Einschränkung einfach einen eindeutigen Index. Ich antworte nicht, weil ich nichts über SQL Server weiß.
Xenoterracide
6
In postgresql können Sie einen Ausdruck in einem eindeutigen Index, jedoch nicht in einer eindeutigen Einschränkung verwenden.
Neil McGuigan
1
In MS SQL sind sie gleich implementiert. Versuchen Sie, zwei Tabellen mit denselben Daten zu erstellen, eine mit einer eindeutigen Einschränkung und die andere mit einem eindeutigen Index. Sie werden die gleiche Menge an Indexspeicherplatz verwenden und beide werden in der Lage sein, nach dem eindeutigen Index zu suchen, der (in der Praxis) so oder so erstellt wird.
Jon of All Trades

Antworten:

153

Unter der Haube wird eine eindeutige Einschränkung genauso implementiert wie ein eindeutiger Index - ein Index wird benötigt, um die Anforderung zur Durchsetzung der Einschränkung effizient zu erfüllen. Selbst wenn der Index als Ergebnis einer UNIQUE-Einschränkung erstellt wird, kann er vom Abfrageplaner wie jeder andere Index verwendet werden, wenn er dies als die beste Methode zum Annähern an eine bestimmte Abfrage ansieht.

Bei einer Datenbank, die beide Funktionen unterstützt, kommt es daher häufig auf den bevorzugten Stil und die Konsistenz an.

Wenn Sie vorhaben, den Index als Index zu verwenden (dh Ihr Code muss möglicherweise schnell nach diesem Feld suchen / sortieren / filtern), verwende ich explizit einen eindeutigen Index (und kommentiere die Quelle) anstelle einer Einschränkung, um dies zu erreichen Klar - auf diese Weise können Sie (oder ein anderer Programmierer) sicherstellen, dass anstelle des eindeutigen Index ein nicht eindeutiger Index erstellt wird, wenn die Eindeutigkeitsanforderung in einer späteren Version der Anwendung geändert wird (nur das Entfernen einer eindeutigen Einschränkung würde dies beseitigen) den Index vollständig). Ein bestimmter Index kann auch in einem Indexhinweis benannt werden (z. B. WITH (INDEX (ix_index_name)), was meines Erachtens nicht für den Index gilt, der hinter den Kulissen zur Verwaltung der Eindeutigkeit erstellt wurde, da Sie dessen Namen wahrscheinlich nicht kennen.

Wenn Sie nur die Eindeutigkeit als Geschäftsregel erzwingen möchten, anstatt das Feld zu durchsuchen oder zum Sortieren zu verwenden, würde ich die Einschränkung verwenden, um die beabsichtigte Verwendung noch einmal deutlicher zu machen, wenn sich jemand anderes Ihre Tabellendefinition ansieht.

Beachten Sie, dass, wenn Sie sowohl eine eindeutige Einschränkung als auch einen eindeutigen Index für dasselbe Feld verwenden, die Datenbank nicht hell genug ist, um die Duplizierung zu erkennen, sodass Sie am Ende zwei Indizes haben, die zusätzlichen Speicherplatz belegen und Zeileneinfügungen / -aktualisierungen verlangsamen.

David Spillett
quelle
1
Ich wundere mich über die "die Datenbank wird nicht hell genug sein"? Gilt das für alle RDBMS? Ist es vom SQL-Standard vorgeschrieben? Und selbst wenn es so ist (und ich würde mich fragen, warum es so sein sollte), implementieren alle Implementierungen es so? Oder: Warum kann eine DB nicht "hell genug" sein?
Jürgen A. Erhard
4
@jae: Ein DBMS könnte durchaus hell genug sein, aber Sie müssten bei jedem DBMS nachsehen, ob dies der Fall ist. Wenn Sie MSSQL auffordern, zwei identische Indizes zu erstellen, werden zwei statt eines mit zwei Namen bezeichneten Index erstellt (zumindest war dies das letzte Mal der Fall, als ich eine solche Situation entdeckte (aufgrund eines Kopier- und Einfügefehlers von meiner Seite)). Daher gehe ich davon aus, dass dies auch der Fall ist, wenn einer der Indizes aufgrund einer Einschränkung vorhanden ist.
David Spillett
3
+1 @ David Spillett Ich denke, dass das DBMS einfach davon ausgeht, dass Sie wissen, was Sie tun. Wenn Sie Lust haben, denselben Index zweimal zu erstellen, werden Sie darüber nicht befragt.
Andrew Barber
2
sehr aufschlussreich. Wissen Sie zufällig, ob dieses Verhalten auch in MySQL und Apache Derby auftritt?
corsiKa
5
Sie können eine Einschränkung benennen und in einem Indexhinweis verwenden. CREATE TABLE #T(X INT CONSTRAINT PK PRIMARY KEY NONCLUSTERED);SELECT * FROM #T WITH(INDEX(PK)) WHERE X = 1. Indizes können flexibler sein, obwohl Einschränkungen nicht alle Indexoptionen wie INCLUDEd-Spalten oder gefilterte Indizes unterstützen.
Martin Smith
101

Neben den Punkten in anderen Antworten gibt es hier einige wesentliche Unterschiede zwischen den beiden.

Hinweis: Die Fehlermeldungen stammen aus SQL Server 2012.

Fehler

Die Verletzung einer eindeutigen Einschränkung gibt den 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.

Die Verletzung eines eindeutigen Index gibt den 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.

Deaktivieren

Eine eindeutige 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ärschlüsseleinschränkung oder einer eindeutigen Einschränkung kann ebenso wie jeder eindeutige Index deaktiviert werden. Hutspitze Brain2000.

ALTER INDEX P1_u ON dbo.P1 DISABLE ;

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

Optionen

Einzigartige Einschränkungen unterstützen Indizierungsoptionen wie FILLFACTORund IGNORE_DUP_KEY, obwohl dies nicht bei allen Versionen von SQL Server der Fall war.

Enthaltene Spalten

Nonclustered-Indizes können nicht indizierte Spalten enthalten (Covering-Index genannt, dies ist eine wesentliche Leistungsverbesserung). Die Indizes hinter den Einschränkungen PRIMARY KEY und UNIQUE dürfen keine Spalten enthalten. Hutspitze @ypercube.

Filtern

Eine eindeutige 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 ;

Fremdschlüsseleinschränkungen

Eine Fremdschlüsseleinschränkung kann nicht auf einen gefilterten eindeutigen Index verweisen, obwohl sie auf einen nicht gefilterten eindeutigen Index verweisen kann (ich denke, dies wurde in SQL Server 2005 hinzugefügt).

Benennung

Beim Erstellen einer Einschränkung 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.

Hutspitze @ i-one.

Links

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

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

Greenstone Walker
quelle
ALTER INDEX tbl ON uconstraint DISABLE, ALTER INDEX tbl ON uconstraint neu zu erstellen: Eine einzigartige Einschränkung kann durch dasselbe Verfahren wie ein Index , deaktiviert und aktiviert werden
Brain2000
Vielen Dank @ Brain2000. Zufälligerweise habe ich heute Morgen einen Abschnitt zum Deaktivieren von Indizes unterrichtet, bevor ich diesen Kommentar gelesen habe.
Greenstone Walker
10

So zitieren Sie MSDN als maßgebliche Quelle:

Es gibt keine wesentlichen Unterschiede zwischen dem Erstellen einer UNIQUE-Einschränkung und dem Erstellen eines eindeutigen Index, der von einer Einschränkung unabhängig ist . Die Datenüberprüfung erfolgt auf dieselbe Weise, und das Abfrageoptimierungsprogramm unterscheidet nicht zwischen einem eindeutigen Index, der von einer Einschränkung erstellt oder manuell erstellt wurde. Wenn Sie jedoch eine UNIQUE-Einschränkung für die Spalte erstellen, wird das Ziel des Index klar ... Weitere Informationen finden Sie hier

Und...

Das Datenbankmodul erstellt automatisch einen EINZIGARTIGEN Index, um die Eindeutigkeitsanforderung der EINZIGARTIGEN Einschränkung durchzusetzen. Wenn daher versucht wird, eine doppelte Zeile einzufügen, gibt das Datenbankmodul eine Fehlermeldung zurück, die besagt, dass die UNIQUE-Einschränkung verletzt wurde, und fügt die Zeile nicht zur Tabelle hinzu. Sofern kein Clustered-Index explizit angegeben wird, wird standardmäßig ein eindeutiger Nonclustered-Index erstellt, um die UNIQUE-Einschränkung zu erzwingen. Weitere Informationen finden Sie hier

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

user919426
quelle
6

Einer der Hauptunterschiede zwischen einer eindeutigen Einschränkung und einem eindeutigen Index besteht darin, dass eine Fremdschlüsseleinschränkung für eine andere Tabelle auf Spalten verweisen kann, aus denen eine eindeutige Einschränkung besteht. Dies gilt nicht für eindeutige Indizes. Darüber hinaus werden eindeutige Einschränkungen als Teil des ANSI-Standards definiert, Indizes jedoch nicht. Schließlich wird die eindeutige Einschränkung im Bereich des logischen Datenbankentwurfs berücksichtigt (der von verschiedenen DB-Engines unterschiedlich implementiert werden kann), während der Index ein physischer Aspekt ist. Daher ist eine eindeutige Einschränkung aussagekräftiger. Ich würde in fast allen Fällen eine eindeutige Einschränkung bevorzugen.

Dmitry Frenkel
quelle
8
-1 In SQL Server ist Folgendes falsch: "Eine Fremdschlüsseleinschränkung für eine andere Tabelle kann auf Spalten verweisen, aus denen eine eindeutige Einschränkung besteht. Dies gilt nicht für eindeutige Indizes." In SQL Server können wir FK-Einschränkungen auf eindeutige Indizes verweisen.
AK
4
Die Möglichkeit für eine Fremdschlüsseleinschränkung, auf einen eindeutigen Index zu verweisen, wurde in SQL Server 2005 hinzugefügt. Viele Quellen, einschließlich einiger Seiten in BOL, wurden nicht aktualisiert, um die Änderungen widerzuspiegeln, daher glaube ich nicht, dass Dmitry die Antwort gibt verdient die downvotes. Der Rest seiner Antwort ist genau richtig - Einschränkungen sind ANSI-Standard, Indizes nicht.
Greenstone Walker
Trotz dieser Abstimmungen meine Lieblingsantwort.
Wunder
Standards sind wichtig. Wenn Ansi-Standards eine eindeutige Einschränkung verwenden sollen, sollten wir eine eindeutige Einschränkung verwenden.
Rhyous
1

In Oracle besteht ein wesentlicher Unterschied darin, dass Sie einen funktionsspezifischen Index erstellen können, der mit eindeutigen Einschränkungen nicht möglich ist:

Zum Beispiel

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

Ist fk_xyzalso nur einmalig für Rekorde die haben amount != 0.

Amir Pashazadeh
quelle
7
In SQL Server (dem Tag der Frage) können Indizes mit einer WHEREKlausel gefiltert werden . CREATE UNIQUE NONCLUSTERED INDEX P4_U ON DBO.P4 ( PID ) WHERE TXT = 'qwert' ;
Greenstone Walker
-3

Die UNIQUE-Einschränkung wird gegenüber dem UNIQUE-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. Index wird für einen schnelleren Zugriff verwendet.

Eindeutige Indizes können where-Klauseln enthalten. Beispielsweise können Sie Indizes für jedes Jahr basierend auf der Datumsspalte erstellen

WHERE Sale_Date BETWEEN '2012-01-01' AND '2012-12-31'
Ravi Ramaswamy
quelle
Gut zu sehen, welche Vorteile die WHERE-Klausel bietet.
Crokusek
3
"Constraint ist auch eine andere Art von Index." Nein, das ist es nicht. Einige Einschränkungen (PK, UQ, FK) können und werden häufig durch die Verwendung von Indizes erzwungen. Nicht unbedingt und nicht standardmäßig in allen DBMS.
ypercubeᵀᴹ