2009-07-01 1 views
2

Gibt es einen Grund, ein einzelnes inkrementieren Feld für einen Primärschlüssel anstelle von mehreren Feldern zu verwenden, die den eindeutigen Datensatz tatsächlich darstellen?Single Autonumber statt Multiple Key

Ich arbeite an einer bestehenden PHP-Anwendung, und die Tabellen scheinen alle einen einzigen "ID" -Schlüssel zu haben, anstatt die 2 oder mehr Felder zu verwenden, die tatsächlich für den Datensatz einzigartig sind (wie Benutzer, Auktion, Gebot) .

Ich bin kein Datenbank-Experte, aber das scheint mir nur faul (oder unerfahren). Gibt es einen Vorteil (Leistung oder anders)?

Aktualisiert: Ich beziehe mich nicht auf psudo-einzigartige Daten (ssn, E-Mail-Adresse, etc.), wo Sie sicherstellen möchten, dass die Daten wirklich einzigartig sind. Ich spreche von Tabellen mit offensichtlichen Fremdschlüsselreferenzen, aber anstatt diese Referenzen zusammen mit den eindeutigen Feldern in der Tabelle selbst zu verwenden, hat jede Tabelle nur eine inkrementierende ID.

Nicht versuchen, eine subjektive Debatte zu starten, es ergab nur keinen Sinn für mich.

Antwort

5

synthetische Primärschlüssel verwenden hat mehrere Vorteile:

  • Sie können ohne Werte in Schlüsselfeldern ändern, um eine Indexaktualisierung nehmen Hit
  • Die Indizes sind kleiner
  • es einfache Fremdschlüsselbeziehungen macht
  • Da es sich nicht um Zeichenketten handelt, gibt es keine Codierungsprobleme.

Da Tabasen haben oft spezifische Optimierungen zum Erstellen von Indizes mit monoton inkrementierenden Schlüsseln.

Das gesagt, es ist nichts falsch mit ein wenig Denormalisierung hin und wieder. Wenn der Anwendungsfall klar ist und die Tabellen relativ klein sind, tun Sie, was praktisch ist.

+0

-1 "Es ist nichts falsch mit einer kleinen Denormalisierung hin und wieder" – onedaywhen

5

Es hängt von der Definition von "Unique" ab. Ja, Namen, E-Mail-Adressen und SSN-Werte sollen "einzigartig" sein. Fremde Dinge sind jedoch passiert. einen separaten ID-Wert, in vielen Fällen ist, kann viel machen das Leben leichter ...

aktualisieren

Basierend auf der Bearbeitung auf die Frage, sehe ich nicht wirklich viel von einer Notwendigkeit, . Es klingt wie die Situation, die Sie haben, ist etwas wie. eine "Join-Tabelle", etwas, wo Sie einfach eine Zuordnung einer UniqueId von einer Tabelle zur UniqueId einer anderen Tabelle erstellen.

Ein einfaches Beispiel für das, worüber ich spreche, wäre ein Benutzer -> Rollenassoziation. Sie müssen einen Benutzer einer Rolle zuordnen. Eine UserId und eine RoleId.

Sie haben in Ihrer Datenbank eine Struktur ähnlich

MappingId (Your Auto Number) (This is the PK) 
UserId (From the user table) 
RoleId (From the Role table) 

Diese Struktur keinen Sinn für mich macht, hätte ich nur die User und RoleId die Primärschlüssel bilden, da es keine Notwendigkeit gibt, zu duplizieren Einträge hier.

Wenn Sie etwas anderes haben, die Dinge ändern könnten ...

+0

Einverstanden. Normalerweise entscheide ich mich für einen synthetischen Primärschlüssel, füge dann aber einen Index mit einer Eindeutigkeitsbeschränkung hinzu, um den natürlichen Schlüssel zu identifizieren. Auf diese Weise kann ich den Index ändern/löschen, wenn meine ursprünglichen Annahmen während des Entwurfs nicht mehr gelten. – Adamski

+0

SSNs werden im Laufe der Zeit wiederverwendet. Immerhin wird die Zahl der Menschen, die in den USA leben, auf 306.808.431 geschätzt, entsprechend der US-Census-Bevölkerungstaktung ... fast 1/3 des verfügbaren Raums für SSNs. – Powerlord

+0

Aktualisiert die Frage, um es klarer zu machen, nicht über fragwürdig eindeutige Daten zu sprechen. Ich meine eine Tabelle mit einer Benutzer-ID, einer Auktions-ID usw., aber sie hat einen einzigen automatisch inkrementierenden Primärschlüssel. –

0

Nun geben die ids eine sequentielle Ordnung in Ihre Datenbank von 1 bis unendlich. Benutzernamen und dergleichen sind vorübergehend und nicht immer geordnet. Also, vermutlich würde es das Suchen schneller machen. Außerdem scheint es so, als würden Sie vorschlagen, mehrere Schlüssel für einen Gegenstand zu haben. Das wird die Dinge im Allgemeinen verlangsamen, weil jetzt zwei Dinge überprüft werden müssen, um sicherzustellen, dass etwas das richtige Element ist statt eines.

1

Normalerweise möchten Sie einen Clustered-Index für Ihren Primärschlüssel. Das Problem mit einem zusammengesetzten, gruppierten Primärschlüssel ist, dass SQL beim Einfügen neuer Zeilen den neuen Datensatz zwischen andere Datensätze stecken muss, was Mischen bedeutet. Je größer der Primärschlüssel ist, desto mehr Speicherplatz wird benötigt.

Here ist ein Artikel über die Verwendung einer GUID als Primärschlüssel, aber das gleiche gilt für einen zusammengesetzten Schlüssel.

Siehe auch this great answer.

3

Oh mein Gott, es sieht so aus, als ob wir die Debatte über große natürliche vs Ersatzschlüssel wieder eröffnen.

Der einfachste Grund ist, Datenredundanz zu verhindern. Natürliche Schlüssel erfordern häufig mehrere Schlüssel, die sich im Laufe der Lebensdauer der Datenbank ändern können.

Wenn beispielsweise eine Person heiratet und ihren Nachnamen ändert, muss dieser Nachname überall dort aktualisiert werden, wo er referenziert wird.

Dies ist kein Problem, wenn Sie Ihre Fremdschlüssel auf Update-Kaskade eingestellt haben, wie die DB es für Sie tun wird.

Da Ihr Tisch immer weiter nistet, werden Ihre Schlüssel möglicherweise immer mehr Spalten benötigen. Ich habe tatsächlich eine Tabelle mit einem siebenspaltigen Primärschlüssel gesehen. Für eine Tabelle, die nur vier andere Spalten hatte.

+0

Ein Englisch: www.doc-o-matic.com/webhelp/TdlgEditEdit.html Der Code ist nun dafür verantwortlich, nach doppelten Daten zu suchen, anstatt die Datenbank anzuhalten, um doppelte Daten anzuhalten.Bei dem Code, der zu dieser Frage geführt hat, muss der Code vor der Einreichung eines Auktionsangebots die Datenbank nach Angeboten durchsuchen der gleiche Wert von demselben Benutzer für die gleiche Auktion.Sure sollte es auf jeden Fall tun, aber wenn der Code fehlschlägt, wird die Datenbank es nicht stoppen.In diesem Fall gibt es doppelte Daten. –

+0

R. Bemrose schrieb: Das ist nicht ein Problem, wenn Sie Ihre Fremdschlüssel auf Update-Kaskade eingestellt haben, wie die DB es für Sie tun wird Aber alle Verweise auf diesen Datensatz außerhalb Ihrer Datenbank sind verloren Schnittstellen zu anderen Systemen haben Sie in Schwierigkeiten. –

+0

@Tim Lytle: Es gibt nichts, was Sie daran hindert, einzigartige Einschränkungen zu haben. – Powerlord

0

Hier sind ein paar Punkte Automatische Nummerierung

  • automatische Nummerierung ist ein einziges eindeutigen Schlüssel zu verwenden, die Fremdschlüsselbeziehungen viel einfacher macht

    automatische Nummerierung Zahlen zu erhalten und zu verwenden sind, so dass es ziemlich einfach ist, um sie zu benutzen und nicht zu verwirren sie auf.Was ich meine ist, wenn Ihre Primärschlüssel ein String und Ihre Entwickler vergessen, dass in einfachen Anführungszeichen um es Ihre Leistung zerstört

    Es ist normal üblich ein Auto

    Sie können zu verwenden, noch machen andere Felder „einzigartig“

    eine Sequenz Zurücksetzen ist viel einfacher, mit einem Autowert

    wenn Sie im voraus in der Folge springen müssen, ist es viel einfacher, mit einem Nummer als eine Combo von Attributen oder Strings

Nur ein paar Dinge ...

0

in den meisten Fällen, es ist wirklich nicht eindeutig, wenn diese Felder wirklich die Entität eindeutig durch den Datensatz repräsentiert identifizieren . Immer wieder habe ich Fälle gesehen, in denen alte, in der Geschäftsmentalität verankerte Datenbankkonzepte jede weitere Entwicklung behindern.

0

Ja, das wird die Debatte anstacheln.

Im Allgemeinen sollten Primärschlüsseldaten unveränderlich sein, was bei Verwendung eines aus den Tabellendaten abgeleiteten natürlichen Schlüssels häufig nicht der Fall ist. Wie bereits erwähnt, können Dinge wie SSN oft geändert werden, wodurch Unveränderlichkeit verloren geht.

Monoton ansteigende Ersatzschlüssel, wie die Spalten "autonumber" oder "identity", sind ein einfacher Ersatz für einen natürlichen Schlüssel. Sie können jedoch anfällig für Indexineffizienzen sein, da sie möglicherweise nicht gut über B-Tree-Indexalgorithmen balancieren. Dies kann durch die Verwendung eines zufällig generierten Ersatzschlüssels, wie zum Beispiel eines eindeutigen Identifikators, d. H. GUID, in MS SQL Server behoben werden, aber ich habe gelesen, dass dies auch Auswirkungen auf die Leistung hat.

Im Allgemeinen verwende ich einen Ersatzschlüssel aus einer sequentiellen Funktion wie Autonummer oder Identität zur Erleichterung der Tabellen Joins.

0

Fast jede "natürliche" Tastenkombination, die ich jemals in einer Datenbank verwendet habe, war im Laufe der Zeit nicht eindeutig. Datenmodelle müssen sich schnell entwickeln, da Abstraktionen undicht werden.

Dazu gehören Namen, Telefonnummern, SSNs, rechtliche Dokumente Referenzen, Seitenzahlen, E-Mail-Adressen, Benutzernamen, Projektnummern und ein paar andere Dinge, die ich im Laufe meiner Karriere versucht habe zu verwenden.

Abgesehen davon sind die anderen Antworten in Bezug auf die Leistung für das Schreiben neuer Datensätze, den Vergleich von Fremdschlüsseln usw. Grund genug.

Sie können Ihre aktuelle Geschäftslogik der Einzigartigkeit beibehalten, ohne sie in den Primärschlüssel zu integrieren - richten Sie einfach einen eindeutigen Index für Ihre Natural-Key-Spalten ein. Sie zahlen einen Preis für Einfügungen und Updates, wie mit jedem Index, aber wenn es auch ein nützlicher Index ist (hilft, einige Fragen zu decken), alles besser.

+0

Wenn also der 'natürliche' Schlüssel durch einen Ersatzschlüssel ersetzt wird, sagen wir, ein Benutzername wird eine Benutzer-ID (eindeutige generierte Nummer), warum nicht die Benutzer-ID (zusammen mit anderen unveränderlichen IDs) als Schlüssel für verwandte Tabellen verwenden? –

+0

Ein PK ist per Definition einzigartig. Für Argumentationszwecke haben Sie soeben ein PK erstellt, jedes Mal, wenn eine eindeutige Einschränkung erstellt wird. Warum nicht einfach den Tisch abbrechen und durch eine Aussicht ersetzen? – WolfmanDragon

0

Es kommt alles darauf an, wie "normal" Ihre Datenstruktur ist. Eine hoch normalisierte Datenbank kann definitionsgemäß nur ein einzelnes Feld für den Primärschlüssel haben. In diesem Fall gibt es wenig Grund, eine serielle oder automatisch generierte Nummer als PK zu verwenden. Die Datenstruktur sollte mit eindeutigen Einträgen als PK gestaltet werden (Tracking-Leute sind ein Problem, es gibt nur so viele Namen).

Natürlich mit der Normalisierung kommt die Leistungseinbuße, so dass die Datenbank de-normalisiert ist, um nutzbar zu machen (sehr häufig für Web-Anwendungen). Bei einer stark de-normalisierten DB ist es oft unmöglich, eine PK zu erhalten, ohne jedes Feld in der Tabelle zu verwenden. Beachten Sie, dass der Grund für die De-Normalisierung der Struktur darin besteht, die Leistung zu erhöhen. Alle Datenbanken, mit denen ich vertraut bin, erstellen einen Index für jede PK. Je größer der Index ist, desto größer ist der Overhead, um den Index zu erhalten.

Das Erstellen von gigantischen Indizes wird die Einfüge- und Aktualisierungszeit der Leistung zunichte machen, wodurch die De-Normalisierung nutzlos wird (es sei denn, es handelt sich um eine schreibgeschützte Datenbank). Es dauert auch länger, gigantische Indizes zu suchen und mehr Speicher als kleinere zu verwenden.

Im Allgemeinen ist es aus Leistungsgründen oft vorteilhaft, die PK für jede Tabelle automatisch zu generieren, die mehrere Felder benötigt, um eine eindeutige PK zu erhalten.