Pembuat UUID

Buat UUID — v4 acak atau v7 terurut waktu — satu per satu atau dalam batch.

Versi

122 bit acak. Tak mengungkap apa pun tentang kapan ia dibuat.

Berapa banyak

Membuat…

Apa itu UUID dan mengapa ia ada

Sebuah UUID — Universally Unique Identifier, disebut juga GUID dalam dokumentasi Microsoft — adalah nilai 128-bit yang ditulis sebagai 32 digit heksadesimal dalam pengelompokan 8-4-4-4-12 yang familiar. Seluruh tujuannya adalah membiarkan sistem terpisah mencetak pengenal secara mandiri, tanpa koordinasi di antara mereka, dan tetap yakin hasilnya tak akan bertumbukan. Itulah yang membedakannya dari kolom penambah-otomatis basis data: dua server, dua klien seluler yang luring di pesawat, dan sebuah pekerjaan latar bisa semuanya membuat catatan pada saat yang sama tanpa meminta izin siapa pun.

Keunikan di sini bersifat probabilistik ketimbang terjamin. Versi 4 menyisakan 122 bit untuk keacakan, yang merupakan ruang cukup besar sehingga menghasilkan miliaran nilai masih menyisakan peluang pengulangan jauh di bawah peluang sebuah cakram diam-diam merusak datanya. Dalam praktik Anda bisa memperlakukannya sebagai unik; matematikanya bukan mata rantai lemahnya.

Versi 4 vs. versi 7 — pilihan yang penting

Versi 4 acak dari ujung ke ujung. Ia tak membawa informasi apa pun: bukan kapan ia dibuat, bukan oleh siapa, bukan dalam urutan apa. Itu entah kekuatan terbesarnya atau cacat sentralnya, bergantung di mana Anda menaruhnya.

Versi 7, distandarkan dalam RFC 9562 pada 2024, mengganti 48 bit pertama dengan sebuah stempel waktu Unix milidetik dan mengisi sisanya dengan keacakan. Karena waktunya datang lebih dulu dan nilainya dibaca dari kiri ke kanan, menyortir pengenal v7 sebagai teks polos juga menyortirnya secara kronologis.

Ini bukan perbedaan kosmetik. Basis data menyimpan kunci utama dalam indeks B-tree yang tersortir. Sisipkan kunci v7 dan tiap baris baru mendarat di tepi kanan pohon, di samping yang sebelumnya — halaman yang Anda tulisi tetap di memori dan indeks tumbuh dengan rapi. Sisipkan kunci v4 dan tiap penulisan mendarat pada posisi acak, jadi basis data menyentuh halaman berbeda tiap kali, tingkat cache-hit jatuh dan indeks terfragmentasi. Pada tabel besar dan sibuk, perbedaan throughput sisipan itu substansial, itulah sebabnya v7 diadopsi begitu cepat untuk kunci utama.

  • Pilih v7 untuk kunci utama basis data, pengenal peristiwa dan log, dan apa pun yang ingin Anda sortir atau kueri-rentang berdasarkan waktu pembuatan.
  • Pilih v4 ketika pengenal muncul di suatu tempat tak tepercaya dan tak boleh membocorkan apa pun — termasuk fakta bahwa satu catatan dibuat tepat sebelum yang lain.
  • Keduanya baik untuk sebuah ID korelasi, kunci idempotensi, atau nama berkas, tempat pengurutan tak penting.

Imbangannya persis kebocoran itu: sebuah pengenal v7 memberi tahu siapa pun yang melihatnya, hingga milidetik, kapan ia dibuat. Untuk sebuah ID baris itu biasanya tak berbahaya dan sering berguna. Untuk token setel-ulang-sandi atau tautan berbagi publik itu adalah informasi yang tak Anda maksudkan untuk diterbitkan — dan itu seharusnya bukan UUID sama sekali, melainkan token acak dari pembangkit rahasia khusus.

Pengurutan dalam milidetik yang sama

Sebuah kehalusan yang menjebak banyak implementasi v7: perangkat keras modern menghasilkan jauh lebih dari satu pengenal per milidetik. Jika dua nilai berbagi sebuah stempel waktu, urutannya diputuskan oleh bit acak yang mengikutinya — yang berarti, secara acak. Hasilkan lima puluh dalam sebuah gelung ketat dan Anda mendapatkan lima puluh nilai yang hanya kira-kira terurut, kehilangan persis sifat yang karenanya Anda memilih v7.

RFC 9562 mengatasi ini dengan pencacah monotonik, dan alat ini mengimplementasikannya: 12 bit tepat setelah stempel waktu mencacah ke atas dalam sebuah milidetik, jadi sebuah batch meningkat ketat ketimbang kira-kira. Jika pencacah penuh — lebih dari 4096 nilai dalam milidetik yang sama — pembangkit meminjam milidetik berikutnya alih-alih membungkus dan memancarkan nilai yang tersortir sebelum pendahulunya. Ia menangani jam yang bergerak mundur, yang terjadi dengan koreksi NTP, dengan cara yang sama.

Membaca sebuah nilai v7 dari kiri ke kanan, mengambil 0190a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b sebagai contohnya:

  • 0190a1b2-c3d4 — stempel waktu Unix 48-bit dalam milidetik. Karena ia datang lebih dulu, urutan teks adalah urutan waktu.
  • 7 — nibble versi, yang menjadikan ini v7 ketimbang v4.
  • e5f — pencacah monotonik 12-bit, menambah dalam satu milidetik.
  • 8 — bit varian, ditetapkan RFC 9562 untuk setiap UUID modern (selalu 8, 9, a, atau b).
  • a9b-0c1d2e3f4a5b — 62 bit sisanya, murni acak.

Menyimpan dan memakai UUID

Bentuk kanonisnya adalah huruf kecil dengan tanda hubung, dan RFC 9562 mengatakan pembangkit sebaiknya memancarkan persis itu — itulah sebabnya alat ini tak menawarkan opsi pemformatan. Anda masih akan menemui ejaan lain di alam bebas: huruf besar dan dibungkus kurung kurawal dalam perkakas Microsoft, dan tanpa tanda hubung tempat seseorang menginginkan kolom lebih pendek. Semuanya adalah 128 bit yang sama, dan perbandingan sebaiknya tak peka besar-kecil huruf.

Yang penting adalah penyimpanan. Sebuah UUID adalah 16 bita, tetapi bentuk teksnya 36 karakter — jadi menyimpannya sebagai string lebih dari menggandakan ruang dalam baris dan, yang lebih penting, dalam setiap indeks yang menyertakannya. Pakai tipe asli tempat ada:

uuid                      -- PostgreSQL: native 16-byte type
BINARY(16)                -- MySQL: compact; CHAR(36) wastes 20 bytes/row
uniqueidentifier          -- SQL Server
crypto.randomUUID()       // JavaScript: v4 only, needs a secure context
uuid.uuid4() / uuid7()    # Python: stdlib v4; v7 via a library

Satu peringatan terakhir: sebuah UUID mengenali, ia tak mengizinkan. Karena mereka tak bisa ditebak, tergoda memperlakukan sebuah URL tak terdaftar yang berisi satu sebagai privat. Tetapi pengenal bocor — melalui log, riwayat browser, header perujuk, dan tangkapan layar — jadi apa pun yang benar-benar butuh dilindungi tetap butuh sebuah pemeriksaan izin nyata di baliknya.

Pertanyaan yang sering diajukan

Apakah saya sebaiknya memakai v4 atau v7?
Pakai v7 untuk kunci utama basis data dan apa pun yang akan Anda sortir berdasarkan waktu pembuatan: stempel waktu di depan menjaga sisipan bergerombol di ujung indeks alih-alih tersebar. Pakai v4 ketika pengenal tak boleh mengungkap apa pun, termasuk kapan ia dibuat.
Apakah dua UUID pernah sama?
Mungkin tetapi teramat kecil kemungkinannya. Versi 4 punya 122 bit acak, jadi bahkan setelah menghasilkan miliaran nilai probabilitas tumbukan tetap jauh di bawah probabilitas penyimpanan diam-diam merusaknya.
Apa yang terjadi pada versi 1, 3, dan 5?
Versi 1 mengodekan sebuah stempel waktu dan alamat MAC mesin, yang membocorkan identitas perangkat keras dan tak bisa dihasilkan di browser sama sekali. Versi 3 dan 5 menurunkan sebuah UUID secara deterministik dari sebuah ruang-nama dan sebuah nama memakai MD5 atau SHA-1 — berguna ketika masukan yang sama harus selalu menghasilkan pengenal yang sama, tetapi pekerjaan berbeda dari menghasilkan yang baru.
Apakah sebuah UUID cukup aman untuk dipakai sebagai token rahasia?
Sebuah UUID v4 tak bisa ditebak, tetapi yang v7 secara terbuka mengodekan waktu pembuatannya, dan tak satu pun dimaksudkan sebagai kredensial. Untuk setel-ulang-sandi, token sesi, atau tautan berbagi, hasilkan sebuah rahasia acak khusus dan periksa izin di server ketimbang mengandalkan pengenal yang sulit ditebak.
Mengapa batch v7 saya tak tersortir sempurna di alat lain?
Karena banyak implementasi melewati pencacah monotonik. Ketika beberapa nilai berbagi sebuah milidetik, urutannya jatuh ke bit acak yang mengikuti. Alat ini mengimplementasikan pencacah RFC 9562, jadi sebuah batch yang dihasilkan di sini meningkat ketat.
Bagaimana saya sebaiknya menyimpan sebuah UUID dalam basis data?
Dalam sebuah tipe asli 16-bita tempat ada — uuid di PostgreSQL, uniqueidentifier di SQL Server, BINARY(16) di MySQL. Menyimpan bentuk teks 36-karakter alih-alih lebih dari menggandakan ruang yang dipakai dalam baris dan dalam setiap indeks yang menyertakan kolomnya.
Apakah ini dihasilkan di server Anda?
Tidak. Mereka dihasilkan di browser Anda memakai crypto.getRandomValues, sumber acak kriptografis platform — yang sama dipakai crypto.randomUUID. Tak ada nilai yang pernah dikirim ke mana pun, dan memuat ulang halaman menghasilkan set yang sama sekali baru.