UUID ve ULID Oluşturucu
Tarayıcının kriptografi API destegiyle UUID v4, UUID v7 ve ULID üretin. v7 ve ULID kimliklerinin veritabanı indekslerinde neden v4 kadar dağılmadığını anlatır.
v4: 122 bit rastgelelik taşır, hiçbir sıralama bilgisi içermez. Veritabanı birincil anahtarı olarak kullanıldığında indeks eklemeleri dağınık olur.
- 53ccbf45-ed8d-4309-98f9-d22fd2a0036f
- ad7c8f72-ec17-4d1f-b805-53f141d7146c
- 906c4049-46a3-43a9-a97f-94d1b15ac41d
- f91e6a97-7cba-45e8-ae4b-8bb615b8912a
- 10be858f-e1b0-4b27-b80e-d6c688bffd4f
Bir kimliği çözümle
Bir UUID yapıştırın, sürümü ve varsa içindeki zaman burada görünecek.
Özet (TL;DR)
- UUID v4 tamamen rastgeledir, ardışık kayıtlar B-tree indeksinde her yere dağılır ve indeks parçalanır.
- UUID v7, ilk 48 biti milisaniye cinsinden zaman damgası olduğu için oluşturulma sırasına göre sıralanır ve ekleme işlemi indeksin sonuna düşer.
- ULID aynı fikri 26 karakterlik Crockford base32 ile uygular: URL güvenli ve büyük küçük harf ayrımı yok.
- v7 ve ULID oluşturulma zamanını AÇIK EDER; zamanı gizli olması gereken kayıtlarda v4 kullanın.
Birincil anahtarın indeksi parçaladığı gün
Tabloyu UUID birincil anahtarla kurdunuz, ilk aylar sorunsuz geçti. Satır sayısı milyonu geçtikten sonra ekleme işlemleri yavaşlamaya başladı ve kimse tek bir sorguyu suçlayamadı. Sebep sorguda değil, anahtarın kendisinde: v4 tamamen rastgele olduğu için her yeni kayıt indeks ağacında rastgele bir yaprağa düşüyor, veritabanı her seferinde başka bir sayfayı diskten okuyup bölmek zorunda kalıyor.
v4 ile v7 arasındaki gerçek fark
UUID v4'ün 122 biti rastgeledir, kalan 6 bit sürüm ve varyant alanlarına gider. Bu rastgelelik kimlik olarak mükemmel ama indeks için felaket: art arda üretilen iki v4 değeri sıralamada birbirinden çok uzağa düşer. v7 ise ilk 48 bite Unix milisaniyesini big-endian yazar, geri kalanı rastgele bırakır. Sonuç şu: metinsel sıralama oluşturulma sırasıyla örtüşüyor, yeni kayıtlar indeksin sonuna ekleniyor ve veritabanı hep aynı sayfalarla çalışıyor.
# Art arda uretilen v4 (siralama rastgele)9f8a2c14-... 3b1e77d0-... c40d5e92-... 1a7f30bb-... # Art arda üretilen v7 (sıralama oluşturulma sırası)01994e2a-7c10-7... 01994e2a-7c10-7... 01994e2a-7c11-7...^^^^^^^^^^^^^ ortak zaman oneki, tarih ilerledikce buyuyor # ULID (26 karakter, Crockford base32)01JQ8ZK4T0XA9V7C2M5N3PQRSD^^^^^^^^^^ ilk 10 karakter zaman, kalan 16 rastgeleBig-endian yazım burada üslup tercihi değil zorunluluk. Yalnızca bu sırada, kodlanmış metnin bayt bayt karşılaştırılması zaman damgasının sayısal karşılaştırmasıyla örtüşür. Little-endian yazılmış bir v7 gözle aynı görünür ama sıralaması rastgele çıkar, yani tek faydasını kaybeder. Aynı milisaniye içinde üretilen kimliklerde de sıra garanti altında: rand_a alanının 12 biti sayaç olarak kullanılıyor, böylece döngü içinde üretilen yüz kimlik de sıralı geliyor.
| Özellik | UUID v4 | UUID v7 | ULID |
|---|---|---|---|
| Uzunluk | 36 karakter | 36 karakter | 26 karakter |
| Sıralanabilir | Hayır | Evet | Evet |
| Rastgele bit | 122 | 74 | 80 |
| Zaman açığa çıkar | Hayır | Evet (milisaniye) | Evet (milisaniye) |
| Kodlama | Onaltılık | Onaltılık | Crockford base32 |
ULID ve Crockford base32
ULID, v7 ile aynı fikri farklı bir kabukta sunuyor: 48 bit zaman, 80 bit rastgelelik, hepsi 26 karakterlik Crockford base32 metin. Alfabeden I, L, O ve U harfleri çıkarılmış. İlk üçü ekrandan elle kopyalarken 1 ve 0 rakamlarıyla karıştığı için, U ise kodlamanın tesadüfen çirkin kelimeler üretmemesi için. Değer büyük küçük harf ayrımı yapmaz ve tire içermez, bu da onu URL'de ve çift tıklamayla seçilen metinlerde rahat kullanılır kılar. Zaman öneki tam olarak 10 karakter olduğu için önek üzerinden aralık taraması yapabilirsiniz.
Uyarı
Çakışma riski ve otomatik artan tamsayılar
v4'te 122 bit rastgelelik var ve bu pratikte çakışmayı gündem dışı bırakıyor. Kabaca ölçek vermek gerekirse, çakışma olasılığının hissedilir hale gelmesi için milyarlarca kimlik üretmeniz gerekir. Asıl risk matematikte değil, zayıf rastgelelik kaynağında: Math.random() tabanlı üreteçler UUID'ye benzeyen ama tahmin edilebilir değerler üretir. Bu araç her baytı crypto.getRandomValues ile alıyor ve sürüm ile varyant nibble'larını açıkça yazıyor, yani Postgres uuid tipi ya da Java UUID.fromString gibi katı ayrıştırıcılar değeri reddetmiyor.
Otomatik artan tamsayıyla karşılaştırınca tablo netleşiyor. Tamsayılar kısa, indeks dostu ve okunması kolay ama iki zayıf noktası var: /siparis/1042 adresini gören biri /siparis/1043 deneyebilir ve numaralar iş hacminizi ele verir. Ayrıca değeri yalnızca veritabanı üretebildiği için, kaydı yazmadan önce kimliğini bilemezsiniz. UUID'de kimliği istemci tarafında üretip ilişkili kayıtları tek turda kurabilirsiniz. Bedeli sekiz bayt yerine on altı bayt ve daha uzun bir metin gösterimi.
Sıkça Sorulan Sorular
- v4 mü v7 mi kullanmalıyım?
- Veritabanı birincil anahtarı için v7, çünkü indeks yerelliği ekleme başarımında somut fark yaratır. Oluşturulma zamanının görünmesi sakıncalıysa ya da kimliği tahmin edilemezliği önemseyen bir yerde kullanıyorsanız v4. Var olan bir tabloyu dönüştürmek için ise iyi bir sebep gerekir, ikisi de aynı 36 karakterlik alana sığar.
- UUID'ler çakışır mı?
- Pratikte hayır. v4'ün 122 bitlik rastgeleliğiyle çakışma olasılığı ihmal edilebilir düzeyde kalır. Asıl tehlike matematiksel çakışma değil, zayıf rastgelelik kaynağı:
Math.random()ile üretilen sahte UUID'ler hem tahmin edilebilir hem de düzgün dağılmamıştır. - UUID mi otomatik artan tamsayı mı?
- Tamsayı daha küçük ve okunması kolay ama numaralandırılabilir olduğu için kayıt sayınızı ve sıranızı açık eder, ayrıca kimliği yalnızca veritabanı üretebilir. UUID dağıtık üretime izin verir ve tahmin edilemez, karşılığında iki katı yer kaplar. Dağıtık sistemlerde ve dışa açık kaynak adreslerinde UUID, tek veritabanlı iç tablolarda tamsayı makul.
- UUID gizli bir değer sayılır mı?
- Sayılmaz. UUID'yi tek başına oturum anahtarı, parola sıfırlama token'ı ya da yetki kanıtı olarak kullanmayın. v4 kriptografik olarak güçlü bir kaynaktan gelse bile UUID'ler loglara, Referer başlıklarına ve URL geçmişine düşer. Token gerekiyorsa amaca özel, süresi dolan ve iptal edilebilen bir yapı kurun.
- ULID nedir?
- UUID v7 ile aynı fikrin farklı kodlaması: 48 bit zaman damgası, 80 bit rastgelelik, 26 karakterlik Crockford base32 metin. Tire yok, büyük küçük harf ayrımı yok, karıştırılabilir I/L/O/U harfleri alfabede yok. URL'de ve elle kopyalanan kimliklerde UUID'den rahat kullanılır.