UUID v7 Üretici
Veritabanı birincil anahtarları için zamana göre sıralı UUID v7 oluşturur
…
Biçimle
UUID v7 Nedir?
UUID v7, RFC 9562'de (Mayıs 2024) standartlaştırılmış yeni nesil bir UUID biçimidir. En anlamlı bitlere 48 bitlik Unix milisaniye zaman damgası kodlar, ardından sürüm ve varyant işaretçileri gelir ve kalan bitleri kriptografik açıdan güvenli rastgele verilerle doldurur.
Zaman damgası yüksek bitleri kapladığından UUID v7 değerleri kronolojik olarak sıralanır — hem sözcüksel hem de sayısal olarak. Bu, rastgele UUID'lerin (v4) B-ağacı dizini parçalanmasına neden olduğu veritabanı birincil anahtarları için mükemmel bir seçimdir.
Rastgele UUID'ler Veritabanı Dizinlerini Neden Parçalar
B-ağacı dizinleri — PostgreSQL, MySQL, SQLite ve çoğu veritabanı tarafından kullanılır — satırları anahtar değerine göre sıralı tutar.
UUID v4 (tamamen rastgele) ile her yeni ekleme, dizin ağacında özünde rastgele bir konuma yerleşir. Bu, veritabanını dizin sayfalarını sürekli okumaya ve yeniden yazmaya zorlar.
UUID v7 Bit Düzeni
UUID v7 128 bit genişliğinde olup altı alana bölünür:
| Bit | Alan | Amaç |
|---|---|---|
| 48 | unix_ts_ms | Milisaniye cinsinden 48 bitlik Unix zaman damgası — yüksek yarının tamamını kaplar |
| 4 | ver | Sürüm numarası — her zaman 0111 (ondalık 7) |
| 12 | rand_a | 12 bit kriptografik açıdan güvenli rastgele veri |
| 2 | var | Varyant işaretçisi — her zaman 10 (RFC 4122 varyantı) |
| 62 | rand_b | 62 bit kriptografik açıdan güvenli rastgele veri |
Zaman damgası hassasiyeti 1 milisaniyedir. UUID v7 değerleri k-sıralanabilirdir: zamansal olarak yakın oluşturulan ID'ler dizinde yakın sıralanır.
UUID v7 ile UUID v1 Karşılaştırması
Hem UUID v1 hem de UUID v7 bir zaman damgası gömüyor, ancak tasarım açısından önemli ölçüde farklılar:
| Özellik | UUID v7 | UUID v1 |
|---|---|---|
| Dönem / Zaman Tabanı | Unix dönemi (1 Ocak 1970) | Gregoryen dönemi (15 Ekim 1582) |
| Zaman Hassasiyeti | 1 milisaniye | 100 nanosaniye |
| Sıralanabilir | Evet — tasarımdan k-sıralanabilir | Hayır — zaman alanları UUID düzeninde karıştırılmış |
| Gizlilik | Ana bilgisayar bilgisi sızdırılmıyor | Oluşturan ana bilgisayarın MAC adresini gömer |
| Veritabanı Dizin Performansı | Mükemmel — sıralı eklemeler, minimal parçalanma | Zayıf — zaman damgasına rağmen sıralı değil |
| Standart | RFC 9562 (2024) | RFC 4122 (2005) |
| Yerel Tarayıcı Desteği | Henüz yok (crypto.randomUUID v7 yok) | Yerel olarak mevcut değil |
Zaman sıralı UUID'lere ihtiyaç duyan herhangi bir yeni proje için UUID v1 yerine UUID v7'yi tercih edin.
UUID v7 ile ULID Karşılaştırması
ULID, UUID v7'ye benzer bir sorunu çözer. Karşılaştırma:
- RFC 9562 UUID standardını izler — tüm UUID araçlarıyla uyumlu
- Tireli onaltılık biçim — evrensel olarak tanınan
- Yerel veritabanı UUID sütun desteği
- Toplam 128 bit
- Crockford Base32 kodlama — 26 karakter, biraz daha kompakt
- Büyük/küçük harf duyarsız ve belirsiz karakterlerden (I, L, O, U) kaçınır
- Bakışta daha insan tarafından okunabilir
- Kitaplık gerektirir — yerel platform desteği yok
UUID ekosistemindeyseniz UUID v7'yi kullanın. Taze başlıyorsanız ve insan dostu kodlamayı tercih ediyorsanız ULID makul bir alternatiftir.
Veritabanlarında UUID v7 Kullanımı
UUID v7 henüz çoğu veritabanı tarafından yerel olarak oluşturulmamaktadır ancak standart UUID sütunlarında depolanabilir:
uuid sütununa depolayın. pg-uuidv7 uzantısı DB tarafından oluşturulan ID'ler için uuid_generate_v7() sunucu taraflı işlevi ekler.BINARY(16) veya CHAR(36) sütununa depolayın. Uygulama kodunda oluşturun.TEXT (36 karakter) veya BLOB (16 bayt) olarak depolayın. TEXT üzerinde sözcüksel sıralama doğru çalışır.Kod Örnekleri
UUID v7 henüz crypto.randomUUID() aracılığıyla mevcut değil. Yerel destek gelene kadar uuidv7 (npm) gibi bir kitaplık kullanın:
function generateUuidV7() {
const buf = new Uint8Array(16)
crypto.getRandomValues(buf)
const ms = BigInt(Date.now())
// Embed 48-bit Unix ms timestamp
buf[0] = Number((ms >> 40n) & 0xFFn)
buf[1] = Number((ms >> 32n) & 0xFFn)
buf[2] = Number((ms >> 24n) & 0xFFn)
buf[3] = Number((ms >> 16n) & 0xFFn)
buf[4] = Number((ms >> 8n) & 0xFFn)
buf[5] = Number(ms & 0xFFn)
// Set version 7 (0111xxxx)
buf[6] = (buf[6] & 0x0F) | 0x70
// Set variant (10xxxxxx)
buf[8] = (buf[8] & 0x3F) | 0x80
const hex = [...buf].map(b => b.toString(16).padStart(2, '0')).join('')
return `${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20)}`
}
// Node.js 20+ built-in
// import { randomUUID } from 'node:crypto' // v4 only — no v7 yet in stdlib# pip install uuid7 import uuid_extensions uid = uuid_extensions.uuid7() print(uid) # e.g. 018e2b3d-1a2b-7000-8000-abc123456789 print(uid.time) # Unix ms timestamp embedded in the UUID # Or as a plain string from uuid_extensions import uuid7str print(uuid7str())
-- PostgreSQL 13+ extension-free implementation
CREATE OR REPLACE FUNCTION uuid_generate_v7()
RETURNS uuid
LANGUAGE sql
AS $$
SELECT encode(
set_bit(
set_bit(
overlay(
uuid_send(gen_random_uuid())
PLACING substring(int8send(floor(extract(epoch FROM clock_timestamp()) * 1000)::bigint) FROM 3)
FROM 1 FOR 6
),
52, 1
),
53, 1
),
'hex'
)::uuid;
$$;
-- Usage as a default primary key
CREATE TABLE events (
id uuid PRIMARY KEY DEFAULT uuid_generate_v7(),
payload jsonb,
created_at timestamptz DEFAULT now()
);function extractTimestamp(uuid: string): Date {
const hex = uuid.replace(/-/g, '')
const ms = parseInt(hex.slice(0, 12), 16) // first 48 bits = ms timestamp
return new Date(ms)
}
const uid = '018e2b3d-1a2b-7000-8000-abc123456789'
console.log(extractTimestamp(uid).toISOString())
// → "2024-03-15T10:22:05.259Z"