03 / PANDUAN
UUID vs ULID: memilih identifier untuk aplikasi Anda
UUID v4 versus v7, struktur dan keterurutan ULID, dampak identifier acak pada indeks B-tree, probabilitas tabrakan, paparan di URL, dan membuat identifier secara lokal.
Apa yang harus dilakukan identifier aplikasi
Identifier yang dibuat punya satu tugas—unik—plus beberapa yang menyusul kemudian: dibuat di mana saja tanpa koordinasi, tersimpan ringkas, terurut secara dapat diprediksi, dan tidak membocorkan apa pun yang memalukan. UUID dan ULID sama-sama lolos syarat keunikan; bedanya pada semua hal setelah itu.
- Tanpa koordinasiPembuatan terdesentralisasi: layanan, worker, atau tab browser mana pun bisa mencetak identifier tanpa bertanya pada penghitung pusat—itulah yang membuat kedua format cocok untuk sistem terdistribusi.
- Sama-sama 128 bit128 bit untuk keduanya: UUID adalah nilai 128-bit yang ditulis sebagai 36 karakter heksadesimal ber-tanda hubung; ULID membawa 128 bit yang sama sebagai 26 karakter base32.
- Tata letak adalah bedanyaPertanyaan sebenarnya adalah tata letak: bit mana yang acak dan mana yang mengkodekan waktu menentukan perilaku identifier dalam indeks dan apa yang diungkapkannya.
Versi UUID: v4 acak, v7 berurutan waktu
RFC 9562 mendefinisikan beberapa versi UUID, tetapi dua mendominasi pekerjaan aplikasi. Versi 4 mengisi 122 dari 128 bit dengan keacakan dan tidak menyematkan apa pun; versi 7 diawali timestamp Unix 48-bit dalam milidetik dan mengisi 74 bit sisanya dengan keacakan.
- v4: acak murniv4 adalah pilihan maksimal-privasi: nilainya tidak mengatakan kapan atau di mana ia dibuat, dan 122 bit acak adalah keunikan yang lebih dari cukup untuk aplikasi mana pun.
- v7: waktu duluv7 terurut menurut waktu pembuatan dengan presisi milidetik, sehingga identifier yang dibuat kemudian terurut setelah yang lebih awal—properti yang diinginkan database dari primary key.
- Lewati v1Versi lama adalah warisan: v1 menyematkan alamat MAC dan nilai jam, membocorkan keduanya; v3 dan v5 adalah hash berbasis nama untuk menurunkan ID stabil, bukan keacakan segar.
ULID: dapat diurutkan dan ringkas sebagai teks
ULID adalah 26 karakter base32 Crockford: 10 karakter pertama mengkodekan timestamp milidetik 48-bit, 16 sisanya mengkodekan 80 bit acak. Alfabetnya sengaja mengecualikan I, L, O, dan U, sehingga identifier tahan dibacakan atau diketik dari screenshot.
- Urutan string = urutan waktuUrutan leksikografis adalah urutan waktu: mengurutkan ULID sebagai string biasa mengurutkannya menurut waktu pembuatan tanpa parsing—berguna di baris log, nama file, dan key-value store.
- 26 karakter amanRingkas dan aman-URL: 26 karakter case-insensitive tanpa tanda hubung atau simbol, lebih pendek dari 36 milik UUID dan aman di segmen path atau parameter query mana pun.
- Monoton per milidetikDalam satu milidetik, urutan datang dari bagian acak; generator yang menaikkannya secara monoton—seperti generator batch Toolars—menjaga identifier semilidetik pun tetap dalam urutan pembuatan.
ID acak memecah indeks Anda
Indeks B-tree itu terurut, dan menyisipkan UUID v4 acak menulis ke leaf acak setiap kali: halaman terbelah, buffer cache bergejolak, dan indeks membengkak oleh ruang mati. Identifier berurutan waktu menempel di dekat tepi kanan indeks, mengubah insert menjadi kasus terbaik B-tree.
Inilah mengapa pilihan ini milik fase desain skema, bukan setelah kuartal pertama yang lambat: memigrasikan primary key berarti menulis ulang setiap baris dan setiap foreign key yang mereferensikannya. Bila tabel akan tetap kecil, ketidakteraturan v4 tak pernah terlihat; bila ia tumbuh ke ratusan juta baris di bawah tulisan konstan, format terurut membayar sewanya sejak hari pertama.
- Acak menyebarDengan v4 sebagai primary key, tabel yang padat insert menunjukkan lebih banyak page split, fill factor lebih rendah, dan throughput tulis yang terukur lebih buruk dibanding kunci terurut dengan ukuran sama.
- Terurut menempelv7 dan ULID memulihkan lokalitas sambil menjaga pembuatan tetap terdesentralisasi—tanpa sequence, tanpa koordinasi, dan tetap tanpa prediktabilitas ID baris lain.
- Ukur komprominyaKomprominya nyata tetapi moderat: 128 bit adalah dua kali lipat penyimpanan bigint, dan kunci berurutan waktu memusatkan tulisan hari ini di tepi kanan indeks, yang hanya penting pada laju insert sangat tinggi.
Tabrakan, URL, dan apa yang diungkap ID
Matematika tabrakan dulu: dengan 122 bit acak di v4, membuat satu miliar identifier menyisakan probabilitas tabrakan sekitar satu banding 10^18—praktis tidak pernah. 80 bit acak ULID menjaga anggaran berbeda: identifier yang dibuat dalam milidetik yang sama.
Tempelkan nilai mencurigakan apa pun ke validator: ia mengenali bentuk UUID kanonik 36 karakter dengan varian RFC 9562 dan nibble versinya, alfabet ULID 26 karakter dengan aturan overflow-nya, dan melaporkan timestamp tersemat untuk format berurutan waktu—sehingga nilai dari log memberi tahu Anda apa dia sebelum Anda membangun di atasnya.
- Probabilitas bisa diabaikanKedua format bukan batas keamanan: identifier dalam URL baik-baik saja untuk pengalamatan, tetapi siapa pun yang melihatnya bisa mengutipnya—otorisasi harus datang dari access check, bukan dari keopakan ID.
- ID bukan rahasiav7 dan ULID membocorkan waktu pembuatan by design; validator mengekstraknya secara terbuka. Itu biasanya metadata tak berbahaya, tetapi putuskan secara sadar untuk objek yang menghadap publik.
- Waktu terlihatID database sekuensial membocorkan volume dan laju pertumbuhan; identifier acak dan waktu-plus-acak tidak mengungkap apa pun tentang berapa banyak record yang ada.
Buat dan validasi tanpa server
Pembuatan identifier hanya butuh satu sumber daya langka—keacakan yang baik—dan browser sudah memilikinya. Ruang kerja mengambil dari crypto.getRandomValues, membuat batch sepenuhnya di tab, dan tidak pernah mengirim nilai apa pun.
- 1–100 per batchPilih UUID v4, UUID v7, atau ULID dan buat 1 hingga 100 per batch; batch v7 dan ULID menaikkan field acak secara monoton, sehingga seluruh batch tetap dalam urutan pembuatan.
- Case dan eksporHuruf besar-kecil output adalah pilihan tampilan: kanonik, uppercase, atau lowercase, dengan salin-semua plus unduhan teks baris-baru dan CSV yang mencatat waktu tersemat tiap identifier.
- Validasi seketikaValidasi menjawab pertanyaan struktur seketika: panjang, alfabet, versi dan varian UUID, nilai spesial nil dan max, overflow ULID, dan timestamp tersemat dalam UTC.
ULID adalah base32; token Anda mungkin Base64.
Encoding byte-ke-teks berada di bawah setiap identifier dan token—pelajari biayanya dan di mana ia layak dipakai.