Az UUID és az ULID olyan azonosító-generáló megoldások, amelyek elosztott rendszerekben vagy adatbázisokban biztosítják az egyediség követelményét. A formátumuk első pillantásra hasonlónak tűnik, ám a szabványosítás, a tárolási hatékonyság, az emberi olvashatóság és az információszivárgási kockázat tekintetében jelentős különbségek vannak. Az alábbiakban a három legfontosabb megközelítést – UUID v4, UUID v7, ULID – rendszerezzük, majd a végén kiegészítésként kitérünk a UUID v1 / v6 változatokra is.

Az azonosítók generálására és az időbélyegek visszafejtésére szolgáló, böngészőben futó (teljesen kliensoldali) eszközök itt érhetők el:


UUID v4: teljesen véletlenszerű forma

Az UUID v4 a 128 bitből 122 bitet tiszta véletlenszámra fordít, így az ütközés valószínűsége rendkívül alacsony. Ennek ára, hogy nem sorbarendezhető időrend szerint, ezért B-Tree alapú indexekben gyakori lapfelosztást eredményez, romolhat a beszúrási lokalitás. Olyan esetekben ideális, ahol a „teljes véletlen” elegendő, például munkamenet-azonosítók vagy egyszer használatos kulcsok.


UUID v7: a kronológiailag rendezhető evolúció

A 2024-ben RFC 9562-ben szabványosított UUID v7 az első 48 bitben UNIX-epoch időt (milliszekundum) tárol, a többi bitet véletlen tölti ki. A lexikografikus (sztring) sorrend megegyezik a generálási sorrenddel, vagyis főkulcsként is megőrzi az indexek lokális jellegét. Az is előny, hogy változtatás nélkül tárolható a meglévő uuid típusú vagy BINARY(16) mezőkben.

  • Véletlen bitek hossza: a v7 a version/variant bitek kivételével nagyjából 74 bitnyi véletlen értéket használ. Egyes implementációk monotonikus generálással (azonos milliszekundumon belüli ütközések megelőzése) a véletlen bitek egy részét újrakalibrálják, de a statisztikai véletlenszerűség így is bőséges.
  • Információszivárgási kockázat: az azonosítóból visszakövethető a generálási idő (ms pontossággal). Ha nagy a kibocsátás és gyenge a véletlengenerátor, akkor könnyebb lehet a közeli azonosítók megtippelése. Belső rendszerekben ez többnyire vállalható, nyilvános végpontoknál azonban oda kell figyelni.

ULID: emberközeli azonosító

A 2016-ban ismertetett ULID egy de facto szabvány, amely Crockford-féle Base32 26 karakteres ábrázolását használja. Kihagyja a könnyen összetéveszthető karaktereket (O/I/L/1), ezért jól illeszthető URL-be és könnyű másolni. Az UUID v7-hez hasonlóan az első 48 bit az idő (ms), így a karakterláncok lexikografikus sorrendje az időrendet követi.

  • Rendezhetőség: a ULID-ok Base32 karakterláncainak lexikografikus összehasonlítása mindig időrendi sorrendet ad (a monotonikus generálás széles körben alkalmazott).
  • Tárolási forma: TEXT(26) mezőben könnyű olvasni, viszont bináris tároláshoz Base32↔16 bájt átalakítás kell. Bár 128 bites binárisként kezelhető, sok RDBMS UUID-specifikus típusaival nem kompatibilis.
  • Információszivárgási kockázat: a v7-hez hasonlóan itt is látható az idő (ms). Ha nem szeretnénk, hogy a nyilvános API-k erőforrás-azonosítóiból kikövetkeztessék a kiadási sorrendet, körültekintően kell dönteni.

A három megközelítés összehasonlítása (gyakorlati nézőpontból)

Tétel UUID v4 UUID v7 ULID
Szabvány RFC 4122 RFC 9562 (2024) Nem hivatalos (de facto)
Bitfelépítés 128 bitből 122 bit véletlen 48 bit = UNIX ms + maradék véletlen (monotonikus lehetséges) 48 bit = UNIX ms + 80 bit véletlen
Véletlen entrópia ≈122 bit ≈74 bit (version/variant levonása után) 80 bit
Karakteres ábrázolás 36 karakter (hex + kötőjel) 36 karakter (hex + kötőjel) 26 karakter (Crockford Base32)
Természetes rendezés (szöveg) × (véletlen) ○ (lexikografikus = időrend) ○ (lexikografikus = időrend)
Természetes rendezés (bináris) × ○ (BINARY(16) összehasonlítás növekvő) ○ (ha a 6 bájtos időt nagy végű sorrendben tároljuk, memcmp szerint növekvő)
Adatbázis-tárolás uuid típus / BINARY(16) ideális uuid típus / BINARY(16) ideális TEXT(26) olvasható, BINARY(16)-hoz konverzió kell / UUID típushoz gyakran nem kompatibilis
Indexlokalitás Gyenge (véletlen beszúrás szétszedi) Jó (sorrendezett beszúrás / hotspotokra figyeljünk) Jó (sorrendezett beszúrás / hotspotokra figyeljünk)
Egyenlőségi keresés költsége Alacsony (16 bájt összevetés) Alacsony (16 bájt összevetés) Szövegként kissé magasabb (összehasonlítás), binárisan alacsony
Kódolási teher Hex↔16 bájt (könnyű) Hex↔16 bájt (könnyű) Base32↔16 bájt (kissé nehezebb)
Olvashatóság / URL-kompatibilitás Alacsony Alacsony Magas
Információszivárgás (időbélyeg) Nincs Van (ms) Van (ms)
Jellemző felhasználás Munkamenet-ID, egyszer használatos kulcs Adatbázis főkulcs, eseményazonosító, idősoros napló URL-ek, publikus ID, naplók olvashatósága

Kiegészítés (v7/ULID hotspotok): ha egyetlen shardra vagy elsődleges replikára koncentrált végű beszúrás történik, a B-Tree utolsó szintje könnyen forró ponttá válik. Enyhítésre alkalmazhatunk kis mértékű felső-bites keverést („prefix shuffle”) vagy shard kulcsokat.


Adatbázis-megjegyzések (PostgreSQL / MySQL / SQLite)

  • PostgreSQL
    • v4/v7: a uuid típus a legjobb. A v7 lexikografikus rendezése is érvényesül, ha sztringből uuid-vá alakítjuk.
    • ULID: char(26) / text mezőben vagy bytea(16)-ként (Base32-konverzióval) használható.
  • MySQL/InnoDB
    • BINARY(16) gyors és takarékos (v4/v7). A v7 big-endian sorrendben természetes rendezést biztosít. ULID-hoz CHAR(26) vagy BINARY(16) + konverzió kell.
  • SQLite
    • Nincs dedikált UUID típus. BLOB(16) vagy TEXT formában kezeljük. Indexelt BLOB esetén is megfelelő a teljesítmény.

Biztonsági szempontok

  • Megjósolhatóság: a v7/ULID azonos milliszekundumban közös időbiteket használ, így ha a véletlenszám-generálás gyenge és nagy a kibocsátási sebesség, nő a közeli ID-k becslésének kockázata. Használjunk kriptográfiai biztonságú PRNG-t, és minimalizáljuk a monotonikus növelésből fakadó mintákat.
  • Metadat-szivárgás: az azonosítókból kiolvasható a generálási idő és nagyjából a mennyiség. Publikus API-kon célszerű belső és külső azonosítókat szétválasztani.

Összegzés: hogyan válasszunk?

  • UUID v4: teljesen véletlenszerű, nincs rendezhetőség. Elméletileg minimális ütközési kockázat marad. Munkamenetekhez, CSRF tokenekhez illik.
  • UUID v7: szabványos, rendezhető UUID. Belső rendszerekben, adatbázis főkulcsként optimális. A monotonikus generálás a gyakorlatban kiküszöböli az ütközést.
  • ULID: (a másik kettőhöz képest) emberbarátabb. Ha az olvashatóság vagy URL-kompatibilitás fontos, erős jelölt, de belső főkulcsnak sokszor a v7 célszerűbb. A monotonikus generálás itt is gyakorlatilag elkerüli az ütközést.

Kiegészítés: UUID v1 / v6 röviden

  • UUID v1 (időalap + MAC) 60 bites időbélyeget (100 ns felbontással) és csomópont-azonosítót (gyakran MAC-címet) tartalmaz. Kiváló időrendiség, de a MAC-ből származó hosztinformáció kiszivárgása és a visszaugró óra kezelése problémás. A modern gyakorlatban adatvédelmi okokból többnyire nem ajánlott.

  • UUID v6 (a v1 átrendezett változata) A v1 időbélyege big-endian sorrendbe rendezve a lexikografikus rendezhetőséget javítja. Történetileg „könnyen sorba rakható v1” néven futott, de a szabványosítás végül a v7-re konvergált. Új rendszerekben általában a v6 helyett a v7 a javasolt.


Melléklet: megvalósítási ellenőrzőlista

  • Használjunk kriptográfiai PRNG-t (OS által biztosított biztonságos forrás).
  • A v7/ULID monotonikus generálás azonos milliszekundumon belül kerülje el az ütközést, miközben minimalizálja a véletlen torzulását.
  • Az adatbázisban részesítsük előnyben a uuid / BINARY(16) tárolást, kerüljük a szövegmezők kollációjából adódó teljesítményromlást.
  • Döntsük el az externális ID-k politikáját (szabad-e az időrend látszódjon). Szükség esetén válasszuk szét a belső és külső azonosítókat.

Összegzésként: a jelenlegi technikai helyzetben belső főkulcsnak a UUID v7 az első számú jelölt, míg ha a használhatóság vagy a megkötések miatt fontos a jobb olvashatóság, akkor az ULID is komoly opció. Csak speciális igény (például szigorú időbélyeg-elrejtés) esetén indokolt a v4 vagy más módszer választása.