web-dev-qa-db-ger.com

Primärschlüssel oder eindeutiger Index?

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. In REAL-Projekten: Welche Vor- und Nachteile haben beide?

Was verwenden Sie in Projekten?

EDIT: ... und wie sieht es mit Primärschlüsseln und Replikation auf MS SQL Server aus?

116
Cicik

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 Sie in dieser Spalte nicht zwei gleiche Werte in zwei verschiedenen Zeilen haben dürfen. Beispiel:

 CREATE TABLE table1 (foo int, bar int); 
 CREATE UNIQUE INDEX ux_table1_foo ON table1 (foo); - Erstellen Sie einen eindeutigen Index für foo. 
 
 INSERT IN table1 (foo, bar) VALUES (1, 2); - OK 
 INSERT INTO table1 (foo, bar) VALUES (2, 2); - OK 
 INSERT IN Tabelle1 (foo, bar) WERTE (3, 1); - OK 
 INSERT IN Tabelle1 (foo, bar) WERTE (1, 4); - Fehler! 
 
 Doppelter Eintrag '1' für Schlüssel 'ux_table1_foo' 

Die letzte Einfügung schlägt fehl, weil der eindeutige Index für die Spalte foo verletzt wird, 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:

  • Ein Primärschlüssel impliziert einen eindeutigen Index.

Dinge, die anders sind:

  • Ein Primärschlüssel impliziert auch NOT NULL, aber ein eindeutiger Index kann nullwertfähig sein.
  • Es kann nur einen Primärschlüssel geben, es können jedoch mehrere eindeutige Indizes vorhanden sein.
  • Wenn kein Clustered-Index definiert ist, ist der Primärschlüssel der Clustered-Index.
156
Mark Byers

Sie können es so sehen:

Ein Primärschlüssel IS Unique

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), die für Ihre Person primär ist.

Auf der anderen Seite könnte die Person eine E-Mail haben, 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 einer Norm bei der Codierung. Wenn die "Person" eine Kennung hat, hat das Auto eine Kennung. Nun, dann sollte die Person -> Auto auch eine Kennung haben!

30
Filip Ekberg

Fremdschlüssel arbeiten sowohl mit eindeutigen Einschränkungen als auch mit Primärschlüsseln. Aus der Onlinedokumentation:

Eine FOREIGN KEY-Einschränkung muss nicht nur mit einer PRIMARY KEY-Einschränkung in einer anderen Tabelle verknüpft sein. Es kann auch definiert werden, um auf die Spalten einer UNIQUE-Einschränkung in einer anderen Tabelle zu verweisen

Für die Transaktionsreplikation benötigen Sie den Primärschlüssel. Aus der Onlinedokumentation:

Tabellen, die für die Transaktionsreplikation veröffentlicht wurden, müssen einen Primärschlüssel haben. Wenn sich eine Tabelle in einer Transaktionsreplikationspublikation befindet, können Sie keine Indizes deaktivieren, die Primärschlüsselspalten zugeordnet sind. Diese Indizes werden für die Replikation benötigt. Um einen Index zu deaktivieren, müssen Sie zuerst die Tabelle aus der Publikation löschen.

Beide Antworten beziehen sich auf SQL Server 2005.

8
Jonas Lincoln

Die Wahl, wann ein Ersatz-Primärschlüssel anstelle eines natürlichen Schlüssels verwendet werden soll, ist schwierig. Antworten wie immer oder nie sind selten nützlich. Ich finde, dass es auf die Situation ankommt.

Als Beispiel habe ich die folgenden Tabellen:

CREATE TABLE toll_booths (
    id            INTEGER       NOT NULL PRIMARY KEY,
    name          VARCHAR(255)  NOT NULL,
    ...
    UNIQUE(name)
)

CREATE TABLE cars (
    vin           VARCHAR(17)   NOT NULL PRIMARY KEY,
    license_plate VARCHAR(10)   NOT NULL,
    ...
    UNIQUE(license_plate)
)

CREATE TABLE drive_through (
    id            INTEGER       NOT NULL PRIMARY KEY,
    toll_booth_id INTEGER       NOT NULL REFERENCES toll_booths(id),
    vin           VARCHAR(17)   NOT NULL REFERENCES cars(vin),
    at            TIMESTAMP     DEFAULT CURRENT_TIMESTAMP NOT NULL,
    amount        NUMERIC(10,4) NOT NULL,
    ...
    UNIQUE(toll_booth_id, vin)
)

Wir haben zwei Entitätstabellen (toll_booths und cars) und eine Transaktionstabelle (drive_through). Das toll_booth table verwendet einen Ersatzschlüssel, da es kein natürliches Attribut gibt, dessen Änderung nicht garantiert ist (der Name kann leicht geändert werden). Die Tabelle cars verwendet einen natürlichen Primärschlüssel, da sie einen unveränderlichen eindeutigen Bezeichner (vin) hat. Das drive_through Transaktionstabelle verwendet einen Ersatzschlüssel zur einfachen Identifizierung, hat jedoch auch eine eindeutige 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.

5
aekeus

Es gibt keine Nachteile von Primärschlüsseln.

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 nicht ohne Daten bearbeitet/gelöscht werden kann) Primärschlüssel). Postgresql erlaubt es, dass mehrere NULL-Werte in der UNIQUE-Spalte stehen, PRIMARY KEY erlaubt keine NULL-Werte. Einige ORMs, die Code generieren, können auch 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 ohne Probleme ( Details ).

4
empi

Da es in der relationalen Datentheorie keinen Primärschlüssel gibt, muss Ihre Frage auf praktischer Ebene beantwortet werden.

Eindeutige Indizes sind nicht Bestandteil des SQL-Standards. Die jeweilige 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 unbeantwortet bleibt. Ich kann Ihnen nichts über andere DBMS-Produkte erzählen.

Ich bevorzuge die Deklaration eines Primärschlüssels. Dies hat zur Folge, dass NULL-Werte in den Schlüsselspalten sowie Duplikate verboten werden. Ich befürworte auch die Deklaration von REFERENCES-Einschränkungen, um die Integrität der Entität durchzusetzen. In vielen Fällen beschleunigt das Deklarieren eines Index für die Coulmn (s) eines Fremdschlüssels die Verknüpfungen. Diese Art von Index sollte im Allgemeinen nicht eindeutig sein.

2
Walter Mitty

Wenn es sich bei etwas um einen Primärschlüssel handelt, wird abhängig von Ihrer DB-Engine die gesamte Tabelle nach dem Primärschlüssel sortiert. Dies bedeutet, dass Suchvorgänge auf dem Primärschlüssel viel schneller sind, da keine Dereferenzierung durchgeführt werden muss, wie dies bei jeder anderen Art von Index der Fall ist. Ansonsten ist es nur Theorie.

2
Ray Hidayat

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 lässt nicht mehr als einen (1) NULL-Wert zu, mySQL und Oracle lassen dies zu , wenn eine Spalte EINZIGARTIG ist) Also muss definieren Sie diese Spalte NICHT NULL EINZIGARTIG INDEX

2
Peter Parker

Zusätzlich zu dem, was die anderen Antworten gesagt haben, können einige Datenbanken und Systeme erfordern 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.

1
tddmonkey

Ich verstehe, dass ein Primärschlüssel und ein eindeutiger Index mit einer Nicht-Null-Einschränkung identisch sind (*). und ich nehme an, einer wählt den einen oder anderen, je nachdem, was die Spezifikation ausdrücklich festlegt oder impliziert (eine Frage dessen, was Sie ausdrücken und explizit durchsetzen wollen). Wenn Eindeutigkeit und Nicht-Null erforderlich sind, machen Sie es zu einem Primärschlüssel. Wenn dies nur der Fall ist, sind alle Teile eines eindeutigen Index nicht null, 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 Nicht-Null-Indizes haben, während Sie nicht mehrere Primärschlüssel haben können.

(*) Mit Ausnahme eines praktischen Unterschieds: Ein Primärschlüssel kann für einige Vorgänge, z. B. das Definieren eines Fremdschlüssels, der standardmäßige eindeutige Schlüssel sein. Ex. Wenn ein Fremdschlüssel definiert wird, der auf eine Tabelle verweist, und der Spaltenname nicht angegeben wird, und die referenzierte Tabelle einen Primärschlüssel enthält, ist der Primärschlüssel die referenzierte Spalte. Andernfalls muss die referenzierte Spalte explizit benannt werden.

Andere hier haben DB-Replikation erwähnt, aber ich weiß nicht darüber.

1
Hibou57

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 vielen Einfügungen oder Löschvorgängen in einer Tabelle, die einen Clustered-Index enthält, die physische Tabelle jedes Mal aktualisiert werden muss, um sortiert zu bleiben, wenn Sie die Daten ändern (fast je nach Füllfaktor).

In relativ kleinen Tabellen ist dies in Ordnung. Wenn Sie jedoch zu Tabellen mit GB-Daten gelangen und Eingaben/Löschungen die Sortierung beeinflussen, treten Probleme auf.

1
Nico Bester

Ich erstelle fast nie eine Tabelle ohne einen numerischen Primärschlüssel. Wenn es auch einen natürlichen Schlüssel gibt, der eindeutig sein soll, lege ich auch einen eindeutigen Index darauf. Joins sind bei Ganzzahlen schneller als bei mehrspaltigen natürlichen Schlüsseln. Daten müssen nur an einer Stelle geändert werden (natürliche Schlüssel müssen in der Regel aktualisiert werden, was bei 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, aber zum größten Teil bevorzuge ich einen Schlüssel, der vom Benutzer lesbar ist, insbesondere wenn er zur Unterscheidung zwischen John Smith und John Smith.

Die wenigen Male, in denen ich keinen Ersatzschlüssel erstelle, habe ich eine Verknüpfungstabelle, die in eine Viele-zu-Viele-Beziehung verwickelt ist. In diesem Fall deklariere ich beide Felder als Primärschlüssel.

1
HLGEM

Der eindeutige Index kann einen NULL-Wert haben. Es wird ein NICHT CLUSTERED INDEX erstellt. Der Primärschlüssel darf keinen NULL-Wert enthalten. Es erstellt CLUSTERED INDEX.

0
Chirag

In MSSQL sollten Primärschlüssel monoton ansteigen, um die beste Leistung für den Clustered-Index zu erzielen. Daher ist eine Ganzzahl mit Identitäts-Einfügung besser als jeder natürliche Schlüssel, der nicht monoton ansteigt.

0
Markus