Mikä tekee ULID-generaattorista erilaisen
Tämä sivu tuottaa ULID-tunnisteita, jotka ovat UUID:tä lyhyempiä (26 merkkiä vs. 36) ja käyttävät ainoastaan Crockfordin base32-aakkostoa. Tämä tekee niistä kirjainkoosta riippumattomia ja väliviivattomia. ULID:t ovat leksikografisesti lajiteltavissa luomisajan mukaan, koska ensimmäiset 10 merkkiä koodaavat millisekuntitarkkuudella aikaleiman. Tunnisteet ovat URL-ystävällisiä ilman erikoismerkkejä. Toisin kuin muilla saman työkalun sivuilla, tällä ei ole vaihtoehtoja isojen kirjainten tai väliviivojen lisäämiseen, koska ULID on luonnostaan kirjainkoosta riippumaton eikä sisällä väliviivoja. Satunnaisosa vie loput 16 merkkiä (80 bittiä), ja koko tunnisteen taustalla on 128 bittiä tietoa.
Sivun tuloste on yksinkertainen: annat määrän (1–100), ja saat listan ULID-merkkijonoja. Tilatietona näkyy "Ready.", "Generated." ja "Copied all!". Kaikki tunnisteet luodaan selaimessa paikallisesti crypto.getRandomValues()-funktiolla, eikä mitään lähetetä palvelimelle. Yksittäistä tunnistetta klikkaamalla se kopioituu leikepöydälle.
ULID:n sisäinen rakenne – 48 bittiä aikaa, 80 bittiä satunnaisuutta
Jokainen ULID on 128-bittinen tunniste, joka jakautuu kahteen osaan: aikaleima ja satunnaisosa. Aikaleima on 48 bittiä pitkä ja koodaa millisekuntimäärän Unix-epochista (1. tammikuuta 1970) alkaen. Tämä riittää noin 8 925 vuoden ajanjaksolle, joten käytännössä tunnisteet eivät "lopu" kesken ennen vuotta 10895. Ensimmäiset 26 merkkiä ULID:stä edustavat tätä 48-bittistä aikaleimaa, joka on koodattu Crockfordin base32:lla. Koska 48 bittiä vastaa noin 10 base32-merkkiä (48 / 5 = 9,6, pyöristettynä 10), aikaleimaosa on aina täsmälleen 10 merkkiä.
Loput 16 merkkiä (80 bittiä) ovat satunnaisosa. Tämä 80-bitin satunnaisluku tuotetaan selaimen kryptografisesti vahvalla satunnaislukugeneraattorilla. Koska jokainen merkki edustaa 5 bittiä, 16 merkkiä tarvitsee 80 bittiä. Yhdessä aikaleiman 48 bitin kanssa saadaan 128 bittiä.
Tärkeä huomio: ULID ei takaa tiukkaa järjestystä saman millisekunnin aikana luoduille tunnisteille. Jos kaksi tunnistetta syntyy samalla millisekunnilla, satunnaisosa ratkaisee järjestyksen, eikä se ole aikajärjestyksessä. Käytännössä tämä on harvinaista, mutta se on syytä muistaa, jos tarvitset ehdotonta aikajärjestystä alle millisekunnin tarkkuudella.
Crockford base32 – miksi kirjainkoko ei haittaa
Crockfordin base32-aakkosto on suunniteltu vähentämään visuaalisia sekaannuksia. Se käyttää numeroita 0–9 ja kirjaimia A–Z, mutta jättää pois kirjaimet I, L, O ja U. Tämä estää esimerkiksi sekaannuksen 1:n ja I:n, 0:n ja O:n tai V:n ja U:n välillä. Koska aakkosto on valittu huolellisesti, isot ja pienet kirjaimet ovat keskenään vaihdettavissa: esimerkiksi "A" ja "a" tulkitaan samaksi merkiksi. Tämä tekee ULID:istä käteviä manuaalisessa syötössä, koska käyttäjän ei tarvitse huolehtia kirjainkoosta.
Tämä on suuri etu verrattuna UUID v4:ään, joka käyttää heksadesimaaleja (0–9, A–F) ja on kirjainkoosta riippuvainen. Vaikka UUID on usein esitetään pienillä kirjaimilla, se on teknisesti kirjainkoon suhteen herkkä, ja monet järjestelmät olettavat tietyn muodon. ULID:n tapauksessa voit kopioida tunnisteen suoraan, ja se toimii riippumatta siitä, onko se isolla vai pienellä kirjoitettu.
Lisäksi Crockford base32:n merkit ovat kaikki sallittuja URL-osoitteissa ilman prosenttikoodausta. RFC 3986 määrittelee joukon varattuja merkkejä, mutta ULID:n merkit (0–9, A–Z) eivät sisällä esimerkiksi "+", "/" tai "=", jotka ovat base64:ssä. Tämä tekee ULID:istä suoraan käyttökelpoisia URL-parametreissa, API-poluissa ja tiedostonimissä.
Vertailu UUID v4:ään ja UUID v7:ään
| Ominaisuus | ULID | UUID v4 | UUID v7 |
|---|---|---|---|
| Pituus | 26 merkkiä | 36 merkkiä (32 + 4 väliviivaa) | 36 merkkiä |
| Aikaleima | Kyllä, 48 bittiä (millisekunnit) | Ei, täysin satunnainen | Kyllä, 48 bittiä (millisekunnit) |
| Lajiteltavuus | Leksikografinen aikajärjestys | Ei lajiteltavissa | Leksikografinen aikajärjestys |
| Väliviivat | Ei | Kyllä (4 kappaletta) | Kyllä (4 kappaletta) |
| Kirjainkoko | Riippumaton | Herkkä (yleensä pieni) | Herkkä (yleensä pieni) |
| URL-ystävällisyys | Täysin | Hyvä (väliviivat sallittuja) | Hyvä |
| Satunnaisuus | 80 bittiä | 122 bittiä | 74 bittiä |
UUID v7 on standardoitu vasta vuonna 2024 (RFC 9562), ja se on ULID:n kaltainen aikaperustainen tunniste. Sen etuna on standardointi, mutta se on edelleen 36 merkkiä pitkä ja sisältää väliviivat. ULID on kompaktimpi ja joustavampi esitysmuodoiltaan.
Tärkeä käytännön ero: UUID v4:n täysi satunnaisuus voi aiheuttaa B-puu-indeksien hajoamista tietokannoissa, koska uudet tunnisteet osuvat satunnaisiin kohtiin indeksiä. ULID ja UUID v7 lisäävät uudet tunnisteet loppuun, mikä parantaa kirjoitussuorituskykyä erityisesti suurissa tauluissa.
Lajittelukäyttäytyminen ja rajoitukset
ULID:n lajittelu perustuu aikaleimaosan leksikografiseen järjestykseen. Koska aikaleima on koodattu base32-muotoon, aikaisemmin luodun tunnisteen alkumerkit ovat "pienempiä" kuin myöhemmin luodun. Tämä toimii niin kauan kuin aikaleimat eroavat toisistaan.
Saman millisekunnin aikana luotujen tunnisteiden keskinäinen järjestys on kuitenkin satunnainen. Jos siis luot sata tunnistetta silmänräpäyksessä, ne eivät välttämättä ole aikajärjestyksessä keskenään. Tämä on ULID:n suunnittelussa tietoinen kompromissi: satunnaisosan 80 bittiä tuottaa riittävän satunnaisuuden, mutta ei takaa sekvenssiä millisekuntia tarkemmin.
Käytännön vaikutus: Jos tarvitset ehdottoman järjestyksen nanosekuntitasolla, et voi luottaa pelkkään ULID:hen. Useimmissa sovelluksissa millisekuntitarkkuus riittää, ja saman millisekunnin tunnisteiden satunnainen järjestys on hyväksyttävää. Tietokannoissa, joissa indeksit perustuvat ULID:iin, tämä ei yleensä aiheuta ongelmia, koska useimmat operaatiot tapahtuvat eri ajanhetkillä.
Kollision todennäköisyys – 80 bitin satunnaisuus
ULID:n satunnaisosa on 80 bittiä, mikä tarkoittaa 2^80 mahdollista arvoa. Kollision todennäköisyys riippuu siitä, kuinka monta tunnistetta luodaan. Jos luot miljoona tunnistetta saman millisekunnin aikana, todennäköisyys kahdelle identtiselle tunnisteelle on noin 1 / 2^80 × (10^6)^2 / 2, eli äärimmäisen pieni. Käytännössä tämä on paljon pienempi kuin esimerkiksi laitteistovian aiheuttama riski.
Kannattaa kuitenkin huomata, että ULID ei takaa uniikkiutta samalla tavalla kuin UUID v4, jossa on 122 bittiä satunnaisuutta. 80 bittiä on silti erittäin suuri luku, ja useimmissa sovelluksissa kollision todennäköisyys on käytännössä olematon. Vain jos luot valtavia määriä tunnisteita (miljardeja) samassa aikaleimassa, riski alkaa olla teoreettisesti merkittävä.
Käyttökohteet ja rajoitukset
Sovellusalueet:
- Web- ja mobiilisovellukset: Lyhyet, URL-ystävälliset tunnisteet, jotka ovat lajiteltavissa ilman erillistä aikaleimasaraketta.
- Tietokantojen ensisijaiset avaimet: Aikajärjestyksessä syntyvät avaimet parantavat B-puu-indeksien suorituskykyä.
- Hajautetut järjestelmät: Tunnisteiden uniikkius useilla solmuilla ilman keskuspalvelinta.
- API-tunnisteet: Helposti kopioitavat ja ihmisystävälliset, erityisesti jos käyttäjä joutuu syöttämään niitä manuaalisesti.
Rajoitukset:
- Ei takaa järjestystä saman millisekunnin sisällä.
- 26 merkkiä on pidempi kuin esimerkiksi NanoID (21 merkkiä), mutta lyhyempi kuin UUID.
- Ei standardoitu IETF:n toimesta (toisin kuin UUID v7).
Usein kysytyt kysymykset
Voinko käyttää ULID:iä suurissa tietokannoissa? Kyllä. ULID on suunniteltu erityisesti tietokantojen ensisijaiseksi avaimeksi, ja sen aikajärjestys vähentää indeksin hajoamista. 128 bittinen tila riittää käytännössä loputtomiin.
Miten voin luoda ULID:ejä selaimen ulkopuolella?
Tämä sivu käyttää selaimen crypto.getRandomValues()-funktiota. Palvelinpuolella voit käyttää vastaavia kirjastoja, kuten ulid npm-pakettia. Aikaleima on sama Unix-aika millisekunteina, joten tunnisteet ovat yhteensopivia.
Miksi ULID ei sisällä väliviivoja? Crockfordin base32-aakkosto ei tarvitse erottimia, koska jokainen merkki on 5 bittiä ja kokonaispituus on 26 merkkiä. Väliviivat eivät ole tarpeen, ja ne hidastaisivat manuaalista kopiointia.
Mitä tapahtuu, jos luon sata tunnistetta ja tietokoneen kello menee taaksepäin? ULID ei ota kantaa kellon kääntymiseen. Jos kello menee taaksepäin, uudet tunnisteet voivat olla "vanhempia" kuin aiemmin luodut. Tämä on yleinen ongelma kaikissa aikaleimaan perustuvissa tunnisteissa. Suositeltava ratkaisu on synkronoida järjestelmän kello NTP:n avulla.
Voiko ULID:jä käyttää URL-osoitteissa? Kyllä, ilman prosenttikoodausta. Kaikki Crockford base32 -merkit ovat sallittuja URL-osoitteissa, eikä niitä tarvitse muuntaa.
Mikä on ULID:n tarkka pituus bitteinä? 128 bittiä, kuten UUID:ssä. Ero on vain esitysmuodossa: 26 base32-merkkiä vs. 32 heksadesimaalimerkkiä plus 4 väliviivaa.