Zakaj je ULID drugačen od drugih oblik identifikatorjev
Večina spletnih orodij za generiranje identifikatorjev ponuja UUID v več različicah, dodaja stikala za vezaje in velike črke ter pogosto zahteva izbiro med navadnim in URL‑prijaznim naborom znakov. Na tej strani je format ULID obravnavan kot samostojna možnost, ki odpravlja vse te dodatne izbire. ULID vedno vrne niz dolžine 26 znakov, ki ne vsebuje vezajev in je privzeto neobčutljiv na velikost črk. Prvih deset znakov predstavlja časovni žig z milisekundno natančnostjo, preostalih 16 znakov pa je naključnih. Skupna dolžina podatka je 128 bitov, enako kot pri UUID v4 ali v7, vendar je zapis krajši (26 namesto 36 znakov) in brez posebnih ločil.
Ker ULID uporablja Crockfordovo bazo32, so črke I, L, O in U izpuščene, kar preprečuje zamenjavo s števkami 1, 0 in V. To pomeni, da lahko identifikatorje prepisujete ročno brez tveganja dvoumnosti, hkrati pa jih ni treba odstotkovno kodirati za uporabo v URL-jih – vsi uporabljeni znaki so v RFC 3986 nepredznačeni. Na tej strani zato ni stikal za »velike črke« ali »vezaji«, ker jih format sam po sebi ne potrebuje.
Kako je sestavljen ULID
Vsak ULID je 26‑znakovni niz, ki ga lahko razdelimo na dva dela:
| Del | Dolžina (znaki) | Bitov | Vsebina |
|---|---|---|---|
| Časovni žig | 10 znakov | 48 bitov | Milisekunde od Unix epohe (1970-01-01) |
| Naključni del | 16 znakov | 80 bitov | Kriptografsko naključni podatki |
Prvih 10 znakov torej kodira število milisekund, ki so pretekle od izvornega datuma. Ker je 48 bitov dovolj za približno 8.925 let, trenutno ni nevarnosti preliva. Teh 10 znakov lahko dekodirate v časovni žig, kar pomeni, da so ULID-i sami po sebi razvrščljivi po času nastanka – če imate dva ULID-a, nastala v različnih milisekundah, bo tisti s starejšim časom leksikografsko manjši.
Naključni del obsega 80 bitov, kar je 2⁸⁰ možnih vrednosti. V praksi to pomeni, da je verjetnost kolizije zanemarljiva, tudi če v isti milisekundi generirate več sto identifikatorjev. Orodje na tej strani uporablja brskalnikov crypto.getRandomValues(), ki zagotavlja kriptografsko varno naključnost – noben del identifikatorja ni odvisen od strežnika ali vnaprej določene seme.
Crockfordovo kodiranje baze32 uporablja naslednje znake: 0‑9, A‑Z (brez I, L, O, U). To pomeni, da so ULID-i neobčutljivi na velikost črk – A1b2C3d4E5f6G7h8J9k0LmNp in a1b2c3d4e5f6g7h8j9k0lMnp sta identična identifikatorja. Pri prepisovanju si lahko pomagate s tem, da velike črke pretvorite v male (ali obratno), ne da bi spremenili pomen.
Kako deluje generator na tej strani
Vmesnik je zasnovan tako, da je izbira formata že nastavljena na ULID. Vnesete lahko poljubno število med 1 in 100 ter kliknete gumb za generiranje. Orodje takoj prikaže seznam zahtevanih ULID-ov, vsak v svoji vrstici.
- Števec generiranih ID-jev – pod seznamom je prikazano natančno število ustvarjenih identifikatorjev (npr. »12 generiranih«).
- Stanje »Pripravljeno«, »Generirano«, »Kopirano vse!« – med uporabo se sporočila dinamično posodabljajo. Ob prvem prikazu strani je stanje »Pripravljeno«; po kliku na gumb »Generiraj« se spremeni v »Generirano«; ko kopirate celoten seznam, se prikaže »Kopirano vse!«.
- Kopiranje posameznega ID-ja – klik na poljuben ULID v seznamu ga shrani v odložišče. Celoten seznam lahko kopirate z enim gumbom, ki skopira vse vrstice naenkrat.
- Ponovno generiranje – vsaka sprememba števca ali ponoven klik na gumb povzroči novo generiranje vseh ID-jev. Prejšnji seznam se v celoti zamenja.
Pomembno: vsa obdelava poteka izključno v brskalniku. Noben identifikator, niti njegov časovni žig, ni poslan na strežnik. To pomeni, da je orodje uporabno tudi v okoljih, kjer je zasebnost podatkov ključna, ali kadar ne želite, da bi tretja oseba vedela, katere identifikatorje uporabljate.
Kdaj uporabiti ULID namesto UUID
Odločitev med ULID in običajnim UUID (zlasti različico 4 ali 7) je odvisna od zahtev glede dolžine, razvrščanja in človeške berljivosti.
| Lastnost | ULID | UUID v4 | UUID v7 |
|---|---|---|---|
| Dolžina niza | 26 znakov | 36 znakov | 36 znakov |
| Vezaji | Ne | Da (4 vezaji) | Da (4 vezaji) |
| Občutljivost na velikost črk | Ne | Da (heksadecimalno) | Da (heksadecimalno) |
| Časovna razvrščljivost | Da (milisekunde) | Ne | Da (milisekunde) |
| Varnost za URL | Brez kodiranja | Zahtevano kodiranje | Zahtevano kodiranje |
| Nabor znakov | Crockford base32 | heksadecimalno (0‑9, a‑f) | heksadecimalno (0‑9, a‑f) |
Spletni in mobilni razvijalci bodo cenili krajši zapis ULID, ki ga lahko neposredno vstavijo v URL brez odstotkovnega kodiranja. Če na primer v nadzorni plošči uporabljate identifikatorje v povezavah, bo ULID ostal berljiv in prijazen za kopiranje.
Administratorji podatkovnih zbirk pogosto uporabljajo ULID za primarne ključe, ker so časovno razvrščljivi. Ko v tabelo vstavljate nove vrstice, se novi ključi (v povprečju) dodajajo na konec indeksa B‑drevesa, kar zmanjša potrebo po pogostem preurejanju in fragmentaciji. Pri naključnih UUID v4 se novi ključi pojavljajo naključno po celotnem prostoru, kar poslabša zmogljivost vstavljanja.
Arhitekti porazdeljenih sistemov lahko ULID uporabljajo kot globalno enolične identifikatorje, ki jih generira vsak vozel neodvisno brez centralne koordinacije. Časovni žig omogoča približno razvrščanje po vrstnem redu nastanka, kar olajša združevanje dnevnikov ali sledenje dogodkom.
Oblikovalci API-jev pogosto dajejo prednost ULID pred UUID, ker so identifikatorji, ki jih izpostavijo, krajši, lažje zapomnljivi in manj dovzetni za napake pri ročnem vnosu. Pomanjkanje vezajev pomeni, da jih lahko uporabnik preprosto dvakrat klikne in označi celoten niz.
Tveganje kolizij in natančnost razvrščanja
Kljub 80‑bitnemu naključnemu delu obstaja teoretična možnost kolizije, zlasti če v isti milisekundi generirate zelo veliko število ULID-ov. Verjetnost kolizije lahko ocenite s principom rojstnega dne. Če v eni milisekundi ustvarite 1000 ULID-ov, je verjetnost, da bo vsaj en par enak, približno:
P ≈ n² / (2 · 2⁸⁰) ≈ 10⁶ / (2 · 1.2 · 10²⁴) ≈ 4 · 10⁻¹⁹
To je zanemarljivo za večino aplikacij. Orodje na tej strani generira največ 100 ID-jev naenkrat, kar pomeni, da je verjetnost kolizije v praksi ničelna.
Razvrščanje po času ni strogo, če sta dva ULID-a nastala v isti milisekundi. V tem primeru je vrstni red določen z naključnim delom, zato ne morete zagotoviti, da bo ID, ustvarjen prej, leksikografsko manjši od tistega, ustvarjenega pozneje v isti milisekundi. Če potrebujete absolutno časovno urejenost znotraj milisekunde, morate dodati sekundarni mehanizem (npr. zaporedno številko).
Pogosta vprašanja
Ali so ULID-i občutljivi na velikost črk?
Ne. ULID uporablja Crockfordovo bazo32, ki ne razlikuje med velikimi in malimi črkami. Pri kopiranju in primerjanju lahko uporabite poljubno kombinacijo; orodje bo obravnavalo A in a kot enaka znaka. Vseeno priporočamo, da se dosledno držite ene oblike (npr. vse male črke) zaradi berljivosti.
Ali lahko ULID uporabim v URL‑ju brez kodiranja?
Da. Vsi znaki v Crockfordovi bazi32 so v RFC 3986 nepredznačeni, kar pomeni, da jih ni treba odstotkovno kodirati. To velja tako za števke (0‑9) kot za črke (A‑Z). Izjema so po potrebi posebni znaki, ki jih ULID ne vsebuje.
Kako se ULID razlikuje od UUID v7?
Oba formata vsebujeta časovni žig in naključni del, vendar je UUID v7 zapisan v heksadecimalni obliki (36 znakov s štirimi vezaji) in je občutljiv na velikost črk. ULID je krajši, ne vsebuje vezajev in je neobčutljiv na velikost črk, kar olajša ročno prepisovanje. UUID v7 uporablja 48‑bitni časovni žig in 74‑bitni naključni del (6 bitov je rezerviranih za različico), medtem ko ULID uporablja 48‑bitni časovni žig in 80‑bitni naključni del.
Zakaj na tej strani ni stikala za vezaje ali velike črke?
Ker je ULID že sam po sebi brez vezajev in neobčutljiv na velikost črk, bi bila dodatna stikala odveč. Format je definiran tako, da so vsi identifikatorji enotni. Če bi dodali možnost dodajanja vezajev, bi to preprečilo neposredno primerjavo z drugimi ULID generatorji ali specifikacijami.
Ali se identifikatorji generirajo na strežniku ali v brskalniku?
V celoti v brskalniku, z uporabo crypto.getRandomValues(). Noben podatek ne zapusti vašega računalnika. To pomeni, da lahko orodje uporabljate tudi brez internetne povezave (po prvem nalaganju strani) in da nihče ne more prestreči generiranih identifikatorjev.
Kakšna je verjetnost, da dobim dve enaki ULID v isti seji?
Pri generiranju največ 100 identifikatorjev naenkrat je verjetnost kolizije tako majhna, da je v praksi ne morete izmeriti. 80‑bitni naključni del pomeni 1,2·10²⁴ možnih vrednosti, kar daje ogromen prostor. Tudi če bi večkrat zaporedoma generirali 100 ULID-ov, bi potrebovali več kot 10¹¹ poskusov, da bi pričakovali eno kolizijo.