HandyTools Hub

← Alle Anleitungen

Der komplette Leitfaden zu UUIDs: v1–v7, Kollisionsmathematik und Datenbank-Realität

2026-08-06

Öffnen Sie die Datenbank irgendeines modernen Systems, und Sie finden wahrscheinlich Strings wie 0198a3e2-7b1c-7f3a-9e4d-2c5b8a1f6e90 in Primärschlüsselspalten. Das ist eine UUID — ein universell eindeutiger Identifikator. Sie sieht wie zufälliges Tastaturgeklapper aus, doch jedes Bit wird von einer Spezifikation regiert: Die Versionsnummer sitzt an einer festen Position, die führenden Ziffern können einen Zeitstempel kodieren, und die Kollisionsgarantie ruht auf einer klassischen Geburtstagsparadoxon-Rechnung. Diese Anleitung geht durch die Versionen v1 bis v7, die Mathematik hinter dem Eindeutigkeitsversprechen und die Fehler, die Menschen mit UUIDs in der Produktion immer wieder machen.

Die Anatomie: 128 Bits, fünf Segmente

Eine UUID ist eine 128-Bit-(16-Byte-)Ganzzahl, konventionell als Hexadezimal in einem 8-4-4-4-12-Muster geschrieben — 36 Zeichen inklusive der vier Bindestriche:

0198a3e2-7b1c-7f3a-9e4d-2c5b8a1f6e90
         ↑    ↑
      Version Variante

Zwei Positionen sind es wert, gemerkt zu werden: Die erste Ziffer des dritten Segments ist die Version (hier 7, also v7), und die erste Ziffer des vierten Segments ist die Variante (8, 9, a oder b für Standard-RFC-UUIDs). Eine UUIDs Version zu identifizieren erfordert also einen Blick auf den Anfang der dritten Gruppe. Wollen Sie nicht mit dem Auge dekodieren, fügen Sie sie in den UUID-Decoder ein — er beschriftet Version, eingebetteten Zeitstempel (bei zeitbasierten Versionen) und die Bedeutung jedes Felds. Alles Weitere der 128 Bits hängt von der Version ab.

v1 bis v7: Wofür jede Version gedacht ist

v1 (Zeitstempel + MAC-Adresse): das Original. Sie verkettet die aktuelle Zeit (in 100-Nanosekunden-Ticks seit 1582 — dem Datum der gregorianischen Kalenderreform, eine echte Spezifikations-Eigenheit), eine Clock Sequence und die MAC-Adresse der erzeugenden Maschine. Sie ist geordnet und praktisch kollisionsfrei, leakt aber die MAC-Adresse Ihrer Maschine und die genaue Erzeugungszeit, und Clock-Skew über Maschinen hinweg kann beißen. Eine typische v1 sieht wie c2f4d8a0-6e3b-11ec-90d6-0242ac120003 aus — beachten Sie, dass das dritte Segment mit 1 beginnt.

v3 (MD5-namensbasiert): hasht einen Namensraum plus einen Namen mit MD5 zu einer deterministischen UUID. Gleiche Eingabe, gleiche UUID, für immer — nützlich, um stabile IDs für bekannte Entitäten abzuleiten. MD5 ist kryptografisch gebrochen, v3 taucht also meist bei der Pflege von Altcode auf.

v4 (rein zufällig): die am weitesten verbreitete Version. 122 Bits sind völlig zufällig (128 minus 4 Versionsbits und 2 Variantenbits). Beispiel: f47ac10b-58cc-4372-a567-0e02b2c3d479 — die 4 in der dritten Gruppe verrät sie. Einfach zu erzeugen, leakt nichts, was ihre Beliebtheit erklärt. Der Preis ist totale Zufälligkeit, die Datenbanken nicht lieben — mehr dazu unten.

v5 (SHA-1-namensbasiert): v3s Nachfolger, tauscht MD5 gegen SHA-1 mit identischer Semantik: Gleicher Namensraum plus gleicher Name ergibt immer dieselbe UUID. Brauchen Sie „diese E-Mail zu einer stabilen ID hashen“, ist v5 das richtige Werkzeug — bauen Sie nicht Ihr eigenes Schema.

v6 (neu geordnete v1): ordnet v1s Zeitstempelfelder um, sodass die höchstwertigen Bits zuerst kommen und lexikografische Ordnung mit chronologischer übereinstimmt. Denken Sie an die indexfreundliche v1, meist genutzt, um Systeme zu aktualisieren, die bereits v1-Daten haben.

v7 (zeitgeordnet + zufällig, 2024 in RFC 9562 standardisiert): Die ersten 48 Bits sind ein Unix-Zeitstempel in Millisekunden, gefolgt von 74 zufälligen Bits. Das kombiniert v1s monotone Ordnung mit v4s Zustandslosigkeit und Privatsphäre. Die führenden Gruppen von 0198a3e2-7b1c-... sind buchstäblich der Millisekundenzähler. Um den Kontrast selbst zu sehen, erzeugen Sie je einen Schwung im UUID-Generator — v4er landen überall, während v7er ein wachsendes Präfix teilen. Für neue Systeme ist v7 als Primärschlüssel nahezu Community-Konsens.

Kollisionswahrscheinlichkeit: Das Geburtstagsparadoxon

„v4 ist zufällig — könnten zwei je kollidieren?“ Ja, aber Sie werden es nicht erleben. 122 zufällige Bits bedeuten einen Raum von 2^122 ≈ 5,3 × 10^36 Werten. Doch Kollisionen warten nicht, bis Sie den Raum aufgezählt haben — das Geburtstagsparadoxon sagt, dass sie weit früher kommen, als die Intuition vermutet. Unter nur 23 Personen gibt es eine 50-%-Chance, dass zwei denselben Geburtstag haben, obwohl 365 Tage verfügbar sind, weil die Zahl der Paare quadratisch wächst.

Setzt man UUIDs in dieselbe Formel ein, braucht man rund 2,71 × 10^18 (etwa 2,71 Trillionen) v4-UUIDs, bevor die Wahrscheinlichkeit einer einzigen Kollision 50 % erreicht. Bei einer anhaltenden Rate von einer Milliarde UUIDs pro Sekunde über ein volles Jahrhundert erzeugen Sie etwa 3 × 10^18 — kaum an der Münzwurf-Linie. Eine praktischere Einordnung: Das Erzeugen von 10 Billionen UUIDs trägt grob eine Eins-zu-einer-Milliarde-Chance auf eine Kollision. Das liegt unter dem Risikoprofil von Hardwareausfällen, die Sie ohnehin ignorieren. Was in der Praxis tatsächlich Kollisionen verursacht, ist eine kaputte Zufallsquelle — Math.random() statt eines CSPRNG zu nutzen oder VM-Snapshots zu klonen, die den RNG-Zustand duplizieren. Die Regel ist einfach: Nutzen Sie Ihre Standardbibliothek (Pythons uuid.uuid4(), crypto.randomUUID() in Browsern, Javas UUID.randomUUID()) und bauen Sie nie Ihren eigenen Zufall.

Datenbankindizes: Zufällig vs. zeitgeordnet

Hier hat die Versionswahl echte, messbare Auswirkung. B-Tree-Indizes (und InnoDBs geclusterter Primärschlüssel ist einer) belohnen sequenzielle Einfügungen: Neue Werte hängen sich am rechten Rand an, Seiten splitten selten, Schreibvorgänge bleiben schnell. Auto-Increment-Ganzzahlen und v7-UUIDs folgen beide diesem anfügefreundlichen Muster.

v4 ist gleichmäßig zufällig: Jede neue Zeile landet an einer beliebigen Position im Indexbaum. Das bedeutet schlechte Buffer-Pool-Lokalität, häufige Page-Splits, Indexfragmentierung und merklich verschlechterten Schreibdurchsatz, wenn Tabellen wachsen. Das ist der Kern des Arguments gegen v4-Primärschlüssel. Eine weit verbreitete Abhilfe unabhängig von der Version: Speichern Sie die UUID als BINARY(16) statt CHAR(36). Der Speicher sinkt von 36 auf 16 Byte, der Index schrumpft um mehr als die Hälfte, und Vergleiche werden schneller.

Die praktische Schlussfolgerung: Neue Systeme sollten v7 als Binärformat nutzen; bestehende v4-Systeme mit mäßiger Schreiblast müssen nicht migrieren. PostgreSQL 18 liefert eine eingebaute uuidv7()-Funktion, und gängige UUID-Bibliotheken in jeder großen Sprache haben v7-Unterstützung ergänzt.

Der klassische Missbrauch: UUIDs sind keine Geheimnisse

Das verdient einen eigenen Abschnitt: Eine UUID ist ein Identifikator, kein Credential. „122 zufällige Bits, niemand kann sie erraten“ gilt für IDs und nicht für Tokens, aus drei Gründen:

  1. UUIDs landen in Logs, URLs, Referer-Headern und Fehlermeldungen — die Leak-Fläche ist größer, als Sie denken.
  2. Nicht jede UUID stammt aus einer kryptografisch sicheren Quelle — Sie können nicht kontrollieren, wie die UUID in einem Drittsystem erzeugt wurde.
  3. Tokens müssen widerrufbar, ablaufbar und rotierbar sein. Eine UUID hat überhaupt keine Lebenszyklus-Semantik.

Für Passwort-Reset-Links, API-Schlüssel und Session-Credentials nutzen Sie dedizierte Zufallstokens (z. B. 256 Bits aus einem CSPRNG, base64url-kodiert) mit Ablauf und Widerruf — keine v4, die Sie in einer Zeile erzeugt haben. Das ist dieselbe Stufe gesunden Menschenverstands wie „speichern Sie Passwörter nicht mit MD5 oder SHA-1“; müssen Sie je Hash-Algorithmus-Entscheidungen gegenprüfen, macht der Hash-Generator die Ausgaben leicht nebeneinander vergleichbar.

Eine schnelle Entscheidungscheckliste

  • Primärschlüssel in einem neuen System: v7, als BINARY(16) gespeichert.
  • Kurzlebige IDs, die nie eine Datenbank erreichen (Frontend-Temp-Knoten, Trace-IDs): v4 ist in Ordnung und am einfachsten zu erzeugen.
  • Deterministische IDs, aus Namen abgeleitet (gleiche Eingabe → gleiche ID): v5.
  • v1/v3/v6 in Altcode angetroffen: erkennen, nicht in neuen Code einführen.
  • Rätselhafte UUID, die Sie identifizieren wollen: in den UUID-Decoder werfen — Version und (bei v1/v7) der eingebettete Zeitstempel kommen sofort zurück.
  • Alles Sicherheitsrelevante: keine UUID — ein richtiges kryptografisches Token.

Das Genie der UUID ist, dass sie „global eindeutig“ in eine lokale Operation verwandelt — kein zentraler Koordinator, kein Auto-Increment-Lock, jede Maschine zu jeder Zeit. Haben Sie die Versionsunterschiede, die Kollisionsmathematik und das Indexverhalten einmal verstanden, ist die Wahl nur noch Musterabgleich mit Ihrem Szenario.