ULID Generator

Erzeuge sortierbare, 26-stellige ULIDs (Crockford Base32) und dekodiere den eingebetteten Timestamp zurück in ein Datum. Hervorragend für Datenbank-Primärschlüssel.

Sortierbare eindeutige Identifikatoren. Ein ULID besteht aus 26 Zeichen: die ersten 10 codieren die Erstellungszeit in Millisekunden, die letzten 16 sind zufällig. Das macht sie lexikografisch sortierbar und sicher als Schlüssel verwendbar. Im Browser generiert.

ULID versus UUID

Was ein ULID ist

Ein ULID ist ein 128-Bit-Identifier, genauso breit wie ein UUID, aufgeteilt in zwei Teile: ein 48-Bit-Millisekunden-Timestamp gefolgt von 80 Zufallsbits. Er wird als 26 Zeichen Crockford Base32 gerendert statt als die 36 Zeichen lange, durch Bindestriche getrennte Hex-Form eines UUID, also ist er kürzer, groß-/kleinschreibungsunabhängig und frei von den am leichtesten verwechselten Zeichen – I, L, O und U sind alle aus dem Alphabet ausgeschlossen. Der entscheidende Unterschied ist nicht die Codierung, es ist die Reihenfolge. Weil der Timestamp die hohen Bits belegt und Base32 die Byte-Reihenfolge bewahrt, sortiert das Sortieren von ULIDs als Klartext sie nach Erstellungszeit. Zwei IDs, die in derselben Millisekunde erzeugt wurden, fallen auf ihren Zufallsteil zurück, aber über Millisekunden hinweg ist die Reihenfolge exakt.

Warum Sortierbarkeit für Datenbanken wichtig ist

UUIDv4 ist gleichmäßig zufällig, was genau das ist, was du in einem gruppierten Index nicht willst. Jeder Insert landet an einem zufälligen Punkt im B-Baum, sodass die Datenbank ständig Seiten aufteilt und kalte berührt. Der Index wächst größer als nötig, und der Schreibdurchsatz verschlechtert sich mit wachsender Tabelle. Das ist ein gut dokumentiertes Problem mit UUID-Primärschlüsseln in MySQLs InnoDB und in SQL Server. Ein zeitgeordneter Identifier hängt nahe am rechten Rand des Index an, was dasselbe Zugriffsmuster ist wie ein Auto-Increment-Integer. Du behältst die Vorteile eines client-generierten global eindeutigen Schlüssels – kein Round-Trip, um eine ID zu bekommen, keine Koordination zwischen Services, sichere Merges über Shards –, ohne die Index-Fragmentierung.

Wann man etwas anderes verwenden sollte

UUIDv7, standardisiert in RFC 9562, macht dasselbe wie ULID im standardisierten UUID-Format und -Layout. Wenn dein Stack bereits native UUID-Spalttypen und -Tooling hat, ist UUIDv7 jetzt meist die bessere Wahl, einfach weil es in das bestehende Ökosystem fällt. ULID bleibt attraktiv, wenn du die kürzere, freundlichere Textform in URLs oder Logs willst. Egal wie, sei dir klar, dass der Timestamp für jeden sichtbar ist, der die ID hält. Erstellungszeiten lassen sich ableiten, und benachbarte IDs verraten die Reihenfolge – verwende diese nicht für etwas, bei dem die Aufzählung oder die Zeitangabe sensibel ist. Und mit 80 Zufallsbits pro Millisekunde sind Kollisionen kein praktisches Problem, aber ULIDs sind keine Geheimnisse und sollten niemals als Capability-Token verwendet werden.

Open-Source-Hinweis: implementiert mit crypto.getRandomValues und einem from-scratch Crockford-Base32-Codec. Keine Fremdbibliotheken.

FAQ

Wie unterscheidet sich ein ULID von einem UUID?
Beide sind 128 Bit, aber ein ULID setzt zuerst einen 48-Bit-Millisekunden-Timestamp, sodass das Sortieren der Strings nach Erstellungszeit sortiert. UUIDv4 ist vollständig zufällig und sortiert beliebig.
Warum ist Sortierbarkeit für eine Datenbank wichtig?
Zufällige Primärschlüssel verstreuen Inserts über einen B-Baum und fragmentieren den Index. Zeitgeordnete Schlüssel hängen nahe am Ende an, was Schreibvorgänge sequenziell und die heißen Seiten klein hält.
Sind IDs, die in derselben Millisekunde erzeugt wurden, noch geordnet?
Im monotonen Modus, ja. Anstatt den Zufallsteil neu zu ziehen, erhöht ihn das Werkzeug, sodass mehrere IDs, die innerhalb einer Millisekunde erzeugt wurden, dennoch in Reihenfolge herauskommen.
Ist ein ULID sicher, öffentlich preiszugeben?
Die Zufallshälfte ist unerratbar, aber der Timestamp ist für jeden lesbar. Wenn die Erstellungszeit eines Datensatzes sensibel ist, verwende kein ULID als dessen öffentlichen Identifikator.
Sollte ich ULID oder UUIDv7 wählen?
Sie lösen dasselbe Problem. UUIDv7 ist in RFC 9562 standardisiert und passt zu bestehenden UUID-Spalten und -Bibliotheken, also bevorzuge es für neue Arbeiten, es sei denn, du willst speziell die 26-stellige Crockford-Form.
Warum 26 Zeichen?
128 Bit in Crockford Base32 codiert brauchen 26 Symbole. Das Alphabet schließt I, L, O und U aus, um sowohl Abschreibfehler als auch zufällige Wörter zu vermeiden.