Was sind die Nachteile bei der Verwendung von UUID oder GUID als Primärschlüssel?

60

Ich möchte ein verteiltes System aufbauen. Ich muss Daten in Datenbanken speichern und es wäre hilfreich, eine UUID oder eine GUID als Primärschlüssel für einige Tabellen zu verwenden. Ich nehme an, es ist ein Nachteil bei diesem Design, da die UUID / GUID ziemlich groß ist und sie fast zufällig sind. Die Alternative ist die Verwendung eines automatisch inkrementierten INT oder LONG.

Was sind die Nachteile bei der Verwendung von UUID oder GUID als Primärschlüssel für meine Tabellen?

Ich werde wahrscheinlich Derby / JavaDB (auf den Clients) und PostgreSQL (auf dem Server) als DBMS verwenden.

Jonas
quelle
Warum wäre es hilfreich? Auf welche Nachteile konzentrieren Sie sich am meisten? Die Antwort auf jede dieser vagen DB-Fragen lautet "es kommt darauf an". Können Sie uns mehr Details geben? Interessieren Sie sich am meisten für Lese- oder Schreibvorgänge? Über welche Verteilung sprechen wir?
Brian Ballsun-Stanton
@ Brian: UUIDs in verteilten Systemen sind hilfreich, da Sie den Primärschlüssel auf den Clients erstellen und die Daten dann asynchron auf den Server hochladen können. Ich denke hauptsächlich über Leseleistungseinbußen nach. Die Verwendung vieler JOINs auf UUIDs ist vielleicht nicht so gut? In einem Beispiel fügt ein Client einem Inventarsystem ein Element (UUID, Name, Lieferant, Ersteller) hinzu, und anschließend wird die lokale Datenbank mit der zentralen Datenbank auf dem Server synchronisiert.
Jonas
1
Ich denke, dass es ohne weitere klarstellende Kommentare höchstens "es kommt darauf an" sein wird. Ohne diese werde ich mich für VtC entscheiden.
Jcolebrand
Es gibt einen Artikel, der sich mit den Auswirkungen von GUID auf Clustered-Indizes in SQL Server im Vergleich zu Nicht-GUID befasst. Dieser Artikel ist möglicherweise interessant, obwohl er sich auf ein anderes SQL-Produkt bezieht: x.co/Twpp
Jeff,
Ich habe festgestellt, dass Derby doc die UUID nicht als Datentyp auflistet. Möglicherweise möchten Sie eine Alternative in Betracht ziehen, z. B. die H2 Database Engine (eine reine Java-Datenbank wie Derby), in der ein UUID-Datentyp aufgeführt ist . Natürlich bietet Postgres eine hervorragende Unterstützung für das effiziente Speichern , Indizieren und Generieren von UUID-Werten.
Basil Bourque

Antworten:

29

Dies hängt von Ihrer Generierungsfunktion und der Größe der Final Tables ab

GUIDs sollen global eindeutige Bezeichner sein. Wie in der Dokumentation zu Postgres 8.3 erläutert, gibt es keine allgemein geeigneten Methoden zum Generieren dieser Bezeichner. PostgreSQL wird jedoch mit einigen weiteren nützlichen Kandidaten ausgeliefert.

Aufgrund des Umfangs Ihres Problems und der Notwendigkeit von Offline- Schreibvorgängen haben Sie die Verwendung von etwas anderem als einer GUID ordentlich ausgeschlossen, und daher gibt es keine kompensatorischen Vorteile anderer Schemata.

Unter funktionalen Gesichtspunkten spielt die Schlüssellänge in modernen Systemen in der Regel keine Rolle, abhängig von der Anzahl der Lesevorgänge und der Größe der Tabelle. Als alternative Methode können Offline-Clients neue Datensätze ohne Primärschlüssel stapeln und sie beim erneuten Herstellen der Verbindung einfach einfügen. Da PostgreSQL den Datentyp "Serial" anbietet, müssen Clients die ID nie ermitteln, wenn sie einfach in die Datenbank schreiben können.

Brian Ballsun-Stanton
quelle
3
Verdammt, du schläfst, du bist gegangen und hast Brian die Frage beantworten lassen. Ja, die Forderung nach "Offline-Updates" hat das gesamte Konzept dort komplett verändert.
Jcolebrand
Muahahahaah! :: wirbelt Schnurrbart böse ::
Brian Ballsun-Stanton
1
Auch bei Offline-Schreibvorgängen könnten INTs verwendet werden. Verwenden Sie beispielsweise zwei Spalten, in {Node_ID, Item_ID}denen jeder Knoten ein hat Node_ID, und ein Item_ID, das pro Knoten automatisch inkrementiert wird.
Jonas
@Jonas ~ Ja, das ist machbar. Einer der Gründe, warum die meisten Benutzer sogar GUIDs in Betracht ziehen, ist die global getrennte Replikation von Inhalten in andere Datenbanken. Ich meine, der Begriff selbst ist dort eher QED.
Jcolebrand
In Bezug auf Master / Slave-Architekturen oder Clients mit geringer Verbindungsdichte + Hauptserver-Architekturen könnte es möglich sein, eine globale_ID (SERIAL) auf dem Master und eine globale_ID (BIGINT) + lokale_ID (SERIAL) auf den Slaves zu verwenden. Slaves erledigen ihre lokale Arbeit mit local_id und schreiben fest, wann immer sie können, an den Master. Der Master empfängt die Daten und erteilt ihm eine global_id, die er an den Slave zurückgibt. Der Slave aktualisiert das global_id-Feld (als Referenz für die Kommunikation mit dem Server oder anderen Sklaven).
Mihai Stancu
22

Noch ein Hinweis: Verwenden Sie GUIDs niemals als Teil eines Clustered-Index. GUIDs sind nicht sequenziell. Wenn sie also Teil des Clustered-Index sind, müsste die Datenbank jedes Mal, wenn Sie einen neuen Datensatz einfügen, alle Speicherseiten neu anordnen, um die richtige Stelle für das Einfügen zu finden wäre nur die letzte Seite.

Wenn wir uns nun einige Datenbankrealisierungen ansehen: 1.) MySQL - Primärschlüssel werden geclustert, ohne die Möglichkeit, das Verhalten zu ändern. - Die Empfehlung lautet, hier überhaupt keine GUIDs zu verwenden Primärschlüssel nicht gruppiert, und verwenden Sie ein anderes Feld als gruppierten Index, z. B. autoincrement int.

Ross Ivantsiv
quelle
Was Sie für Postgres vorschlagen, können Sie auch in MySQL mit einer etwas anderen Struktur tun - auto_increment PK (Clustered Key), GUID mit eindeutigem Index (nicht gruppiert).
ypercubeᵀᴹ
Das stimmt nicht immer. Abhängig vom Datenträgersystemdurchsatz kann die Synchronisierung des Zugriffs auf die letzte Seite Ihr Engpass sein. blog.kejser.org/2011/10/05/…
mwilson
2
"Im Gegensatz zu Microsoft SQL Server wird diese Reihenfolge beim Clustering in einem Index in PostgreSQL nicht beibehalten. Sie müssen den CLUSTER-Prozess erneut anwenden, um die Reihenfolge beizubehalten." Wie verbessert CLUSTER ON die
Indexperformance
: Eine komprimierte Version der Informationen @ bartolo-otrit verknüpft stackoverflow.com/a/4796685/1394393 . Diese Antwort scheint mir wirklich nicht relevant zu sein, da es sich bei dieser Frage um PG handelt und Ähnlichkeiten zu SQL Server und MySQL anzunehmen scheinen, die es nicht gibt.
jpmc26
database would need to rearrange all its memory pages to find the right place for insertion=> Ich glaube nicht, dass dies bei Postgres der Fall ist, da das Clustering optional ist und neue Zeilen ungeordnet gespeichert werden.
Flavien
3

Es hängt davon ab, ob.

Im Ernst, mit allem, was Sie bisher gegeben haben, ist dies ungefähr so ​​weit wie Sie gehen können.

Warum wäre es hilfreich, UUIDs zu verwenden? Warum werden Sie keine INTs verwenden? Warum können Sie später nicht einfach nach UUIDs indizieren? Verstehen Sie, was es bedeutet, eine sortierte Liste mit dem Schlüssel einer UUID zu haben und nach einigen Millionen Zeilen eine zufällige (nicht sequentielle) UUID einzufügen?

Auf welcher Plattform läuft das? Wie viele Festplatten? Wie viele Benutzer? Wie viele Datensätze?

jcolebrand
quelle
7
Wie ich in meinem Kommentar schrieb, können die Clients bei Verwendung der UUID der Datenbank Zeilen hinzufügen, ohne eine Verbindung zum Server herzustellen, und später mit dem Server synchronisieren. Ich kann das nicht tun, wenn ich INTs als Primärschlüssel verwende, da dann mehrere Clients denselben Primärschlüssel für verschiedene Elemente verwenden können. Nun, es ist sinnlos, die Liste nach einer UUID-Spalte zu sortieren. Es wäre sinnvoller, sie nach einer Timestamp-Spalte zu sortieren. Nein, ich weiß nicht, was es bedeutet, eine zufällige nicht-sequentielle UUID nach ein paar Millionen Zeilen einzufügen. Deshalb stelle ich diese Frage.
Jonas
Die Anwendung wird in Java geschrieben und die Clients verwenden Windows, Mac oder Linux. Die Clients verwenden gängige Desktop-Computer, die normalerweise über eine Festplatte verfügen. Die Anzahl der Benutzer und Datensätze hängt von der Anzahl der Kunden ab, die ich erhalte. Pro Kunde und Kunde sind es jedoch etwa 5000.
Jonas
1
Der Offline-Kommentar hat alles geändert. Sehen Sie, was mehr Details tut?
Jcolebrand