Was ist eine ULID?
ULID steht für Universally Unique Lexicographically Sortable Identifier. Wie eine UUID trägt sie 128 Bit, stellt sie aber in 26 Zeichen Crockford-Base32 dar: 01ARZ3NDEKTSV4RRFFQ69G5FAV.
Das Format entstand als Antwort auf zwei praktische Schwächen von UUID v4: die fehlende Sortierbarkeit und die für URLs unnötige Länge von 36 Zeichen.
Der innere Aufbau
Die ersten zehn Zeichen kodieren einen 48-Bit-Zeitstempel in Millisekunden seit dem Unix-Epochenbeginn, die restlichen 16 Zeichen 80 Bit kryptografischen Zufall.
Weil Base32 die Sortierreihenfolge der zugrunde liegenden Bits erhält, entspricht die alphabetische Sortierung der Zeichenkette genau der chronologischen Reihenfolge. Der Zeitstempel reicht bis in das Jahr 10889.
Warum Crockford-Base32 wichtig ist
Das Alphabet umfasst 32 Zeichen und lässt bewusst I, L, O und U aus: die ersten drei werden leicht mit 1 und 0 verwechselt, das U vermeidet unbeabsichtigte Wörter.
Der praktische Nutzen: ULIDs lassen sich am Telefon durchgeben, von Hand abschreiben und ohne Kodierung in URLs, Dateinamen und Kommandozeilen verwenden.
ULID und UUID im Vergleich
ULID ist zehn Zeichen kürzer, sortierbar und URL-sicher ohne Sonderbehandlung. UUID ist dafür in einem RFC standardisiert, hat native Datenbanktypen und wird von jeder Plattform ohne zusätzliche Bibliothek verstanden.
Beide bestehen aus 128 Bit und lassen sich verlustfrei umrechnen - eine ULID kann als UUID gespeichert und für die Anzeige zurückkonvertiert werden.
Monotonie innerhalb einer Millisekunde
Zwei in derselben Millisekunde erzeugte ULIDs teilen den Zeitstempel-Präfix; ihre Reihenfolge ergibt sich dann aus dem Zufallsanteil und ist damit beliebig. Die Spezifikation beschreibt dafür einen monotonen Modus, der den Zufallsanteil bei gleichem Zeitstempel um eins erhöht. Wenn Sie sich auf die Reihenfolge innerhalb einer Millisekunde verlassen wollen, brauchen Sie eine Bibliothek, die diesen Modus unterstützt.
Wann ULID passt
ULID spielt seine Stärken dort aus, wo Bezeichner sichtbar sind und trotzdem sortierbar sein sollen: Auftrags- und Rechnungsnummern, Ereignis-IDs in Logs und Event-Stores, Objektnamen in S3-Buckets, Cursor für Pagination. Für rein interne Datenbankschlüssel ist UUID v7 wegen der nativen Unterstützung meist die pragmatischere Wahl.
ULIDs in Datenbanken speichern
Am effizientesten ist die binäre Ablage in 16 Byte: BINARY(16) in MySQL, bytea oder uuid in PostgreSQL. Als CHAR(26) bleibt die Sortierbarkeit erhalten und die Werte sind in Abfragen direkt lesbar, kosten aber zehn Byte mehr pro Zeile.