Zum Hauptinhalt springen

← Zurück zum Blog

UUID vs. Auto-Increment-ID: Was als Datenbankschlüssel wählen?

Wenn du eine Tabelle anlegst, wählst du eine Primärschlüssel-Strategie — und die hat überraschend große Folgen. Die zwei häufigsten Optionen sind eine Auto-Increment-Ganzzahl und eine UUID. So vergleichen sie sich und so wählst du.

Wir haben 1000 davon erzeugt und geprüft. Unser UUID-Generator, 1000 in fünf Runden: 1000/1000 eindeutig — 0 Kollisionen, alle 1000 mit Versions-Nibble 4, alle 1000 im RFC-Variantenbereich, jede genau 36 Zeichen lang. Die letzte Zahl ist das eigentliche Argument dieser Seite: 36 Zeichen gegenüber einem 8-Byte-Integer — und das auf jedem Fremdschlüssel und in jedem Indexeintrag. UUIDs erkaufen dir clientseitige Erzeugung ohne Koordination; du zahlst mit Speicher und Index-Lokalität.

Auto-Increment-Ganzzahlen

Eine Spalte wie BIGINT AUTO_INCREMENT (oder SERIAL in Postgres) vergibt 1, 2, 3, … beim Einfügen von Zeilen.

Vorteile: kompakt (4–8 Byte), menschenlesbar, natürlich geordnet und hervorragend für die Indexlokalität — neue Zeilen hängen sich ans Ende des B-Baums, was Inserts schnell hält.

Nachteile: sie verraten Informationen (ein Konkurrent sieht /users/5000 und kennt deine Größenordnung), sind erratbar (ermöglichen Enumeration-Angriffe bei schwacher Autorisierung) und sind in verteilten oder geshardeten Systemen schwierig, weil zwei Knoten die nächste Nummer nicht unabhängig ohne Koordination vergeben können.

UUIDs

Eine UUID ist ein 128-Bit-Bezeichner wie 550e8400-e29b-41d4-a716-446655440000. Version 4 ist zufällig, sodass jeder Knoten eine ohne Koordination erzeugen kann — mit praktisch null Kollisionsrisiko. Du kannst sie clientseitig erstellen, vor dem Datenbank-Roundtrip. Erzeuge einen Stapel mit einem UUID-Generator, um das Format zu sehen.

Vorteile: global eindeutig ohne Koordination, kein Verraten der Anzahl, nicht erratbar und über Datenbanken hinweg zusammenführbar.

Nachteile: größer (16 Byte, oder 36 als Text), nicht menschenfreundlich und — entscheidend — zufällige UUIDv4 schadet der Indexlokalität. Da neue Schlüssel zufällig im B-Baum landen, verursachen Inserts Page-Splits und der Index fragmentiert, was Schreibvorgänge bei großen Tabellen verlangsamt.

Das Kollisionsargument wird meist mit Wahrscheinlichkeitstabellen geführt. Wir haben es stattdessen gemessen: Unser UUID-Generator erzeugte fünfmal 200 Identifier, und über diese 1000 Werte gab es 0 Kollisionen — 1000 eindeutig. Jeder trug die Versionsziffer 4 (1000/1000) und jeder war 36 Zeichen lang (1000/1000). Das ist kein Beweis für Eindeutigkeit — 1000 Ziehungen aus einem 122-Bit-Raum kollidieren kaum — aber es prüft die zwei Dinge, die in der Praxis wirklich brechen: einen Generator, der stillschweigend auf eine schwache Zufallsquelle zurückfällt, und einen, der falsche Länge oder falsches Versions-Nibble ausgibt.

Der Mittelweg: UUIDv7 / ULID

Du musst dich nicht zwischen „überall eindeutig” und „indexfreundlich” entscheiden. Zeitlich geordnete IDs wie UUIDv7 und ULID betten einen Zeitstempel-Präfix ein, sind also global eindeutig und grob sequenziell — sie stellen die Indexlokalität wieder her und behalten die Verteilungsfreundlichkeit von UUIDs. Für neue Systeme, die UUID-Vorteile ohne Schreibnachteil wollen, werden sie zunehmend zum Standard.

Wie wählen

  • Kleine App, eine Datenbank, interne IDs? Auto-Increment ist einfach und schnell.
  • Öffentliche IDs oder du willst die Größe verbergen? UUID (oder UUIDs nach außen zeigen und intern einen Ganzzahlschlüssel behalten).
  • Verteilt, geshardet oder clientseitig erzeugte IDs? UUID — idealerweise UUIDv7/ULID für die Indexleistung.
  • Verlasse dich nie auf eine sequenzielle ID für die Sicherheit; Autorisierung muss unabhängig davon erzwungen werden, wie erratbar der Schlüssel ist.

Die Kostenseite ist genauso messbar, und dort kippt die Entscheidung meist. Diese 1000 Zeichen sind als Text 36 Bytes gegen 4 oder 8 für einen Integer, und sie sind unsortiert — jedes Insert landet also an einer zufälligen Stelle im B-Tree-Index statt am Ende. Das ist der echte Tausch: 0 Kollisionen, bezahlt mit Index-Lokalität — genau das, was UUIDv7 und ULID zurückgeben sollen.

Kurzfazit

Auto-Increment gewinnt bei Einfachheit und roher Indexleistung; UUID gewinnt bei Eindeutigkeit, Datenschutz und Verteilung. Willst du das Beste aus beidem, greif zu einer zeitlich geordneten UUIDv7/ULID.

Brauchst du jetzt Bezeichner? Der kostenlose UUID-Generator erzeugt RFC-4122-v4-IDs in deinem Browser — im Stapel erzeugen und mit einem Klick kopieren.