Bei der Arbeit haben wir eine große Datenbank mit eindeutigen Indizes anstelle von Primärschlüsseln und alles funktioniert einwandfrei.
Ich entwerfe eine neue Datenbank für ein neues Projekt und habe ein Dilemma:
In der DB-Theorie ist der Primärschlüssel ein grundlegendes Element, das ist in Ordnung, aber was sind in REAL-Projekten die Vor- und Nachteile beider?
Was verwenden Sie in Projekten?
EDIT: ... und was ist mit Primärschlüsseln und Replikation auf MS SQL Server?
sql
database
database-design
Cicik
quelle
quelle
Antworten:
Was ist ein eindeutiger Index?
Ein eindeutiger Index für eine Spalte ist ein Index für diese Spalte, der auch die Einschränkung erzwingt, dass in dieser Spalte nicht zwei gleiche Werte in zwei verschiedenen Zeilen vorhanden sein dürfen. Beispiel:
Die letzte Einfügung schlägt fehl, weil sie den eindeutigen Index für die Spalte verletzt,
foo
wenn versucht wird, den Wert 1 zum zweiten Mal in diese Spalte einzufügen.In MySQL erlaubt eine eindeutige Einschränkung mehrere NULL-Werte.
Es ist möglich, einen eindeutigen Index für mehrere Spalten zu erstellen.
Primärschlüssel versus eindeutiger Index
Dinge, die gleich sind:
Dinge, die anders sind:
quelle
Sie können es so sehen:
Ein Primärschlüssel ist einzigartig
Ein eindeutiger Wert muss nicht die Darstellung des Elements sein
Bedeutung?; Nun, ein Primärschlüssel wird verwendet, um das Element zu identifizieren. Wenn Sie eine "Person" haben, möchten Sie eine persönliche Identifikationsnummer (SSN oder eine solche) haben, die für Ihre Person primär ist.
Auf der anderen Seite hat die Person möglicherweise eine E-Mail, die eindeutig ist, die Person jedoch nicht identifiziert.
Ich habe immer Primärschlüssel, auch in Beziehungstabellen (der Mitteltabelle / Verbindungstabelle), die ich möglicherweise habe. Warum? Nun, ich folge gerne einem Standard beim Codieren. Wenn die "Person" eine Kennung hat, hat das Auto eine Kennung, dann sollte die Person -> Auto auch eine Kennung haben!
quelle
Fremdschlüssel funktionieren sowohl mit eindeutigen Einschränkungen als auch mit Primärschlüsseln. Aus Online-Büchern:
Für die Transaktionsreplikation benötigen Sie den Primärschlüssel. Aus Online-Büchern:
Beide Antworten beziehen sich auf SQL Server 2005.
quelle
Die Wahl, wann ein Ersatzprimärschlüssel im Gegensatz zu einem natürlichen Schlüssel verwendet werden soll, ist schwierig. Antworten wie immer oder nie sind selten nützlich. Ich finde, dass es von der Situation abhängt.
Als Beispiel habe ich die folgenden Tabellen:
Wir haben zwei Entitätstabellen (
toll_booths
undcars
) und eine Transaktionstabelle (drive_through
). Dietoll_booth
Tabelle verwendet einen Ersatzschlüssel, da sie kein natürliches Attribut enthält, dessen Änderung nicht garantiert werden kann (der Name kann leicht geändert werden). Diecars
Tabelle verwendet einen natürlichen Primärschlüssel, da sie einen unveränderlichen eindeutigen Bezeichner (vin
) hat. Diedrive_through
Transaktionstabelle verwendet einen Ersatzschlüssel zur einfachen Identifizierung, unterliegt jedoch auch einer eindeutigen Einschränkung für die Attribute, die zum Zeitpunkt des Einfügens des Datensatzes garantiert eindeutig sind.http://database-programmer.blogspot.com hat einige großartige Artikel zu diesem speziellen Thema.
quelle
Primärschlüssel haben keine Nachteile.
Um nur einige Informationen zu den Antworten von @MrWiggles und @Peter Parker hinzuzufügen: Wenn die Tabelle beispielsweise keinen Primärschlüssel hat, können Sie in einigen Anwendungen keine Daten bearbeiten (sie sagen am Ende, dass etw ohne Daten nicht bearbeitet / gelöscht werden kann Primärschlüssel). Postgresql erlaubt, dass sich mehrere NULL-Werte in der Spalte UNIQUE befinden. PRIMARY KEY erlaubt keine NULL-Werte. Auch einige ORM, die Code generieren, können Probleme mit Tabellen ohne Primärschlüssel haben.
AKTUALISIEREN:
Soweit ich weiß, ist es nicht möglich, Tabellen ohne Primärschlüssel in MSSQL zu replizieren, zumindest nicht ohne Probleme ( Details ).
quelle
Wenn etwas ein Primärschlüssel ist, wird abhängig von Ihrer DB-Engine die gesamte Tabelle nach dem Primärschlüssel sortiert. Dies bedeutet, dass die Suche auf dem Primärschlüssel viel schneller ist, da keine Dereferenzierung durchgeführt werden muss, wie dies bei jeder anderen Art von Index der Fall ist. Abgesehen davon ist es nur Theorie.
quelle
Zusätzlich zu den anderen Antworten erfordern einige Datenbanken und Systeme möglicherweise, dass eine Primärdatenbank vorhanden ist. Eine Situation fällt mir ein; Bei Verwendung der Unternehmensreplikation mit Informix muss eine PK vorhanden sein, damit eine Tabelle an der Replikation teilnehmen kann.
quelle
Solange Sie NULL für einen Wert nicht zulassen, sollten sie gleich behandelt werden, aber der Wert NULL wird in Datenbanken unterschiedlich behandelt (AFAIK MS-SQL erlaubt nicht mehr als einen (1) NULL-Wert, mySQL und Oracle erlauben dies , wenn eine Spalte EINZIGARTIG ist) Sie müssen diese Spalte also NICHT NULL EINZIGARTIGER INDEX definieren
quelle
In der relationalen Datentheorie gibt es keinen Primärschlüssel, daher muss Ihre Frage auf praktischer Ebene beantwortet werden.
Eindeutige Indizes sind nicht Teil des SQL-Standards. Die spezielle Implementierung eines DBMS bestimmt, welche Konsequenzen die Deklaration eines eindeutigen Index hat.
Wenn Sie in Oracle einen Primärschlüssel deklarieren, wird in Ihrem Namen ein eindeutiger Index erstellt, sodass die Frage fast umstritten ist. Ich kann Ihnen nichts über andere DBMS-Produkte erzählen.
Ich bevorzuge die Angabe eines Primärschlüssels. Dies hat zur Folge, dass NULL-Werte in den Schlüsselspalten verboten und Duplikate verboten werden. Ich bevorzuge es auch, REFERENCES-Einschränkungen zu deklarieren, um die Integrität der Entität durchzusetzen. In vielen Fällen beschleunigt das Deklarieren eines Index für die Coulmn eines Fremdschlüssels die Verknüpfungen. Diese Art von Index sollte im Allgemeinen nicht eindeutig sein.
quelle
Es gibt einige Nachteile von CLUSTERED INDEXES gegenüber UNIQUE INDEXES.
Wie bereits erwähnt, ordnet ein CLUSTERED INDEX die Daten in der Tabelle physisch an.
Dies bedeutet, dass bei physischen Einfügungen oder Löschungen in einer Tabelle mit einem Clustered-Index die physische Tabelle jedes Mal (fast abhängig von Ihrem Füllfaktor) aktualisiert werden muss, um sortiert zu bleiben.
In relativ kleinen Tabellen ist dies in Ordnung, aber wenn Sie zu Tabellen mit Daten im Wert von GB gelangen und Einfügungen / Löschungen die Sortierung beeinflussen, treten Probleme auf.
quelle
Ich erstelle fast nie eine Tabelle ohne numerischen Primärschlüssel. Wenn es auch einen natürlichen Schlüssel gibt, der eindeutig sein sollte, setze ich auch einen eindeutigen Index darauf. Verknüpfungen sind bei Ganzzahlen schneller als mehrspaltige natürliche Schlüssel. Daten müssen sich nur an einer Stelle ändern (natürliche Schlüssel müssen in der Regel aktualisiert werden, was in Beziehungen zwischen Primärschlüssel und Fremdschlüssel eine schlechte Sache ist). Wenn Sie eine Replikation benötigen, verwenden Sie eine GUID anstelle einer Ganzzahl. Zum größten Teil bevorzuge ich jedoch einen Schlüssel, der vom Benutzer gelesen werden kann, insbesondere wenn er zur Unterscheidung zwischen John Smith und John Smith angezeigt werden muss.
Ich erstelle selten einen Ersatzschlüssel, wenn ich eine Verbindungstabelle habe, die in eine Viele-zu-Viele-Beziehung verwickelt ist. In diesem Fall deklariere ich beide Felder als Primärschlüssel.
quelle
Nach meinem Verständnis sind ein Primärschlüssel und ein eindeutiger Index mit einer Nicht-Null-Einschränkung identisch (*). und ich nehme an, einer wählt den einen oder anderen, je nachdem, was in der Spezifikation explizit angegeben oder impliziert wird (eine Frage dessen, was Sie ausdrücken und explizit durchsetzen möchten). Wenn es Eindeutigkeit und nicht Null erfordert, machen Sie es zu einem Primärschlüssel. Wenn es einfach passiert, dass alle Teile eines eindeutigen Index nicht null sind, ohne dass dies erforderlich ist, machen Sie ihn einfach zu einem eindeutigen Index.
Der einzige verbleibende Unterschied besteht darin, dass Sie möglicherweise mehrere eindeutige Indizes haben, die nicht null sind, während Sie nicht mehrere Primärschlüssel haben können.
(*) Mit Ausnahme eines praktischen Unterschieds: Ein Primärschlüssel kann der standardmäßige eindeutige Schlüssel für einige Vorgänge sein, z. B. das Definieren eines Fremdschlüssels. Ex. Wenn man einen Fremdschlüssel definiert, der auf eine Tabelle verweist, und den Spaltennamen nicht angibt, wenn die referenzierte Tabelle einen Primärschlüssel hat, ist der Primärschlüssel die referenzierte Spalte. Andernfalls muss die Spalte, auf die verwiesen wird, explizit benannt werden.
Andere hier haben die DB-Replikation erwähnt, aber ich weiß nichts darüber.
quelle
Der eindeutige Index kann einen NULL-Wert haben. Es wird NON-CLUSTERED INDEX erstellt. Der Primärschlüssel darf keinen NULL-Wert enthalten. Es wird ein CLUSTERED INDEX erstellt.
quelle
In MSSQL sollten die Primärschlüssel monoton ansteigen, um die beste Leistung für den Clustered-Index zu erzielen. Daher ist eine Ganzzahl mit Identitätseinfügung besser als jeder natürliche Schlüssel, der möglicherweise nicht monoton ansteigt.
quelle
Wenn es nach mir ginge ...
Sie müssen die Anforderungen der Datenbank und Ihrer Anwendungen erfüllen.
Durch Hinzufügen einer automatisch inkrementierenden Ganzzahl- oder langen ID-Spalte zu jeder Tabelle als Primärschlüssel werden die Datenbankanforderungen berücksichtigt.
Anschließend fügen Sie der Tabelle mindestens einen weiteren eindeutigen Index zur Verwendung durch Ihre Anwendung hinzu. Dies wäre der Index für employee_id oder account_id oder customer_id usw. Wenn möglich, sollte dieser Index kein zusammengesetzter Index sein.
Ich würde Indizes für mehrere Felder einzeln gegenüber zusammengesetzten Indizes bevorzugen. Die Datenbank verwendet die einzelnen Feldindizes immer dann, wenn die where-Klausel diese Felder enthält. Sie verwendet jedoch nur einen Verbund, wenn Sie die Felder in genau der richtigen Reihenfolge angeben. Dies bedeutet, dass das zweite Feld in einem zusammengesetzten Index nur verwendet werden kann, wenn Sie dies angeben sowohl die erste als auch die zweite in Ihrer where-Klausel.
Ich bin alle für die Verwendung von berechneten oder Funktionstyp-Indizes - und würde empfehlen, sie über zusammengesetzte Indizes zu verwenden. Es macht es sehr einfach, den Funktionsindex zu verwenden, indem dieselbe Funktion in Ihrer where-Klausel verwendet wird.
Dies kümmert sich um Ihre Anwendungsanforderungen.
Es ist sehr wahrscheinlich, dass andere nicht-primäre Indizes tatsächlich Zuordnungen dieses Indexschlüsselwerts zu einem Primärschlüsselwert sind, nicht zu Rowid (). Dies ermöglicht physische Sortiervorgänge und Löschvorgänge, ohne dass diese Indizes neu erstellt werden müssen.
quelle