Wenn ich unique
ein Feld einschränke, muss ich dann auch einen Index für dieses Feld erstellen, um eine skalierbare Einfügezeit zu erhalten? Oder ist das für mich erledigt (auch wenn der verwendete Index nicht öffentlich zugänglich ist?)
Insbesondere arbeite ich mit Apache Derby für das Prototyping, obwohl ich es wahrscheinlich in naher Zukunft auf MySQL verschieben werde. Ich hoffe auch, dass der SQL-Standard etwas enthält, das etwas darüber aussagt.
Ich werde nie nach diesem Feld suchen müssen, daher würde ich lieber keinen nutzlosen Index erstellen. Aber ich hätte lieber einen nutzlosen Index als eine O(n)
Einfügezeit.
mysql
constraint
derby
unique-constraint
corsiKa
quelle
quelle
Antworten:
--BEARBEITEN--
Meine ursprüngliche Antwort (unten) ist für Sie wahrscheinlich überhaupt nicht nützlich, da sie die Frage der
unique
Einschränkungen nicht behandelt . Wie andere gesagt haben, werden diese Einschränkungen normalerweise mit einem impliziten eindeutigen Index implementiert. In besonderen Fällen ist dies möglicherweise nicht der Fall (zdisable novalidate
. B. für Oracle).Die Frage könnte sein: Ist es möglich, die Eindeutigkeit ohne Index durchzusetzen? Im Allgemeinen lautet die Antwort "Nein". In einigen Fällen bedeutet ein Clustered-Index jedoch, dass der Index und die Tabelle dasselbe Objekt sind.
--END EDIT--
Sie sagten: "Ich hätte lieber einen nutzlosen Index als eine Einfügezeit von O (n).", Aber im Allgemeinen haben Datenbanken keine Einfügezeit von O (n). Es sind zwei Fälle zu berücksichtigen:
Eine normale Tabelle mit oder ohne Indizes:
Neue Zeilen werden oben auf dem Heap abgelegt. Das RDBMS betrachtet wahrscheinlich nur 1 Block, also nicht nur O (1), sondern sehr kleines O (1).
Wenn die Tabelle Indizes enthält, wird jeder ein Zeiger auf die Zeile hinzugefügt. Dies ist normalerweise eine O-Operation (log (n)).
Eine Tabelle mit einer Art Clustering, z. B. eine indexorganisierte Tabelle oder ein Cluster für Oracle oder ein Clustered Index für SQL Server und andere:
Neue Zeilen werden in einen bestimmten Block eingefügt, was dazu führen kann, dass der Block geteilt wird oder überläuft. Was auch immer passiert, es ist immer noch O (log (n)) oder besser , verursacht durch den B-Baum oder eine ähnliche Struktur, die zum Auffinden des Blocks verwendet wird.
quelle
O(n)
Sie die gesamte Tabelle überprüfen müssen. Das versuche ich zu vermeiden.O(lg n)
. Das ist kein Problem. Meine Frage ist, ob das System, da es weiß, dass Sie diesen Index benötigen, um eine angemessene Einfügezeit zu erhalten, einen Index für mich erstellen würde.PRIMARY KEY> = EINZIGARTIG> = INDEX == KEY
InnoDB-Daten werden von der PK bestellt. MyISAM PK verhält sich genauso wie UNIQUE.
INSERT muss jedem Index (jeglicher Art), den Sie haben, eine "Zeile" hinzufügen. Dies dauert einige Zeit. (Normalerweise nicht genügend Zeit, um eine Rolle zu spielen.) Alle Indizes werden im BTree-Format gespeichert. MyISAM BTree-Blöcke sind 1 KB groß. InnoDB verwendet 16 KB.
Durch das Einfügen in InnoDB werden die PK und die Daten gleichzeitig aktualisiert.
Durch das Einfügen in MyISAM werden die Daten normalerweise an die .MYD "angehängt". Separat wird der PK eine Zeile hinzugefügt (falls vorhanden).
INSERT muss zuerst überprüfen, ob für einen PRIMARY- oder UNIQUE-Schlüssel kein doppelter Schlüssel vorhanden ist. Dies erfolgt mithilfe des Index. Und deshalb erstellen die EINZIGARTIGEN und AUSLÄNDISCHEN SCHLÜSSELBESCHRÄNKUNGEN wirklich Indizes. Dies ist O (logN), aber normalerweise CPU, nicht I / O, denn wenn effizientes Caching.
quelle
UNIQUE
Einschränkung einen Index erstellt, ohne dass der Benutzer einen Index angibt, der erstellt werden soll?Um die Frage fett zu beantworten: Ja, wenn Sie ein Feld eindeutig machen, wird es wie der Primärschlüssel indiziert. Tatsächlich hatte ich dies in einer anderen Frage in Bezug auf Primärschlüssel mit eigenem Namen erörtert , um sie von anderen eindeutigen (Kandidaten-) Schlüsseln zu unterscheiden .
Für Einschränkungen werden Indizes für Sie erstellt, damit das Einschränkungsparadigma eingerichtet wird. Sie sollten in der Lage sein, doppelte Indizes, auch EINZIGARTIGE Schlüssel, zu entfernen, solange die von Ihnen vorgenommene Einschränkung nicht auf andere EINZIGARTIGE Schlüssel verweist, die Sie persönlich erstellt haben, abgesehen vom Einschränkungsparadigma.
Möglicherweise müssen Sie nie nach diesem Feld suchen, aber MySQL muss als Pfad die Gültigkeit der Schlüssel bestimmen und festlegen, wie die Operationen ON DELETE CASCADE und ON UPDATE CASCADE ausgeführt werden sollen.
Der EINZIGARTIGE Index garantiert einfach die Eindeutigkeit von Tupeln (Singletons, Paare, Tripletts, ..., n-Tupel usw.) in jeder Zeile in der Tabelle.
Es liegt in Ihrem Ermessen, solche doppelten Indizes zu entfernen, vorausgesetzt, Sie brechen nicht das Einschränkungsparadigma, das Sie in der Tabelle haben möchten.
quelle
O(n)
). Wenn es einen Index gibt, ist die Suche (wahrscheinlichO(lg n)
) viel schneller . Das ist mein Problem. Ich bin mir der Mechanik der referenziellen Integrität sehr wohl bewusst und mache mir (für die Zwecke dieser Frage) nur Sorgen um die Leistung.