Laut CREATE INDEX
Dokumentation:
Bis zu 16 Spalten können zu einem einzigen zusammengesetzten Indexschlüssel kombiniert werden.
Wir haben eine Tabelle mit ~ 18 Spalten, die eine eindeutige Kombination bilden müssen. Diese Tabelle ist nicht leistungsabhängig - wir aktualisieren selten Werte / fügen Datensätze ein. Wir müssen nur sicherstellen, dass wir das Duplizieren unserer Datensätze vermeiden ... und dachten, wir könnten eine einfache Einschränkung der Eindeutigkeit auferlegen.
Irgendwelche Ideen? Ich bin offen dafür, den eindeutigen Index / die eindeutige Einschränkung vollständig zu vermeiden, wenn es einen besseren Weg gibt.
Antworten:
Fügen Sie eine persistierte berechnete Spalte hinzu , die die 18 Schlüssel kombiniert, und erstellen Sie dann einen eindeutigen Index für die berechnete Spalte:
Siehe Erstellen von Indizes für berechnete Spalten .
Ein anderer Ansatz besteht darin, eine indizierte Ansicht zu erstellen:
Siehe Erstellen indizierter Ansichten .
Beide Ansätze ermöglichen ein Teilschlüsselaggregat: Aggregat c1 + c2 + c3 als k1, c4 + c5 + c6 als k2 usw. Dann indizieren / erstellen Sie eine indizierte Ansicht auf (k1, k2, ...). Dies könnte für Entfernungsscans von Vorteil sein (der Index kann für die Suche nach c1 + c2 + c3 verwendet werden.
Natürlich sind alle
+
Operationen in meinem Beispiel Zeichenfolgenaggregation. Der tatsächlich zu verwendende Operator hängt von den Typen all dieser Spalten ab (dh Sie müssen möglicherweise explizite Umwandlungen verwenden).PS. Da eindeutige Einschränkungen durch einen eindeutigen Index erzwungen werden, gilt jede Einschränkung für eindeutige Indizes auch für eindeutige Einschränkungen:
Das Erstellen der Einschränkung für eine persistierte berechnete Spalte funktioniert jedoch wie folgt:
Offensichtlich belegt die persistierte Spalte den Speicherplatz auf der Festplatte, sodass der Ansatz für eine sehr große Tabelle möglicherweise schlecht ist. Der Ansatz der indizierten Ansicht weist dieses Problem nicht auf, sondern belegt nur den Platz für den Index , nicht den Platz für die berechnete Spalte und den Index.
quelle
Ich denke, dass Sie es viel besser machen würden, Ihre eindeutige Indexprüfung für eine berechnete Spalte durchzuführen, die mit
HASHBYTES('MD5', ...)
der Kombination Ihrer 18 Spalten generiert wird .quelle
Ich bin auf dieses Problem gestoßen, und mein leitender DBA schlug vor, eine Funktion zur Überprüfung der Eindeutigkeit zu verwenden. Meine Beilagen sind relativ klein und selten (~ 1000 Zeilen, die zu Beginn eines jeden Monats eingefügt werden), und meine einzige Sorge ist die Durchsetzung der Eindeutigkeit.
@RBarryYoung, ich habe noch keinen Repräsentanten, um einen Kommentar abzugeben, aber ich hatte Probleme mit der HASHBYTES-Lösung, da einer meiner Datentypen eine Datums- / Uhrzeitangabe war, und ich habe den Fehler des Neulings (?) Begehen, mein nicht das optionale Stilargument anzugeben CONVERT-Funktion beim Konvertieren in Varchar. Ohne den Stil wird der folgende Fehler angezeigt, wenn Sie versuchen, die
PERSISTED UNIQUE NONCLUSTERED
Einschränkungen hinzuzufügen :quelle
Sie können einige der Werte kombinieren, um einen neuen eindeutigen Wert zu erstellen und diesen zusätzlich zu den aktuellen Daten zu speichern.
Erstellen Sie eine benutzerdefinierte Funktion zum Erstellen der neuen Werte und einen Auslöser zum Auffüllen des Felds, wenn Daten hinzugefügt werden. Dann haben Sie nicht viel mehr Aufwand bei der Pflege des Felds.
Wenn Sie zwei oder drei Ihrer Felder kombinieren, unterschreiten Sie das Limit von 16.
quelle
Sie könnten mit einem Auslöser für
insert
/ gehenupdate
. Führen Sie eine ausgewählte Gruppierung nach Ihren Spalten mit der Klausel von durchhaving count(*) > 1
. Wenn das nicht leer zurückkommt, rollen Sie zurück.quelle
Folgendes würde ich tun. Ich würde einen AFTER-Trigger für INSERT, UPDATE erstellen, der eine
ROW_NUMBER ()
Funktion ausführt, und Partitionen für alle 18 Ihrer eindeutigen Spalten. Wenn die maximale Zeilennummer größer als eins ist, führen Sie a ausROLLBACK
.quelle