Kısa cevap
Yeni veritabanı anahtarları, olay kimlikleri, log kayıtları ve kronolojik sırada olmasını istediğin dosya adları için UUID v7 seç. Yeni v7 değerleri her zaman eskilerinden büyüktür; bu yüzden indeksin sonuna, otomatik artan bir sayı gibi eklenirler. Üstelik veritabanına sormadan, herhangi bir sunucuda ya da tarayıcıda üretilebilirler.
Token'lar, oluşturulma zamanının gizli kalması gereken herkese açık kimlikler ve zaten v4 kullanan sistemler için UUID v4 seç. v4 hiçbir şey sızdırmaz ve milyonlarca satır tutmayan çoğu uygulamada rastgele sırasının maliyeti düşüktür. İki sürüm de 2024'te yayımlanan RFC 9562'de tanımlı; bu standart eski RFC 4122'nin yerini aldı ve 6, 7 ve 8. sürümleri ekledi.
Burada dene: UUID v7 oluşturucu
Aracın tam sayfasını açBir UUID nasıl kurulur
Her UUID, beş gruba bölünmüş 32 onaltılık (hex) haneyle yazılan 128 bittir: 8-4-4-4-12, tirelerle birlikte 36 karakter. Her modern UUID'de iki alan sabittir. Üçüncü grubun ilk hanesi sürümdür, bir bakışta okunur: rastgele için 4, Unix zamanı için 7. Dördüncü grubun ilk hanesi varyanttır ve standart UUID'lerde her zaman 8, 9, a ya da b'dir.
Örnek v4: 9b2f4c1e-3a7d-4e8b-a5c2-0f6d1e9a3b47. Örnek v7: 019a2b3c-4d5e-7f60-8a1b-2c3d4e5f6a7b. v7 örneğindeki ilk 12 hex hane (019a2b3c4d5e) milisaniye cinsinden oluşturulma zamanıdır; bir saniye arayla üretilen kimliklerin başlangıcının büyük kısmı bu yüzden aynıdır.
| Bölüm | UUID v4 | UUID v7 |
|---|---|---|
| Toplam boyut | 128 bit | 128 bit |
| Zaman damgası | Yok | 48 bit, milisaniye cinsinden Unix zamanı |
| Sürüm ve varyant | 6 bit (sürüm 4) | 6 bit (sürüm 7) |
| Rastgele bit | 122 | 74 (12'si sayaç olarak kullanılabilir) |
| Sıralama | Rastgele | Oluşturulma zamanına göre |
| Oluşturulma zamanını gösterir mi | Hayır | Evet, milisaniyesine kadar |
| Zaman damgası ne zamana kadar yeter | Geçerli değil | Yaklaşık 10889 yılına kadar |
v7 birincil anahtar olarak neden daha hızlı
Çoğu veritabanı birincil anahtarı, anahtara göre sıralı bir B-tree indekste tutar. Rastgele v4 anahtarlarda her ekleme ağacın rastgele bir yerine düşer. İndeks belleğe sığmayacak kadar büyüyünce eklemeler sürekli diskten eski sayfaları okur, sayfalar yarı dolu bölünür ve indeks gerektiğinden büyük olur. MySQL ve MariaDB'nin InnoDB motorunda tablonun kendisi de birincil anahtar sırasıyla saklandığı için sadece indeks değil, tüm tablo etkilenir.
v7 anahtarlarda yeni satırlar indeksin sağ ucuna gider, sıcak sayfalar bellekte kalır ve sayfalar tamamen dolar. Veritabanı üreticilerinin ve kullanıcıların ölçümleri büyük tablolarda v4'e göre belirgin şekilde daha hızlı eklemeler ve daha küçük indeksler gösteriyor; kazancın büyüklüğü motora, satır boyutuna ve donanıma bağlı. "Son 100 sipariş" gibi aralık sorguları da ucuzlar, çünkü yeni satırlar yan yana durur.
UUID'leri, varsa yerel 16 baytlık tipte sakla (PostgreSQL'de uuid, MySQL'de BINARY(16), SQL Server'da uniqueidentifier); 36 karakterlik metin olarak değil. Metin anahtarlar iki kattan fazla yer kaplar ve karşılaştırması yavaştır.
Veritabanı notları: PostgreSQL, MySQL, SQL Server, .NET
- PostgreSQL: uuid tipi bayt bayt sıralanır, v7 sırası korunur. PostgreSQL 18 yerleşik uuidv7() fonksiyonunu ekledi; eski sürümlerde değeri uygulama üretebilir.
- MySQL ve MariaDB: UUID_TO_BIN(değer) ile, swap bayrağı olmadan BINARY(16) olarak sakla; v7 sırası korunur. MySQL'in kendi UUID() fonksiyonu v7 değil, sürüm 1 üretir.
- SQL Server: uniqueidentifier karşılaştırmada önce son bayt grubuna bakar, bu yüzden v7 değerleri orada zaman sırasıyla dizilmez. SQL Server'da sıralı anahtar gerekiyorsa NEWSEQUENTIALID() ya da bigint identity çoğu zaman daha basit bir seçimdir.
- .NET: Guid.NewGuid() v4 döndürür. .NET 9'dan beri Guid.CreateVersion7() v7 döndürür.
- JavaScript: tarayıcılarda ve Node.js'te crypto.randomUUID() v4 döndürür; v7 için bir kütüphane ya da bu sayfadaki üreticinin arkasındaki gibi küçük bir fonksiyon gerekir.
Gerçek sayılarla çakışma ihtimali
122 rastgele bitle v4'te çakışma bir doğum günü problemidir. Tek bir tekrarın yüzde 50 ihtimali için yaklaşık 2,7 kentilyon (2,7 x 10^18) UUID gerekir; bu, yaklaşık 86 yıl boyunca her saniye bir milyar yeni kimlik demek. Bozuk rastgele sayı üreteçleri, kopyalanan sanal makine anlık görüntüleri ve aynı değeri tekrar kullanan hatalar, şanstan çok daha gerçekçi tekrar sebepleridir.
v7'de rastgele bit daha az, ama bunların sadece aynı milisaniye içinde benzersiz olması gerekir. Tek bir milisaniyede bir milyon kimlik üreten bir servis bile pratikte tehlikede değil. Üreteçler milisaniye içinde bir sayaç da tutar (bu araç da tutar), böylece hızlı bir toplu üretimde kimlikler kesin sıralı kalır.
Yine de kolonda her zaman benzersizlik kısıtı (unique constraint) tut. Hiçbir maliyeti yok ve imkânsız bir olayı bozuk veri yerine net bir hataya çevirir.
UUID ve GUID, diğer sürümler
GUID (globally unique identifier), Microsoft'un UUID'ye verdiği addır. Aynı 128 bitlik değerdir; Windows araçları genelde büyük harfle, bazen de süslü parantez içinde yazar: {3F2504E0-4F89-41D3-9A0C-0305E82C3301}. Üreticideki Büyük harf, Tireler ve Süslü parantez seçenekleri bu biçimleri karşılar.
Sürüm 1, zaman damgasını ağ kartı adresiyle birleştirir; makineyi belli edebildiği için bugün nadiren önerilir. Sürüm 6, zamana göre sıralanacak şekilde yeniden düzenlenmiş sürüm 1'dir. Sürüm 3 ve 5 bir addan MD5 ya da SHA-1 ile türetilir, aynı girdi her zaman aynı UUID'yi verir. Sürüm 8 özel düzenler için serbesttir. ULID, v7 ile aynı fikre sahip popüler bir UUID dışı biçimdir; ama v7 mevcut her uuid kolonuna sığar.
v7 ne zaman yanlış seçim
- Oluşturulma zamanı hassas olan herkese açık kimlikler: URL'deki bir v7, hesabın, siparişin ya da belgenin ne zaman oluşturulduğunu gösterir.
- Token'lar, davet linkleri ve şifre sıfırlama kodları: v4 ya da daha uzun rastgele bir token kullan, asla zamandan tahmin edilebilecek bir şey değil.
- SQL Server uniqueidentifier gibi kimlikleri farklı bayt sırasıyla karşılaştıran sistemler.
- v4 anahtarlarla dolu mevcut tablolar: sürümleri karıştırmak çalışır ama indeks kazancını sadece yeni satırlarda görürsün.