Surrogat vs natürliche Schlüssel: harte Zahlen auf Performance-Unterschiede?
-
22-07-2019 - |
Frage
Es gibt eine gesunde Debatte gibt zwischen Surrogat und natürlichen Schlüsseln:
Meine Meinung, die im Einklang mit der Mehrheit zu sein scheint (es ist eine knappe Mehrheit), ist, dass Sie Ersatzschlüssel verwenden sollten, es wäre denn, ein natürlicher Schlüssel ganz offensichtlich ist und garantiert nicht zu ändern. Dann sollten Sie Einzigartigkeit auf den natürlichen Schlüsseln erzwingen. Was bedeutet, Ersatzschlüssel fast die ganze Zeit.
Beispiel der beiden Ansätze, mit einer Firma Tabelle Start:
1: Surrogate Schlüssel: Tabelle hat ein ID-Feld, das die PK (und eine Identität) ist. Firmennamen sind erforderlich, durch staatliche eindeutig sein, so gibt es eine eindeutige Einschränkung gibt.
2: Natürlicher Schlüssel:. Tabelle verwendet Company und Staat, wie die PK - erfüllt sowohl die PK und Einzigartigkeit
Lassen Sie uns sagen, dass die Gesellschaft PK in 10 anderen Tabellen verwendet wird. Meine Hypothese, ohne Zahlen es zu sichern, ist, dass der Ersatzschlüssel Ansatz viel schneller hier sein würde.
Das einzige überzeugendes Argument ich für natürliche Schlüssel gesehen habe, ist für viele ein zu vielen Tabelle, die die beiden Fremdschlüssel als natürliche Schlüssel verwendet. Ich denke, in diesem Fall ist es sinnvoll ist. Aber Sie können in Schwierigkeiten geraten, wenn Sie ein Refactoring benötigen; das ist außerhalb des Geltungsbereichs dieses Postens denke ich.
hat einen Artikel jemand gesehen, die Performance-Unterschiede vergleichen auf einer Reihe von Tabellen, die Ersatzschlüssel vs. der gleiche Satz von Tabellen natürliche Schlüssel ? Umsah auf SO und Google hat noch nichts lohnt sich, nur eine Menge theorycrafting ergab.
Wichtiges Update : Ich habe angefangen, einen Satz von Testtabellen Aufbau , die diese Frage zu beantworten. Es sieht wie folgt aus:
- PartNatural - Teile-Tabelle, die verwendet der einzigartige Part als PK
- PartSurrogate - Teile Tisch verwendet eine ID (int, Identität) als PK und hat einen eindeutigen Index für den Part
- Plant - ID (int, Identität) als PK
- Engineer - ID (int, Identität) als PK
Jeder Teil für eine Pflanze und jede Instanz eines Teils an einer Anlage verbunden ist, ist mit einem Ingenieure verbunden. Wenn jemand ein Problem mit diesem Testbed hat, ist jetzt die richtige Zeit.
Lösung
Verwenden Sie beide! Natürlicher Keys verhindert eine Beschädigung der Datenbank (Inkonsistenz könnte ein besseres Wort). Wenn die „richtigen“ natürlichen Schlüssel, (um doppelte Zeilen zu eliminieren) wegen Länge schlecht durchführen würden, oder die Anzahl der Spalten beteiligt, für Leistungszwecke kann ein Ersatzschlüssel als auch hinzugefügt werden, um als Fremdschlüssel in anderen Tabellen verwendet wird, statt der natürliche Schlüssel ... Aber die natürliche Schlüssel sollte als alternativer Schlüssel oder einen eindeutigen Index bleiben Datenkorruption und enforece Datenbankkonsistenz ...
zu verhindernEin großer Teil der hoohah (in der "Debatte" zu diesem Thema), kann aufgrund dessen, was ist eine falsche Annahme -, dass Sie die Primary Key verwenden für Joins und Fremdschlüssel in anderen Tabellen. DAS IST FALSCH. Sie können ANY Taste als Ziel für die Fremdschlüssel in anderen Tabellen verwenden. Es kann der Primärschlüssel, ein alternativer Schlüssel oder jeder eindeutiger Index oder eindeutige Einschränkung sein. Und was verbindet, kann man alles überhaupt für eine Join-Bedingung verwendet, ist es nicht einmal ein Schlüssel sein, oder ein idex oder sogar einzigartig !! (Obwohl, wenn es nicht eindeutig ist, werden Sie mehrere Zeilen in dem cartesianischen Produkt bekommen es schafft).
Andere Tipps
Natürliche Tasten unterscheiden sich von Ersatzschlüsseln in Wert, geben Sie nicht.
kann ein beliebiger Typ für einen Ersatzschlüssel verwendet werden, wie ein VARCHAR
für das System generierte slug
oder etwas anderes.
Allerdings sind die meisten verwendeten Typen für Ersatzschlüssel sind INTEGER
und RAW(16)
(oder wie auch immer geartete Ihre RDBMS
nicht verwendet für GUID
ist),
Im Vergleich Surrogat ganze Zahlen und natürliche Zahlen (wie SSN
) nimmt genau gleiche Zeit.
Beim Vergleich VARCHAR
s machen take Sortierungs berücksichtigt und sie sind in der Regel länger als ganze Zahlen sind, dass sie weniger effizient.
einen Satz von zwei INTEGER
Vergleich ist wohl auch weniger effizient als ein einzelnes INTEGER
Vergleich.
Auf Datentypen klein dieser Unterschied ist wahrscheinlich Prozent Prozent der Zeit, die benötigten Seiten zu holen, Traverse Indizes, acquite Datenbank Verriegelungen usw.
Und hier sind die Zahlen (in MySQL
):
CREATE TABLE aint (id INT NOT NULL PRIMARY KEY, value VARCHAR(100));
CREATE TABLE adouble (id1 INT NOT NULL, id2 INT NOT NULL, value VARCHAR(100), PRIMARY KEY (id1, id2));
CREATE TABLE bint (id INT NOT NULL PRIMARY KEY, aid INT NOT NULL);
CREATE TABLE bdouble (id INT NOT NULL PRIMARY KEY, aid1 INT NOT NULL, aid2 INT NOT NULL);
INSERT
INTO aint
SELECT id, RPAD('', FLOOR(RAND(20090804) * 100), '*')
FROM t_source;
INSERT
INTO bint
SELECT id, id
FROM aint;
INSERT
INTO adouble
SELECT id, id, value
FROM aint;
INSERT
INTO bdouble
SELECT id, id, id
FROM aint;
SELECT SUM(LENGTH(value))
FROM bint b
JOIN aint a
ON a.id = b.aid;
SELECT SUM(LENGTH(value))
FROM bdouble b
JOIN adouble a
ON (a.id1, a.id2) = (b.aid1, b.aid2);
t_source
ist nur eine Dummy-Tabelle mit 1,000,000
Reihen.
aint
und adouble
, bint
und bdouble
enthalten genau dieselben Daten, mit der Ausnahme, dass eine ganze Zahl aint
als PRIMARY KEY
aufweist, während adouble
ein Paar von zwei gleichen ganzen Zahlen hat.
Auf meinem Rechner beiden Abfragen 14,5 Sekunden laufen, +/- 0,1 Sekunden
Performance Unterschied, wenn überhaupt, in den Schwankungen liegen.