20 Stimmen

Gründe, die gegen die Verwendung einer automatisch inkrementierenden Zahl für einen Primärschlüssel sprechen

Ich arbeite derzeit an der Datenbank eines anderen Unternehmens, in der die Primärschlüssel über eine Nachschlagetabelle generiert werden, die eine Liste von Tabellennamen und den zuletzt verwendeten Primärschlüssel enthält. Eine gespeicherte Prozedur erhöht diesen Wert und prüft, ob er eindeutig ist, bevor sie ihn an die aufrufende "insert"-SP zurückgibt.

Welche Vorteile hat die Verwendung einer solchen Methode (oder das Generieren einer GUID) anstelle der Verwendung der Identitäts-/Autonummer?

Ich spreche nicht von Primärschlüsseln, die tatsächlich etwas "bedeuten", wie ISBNs oder Produktcodes, sondern nur von den eindeutigen Bezeichnern.

Danke.

27voto

Galwegian Punkte 40819

Eine automatisch generierte ID kann in Situationen, in denen Sie mit Replikation arbeiten, zu Problemen führen (ich bin mir sicher, dass dies bei den von Ihnen gefundenen Techniken der Fall ist). In diesen Fällen entscheide ich mich in der Regel für eine GUID.

Wenn Sie wahrscheinlich keine Replikation verwenden werden, wird eine automatisch inkrementierende PK höchstwahrscheinlich gut funktionieren.

1 Stimmen

Können Sie ein Beispiel für eine Replikation nennen? Können wir bei der Replikation nicht den Identitätseintrag für die automatisch generierte ID verwenden?

0 Stimmen

@ivorykoder Wenn zwei Datenbanken beide eine neue Zeile (und damit eine neue ID) erzeugen und dann versuchen, sie zu synchronisieren, kommt es zu einem Konflikt, da zwei verschiedene Zeilen in der Tabelle unterschiedliche PKs haben werden. Wenn Sie GUIDs verwenden, ist praktisch garantiert, dass die PKs eindeutig sind.

20voto

Greg Smalter Punkte 6333

Gegen die Verwendung von AutoNumber ist an sich nichts einzuwenden, aber es gibt ein paar Gründe, die dagegen sprechen. Dennoch ist es nicht die beste Idee, eine eigene Lösung zu entwickeln, wie dacracot erwähnte. Lassen Sie mich das erklären.

Der erste Grund, AutoNumber nicht für jede Tabelle zu verwenden, ist, dass Sie am Ende Datensätze aus mehreren Tabellen zusammenführen können. Angenommen, Sie haben eine Auftragstabelle und eine andere Art von Auftragstabelle, und Sie beschließen, einige gemeinsame Daten herauszuziehen und die Vererbung mehrerer Tabellen zu verwenden. Es ist gut, Primärschlüssel zu haben, die global eindeutig sind. Das ist ähnlich wie das, was bobwienholt über das Zusammenführen von Datenbanken gesagt hat, aber es kann auch innerhalb einer Datenbank geschehen.

Zweitens verwenden andere Datenbanken dieses Paradigma nicht, und andere Paradigmen wie die Sequenzen von Oracle sind weitaus besser. Glücklicherweise ist es möglich, Oracle-Sequenzen mit SQL Server zu imitieren. Eine Möglichkeit besteht darin, eine einzige AutoNumber-Tabelle für Ihre gesamte Datenbank zu erstellen, die MainSequence oder so heißt. Keine andere Tabelle in der Datenbank wird AutoNumber verwenden, aber jede Tabelle, die einen automatisch generierten Primärschlüssel benötigt, wird MainSequence verwenden, um diesen zu erhalten. Auf diese Weise erhalten Sie alle integrierten Leistungsmerkmale, Sperren, Thread-Sicherheit usw., von denen dacracot gesprochen hat, ohne dass Sie sie selbst erstellen müssen.

Eine andere Möglichkeit ist die Verwendung von GUIDs für Primärschlüssel, aber das empfehle ich nicht, denn selbst wenn Sie sicher sind, dass ein Mensch (sogar ein Entwickler) sie niemals lesen wird, wird es wahrscheinlich jemand tun, und das ist schwierig. Und was noch wichtiger ist, Dinge lassen sich in T-SQL sehr leicht implizit in Ints umwandeln, aber es kann sehr schwierig sein, sie implizit in eine GUID umzuwandeln. Im Grunde sind sie unbequem.

Beim Aufbau eines neuen Systems würde ich empfehlen, eine eigene Tabelle für die Erzeugung von Primärschlüsseln zu verwenden (genau wie bei Oracle-Sequenzen). Bei einer bestehenden Datenbank würde ich mir nicht die Mühe machen, sie zu ändern.

10voto

andyhky Punkte 1728

Von CodingHorror :

GUID-Profis

  • Eindeutig für jede Tabelle, jede Datenbank und jeden Server
  • Ermöglicht die einfache Zusammenführung von Datensätzen aus verschiedenen Datenbanken
  • Ermöglicht die einfache Verteilung von Datenbanken auf mehrere Server
  • Sie können überall IDs generieren, anstatt einen Roundtrip zur Datenbank machen zu müssen.
  • Die meisten Replikationsszenarien erfordern ohnehin GUID-Spalten

GUID Nachteile

  • Er ist satte viermal größer als der herkömmliche 4-Byte-Indexwert; dies kann schwerwiegende Auswirkungen auf die Leistung und den Speicherplatz haben, wenn Sie nicht vorsichtig sind
  • Umständlich zu debuggen (where userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • Die generierten GUIDs sollten teilweise sequentiell sein, um die beste Leistung zu erzielen (z. B. newsequentialid() auf SQL 2005) und um die Verwendung von Cluster-Indizes zu ermöglichen

Der Artikel enthält eine Menge guter externer Links zur Entscheidung zwischen GUID und Auto Increment. Wenn ich kann, gehe ich mit GUID.

7voto

Jon Skeet Punkte 1325502

Für Kunden ist es nützlich, dass sie eine ganze Reihe von IDs vorab zuweisen können, um eine Masseneinfügung vorzunehmen, ohne anschließend ihre lokalen Objekte mit den eingefügten IDs aktualisieren zu müssen. Dann ist da noch das ganze Replikationsproblem, wie von Galwegian erwähnt.

6voto

dacracot Punkte 21242

Die Prozedurmethode der Inkrementierung muss thread-sicher sein. Ist dies nicht der Fall, erhalten Sie möglicherweise keine eindeutigen Zahlen. Außerdem muss sie schnell sein, da sie sonst zu einem Engpass für die Anwendung wird. Die eingebauten Funktionen haben diese beiden Faktoren bereits berücksichtigt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X