Veritabanında UUID Kullanımının Artı ve Eksileri
"Birincil anahtar için UUID mi, auto-increment mı?" sorusu her yeni şema tasarımında karşınıza çıkar ve doğru cevap "duruma göre değişir"dir. Bu rehberde UUID'i veritabanı birincil anahtarı yapmanın gerçek artılarını ve eksilerini karşılaştırma tablolarıyla ortaya koyuyoruz.
UUID'i veritabanı birincil anahtarı yapmalı mıyım?
Yani soru aslında "UUID mi auto-increment mı" değil, "hangi UUID versiyonu mu, yoksa auto-increment mi" şeklinde sorulmalı. Aşağıda her iki yaklaşımın da gerçek avantaj ve dezavantajlarını inceliyoruz; kendi UUID'lerinizi UUID Üretici'de deneyebilirsiniz.
Artılar: UUID neden tercih edilir?
- Dağıtık üretim: Birden fazla sunucu, mikroservis veya çevrimdışı mobil istemci, birbirine danışmadan kayıt oluşturabilir; senkronizasyon anında ID çakışması yaşanmaz.
- Merkezi koordinasyon gerekmez: Auto-increment'te "bir sonraki ID kaç" sorusunun tek bir doğru cevabı olmalıdır (bu bir darboğaz noktası olabilir); UUID'de böyle bir soru yoktur.
- Bilgi sızdırmaz: Sıralı bir ID (
/siparis/1042) toplam sipariş sayınızı ve büyüme hızınızı rakiplere açık eder; UUID bu bilgiyi gizler. - Tahmin edilemez, daha güvenli: Sıralı ID'ler bir sonraki/önceki kaydı deneyerek erişim (IDOR) saldırılarına açık kapı bırakır; rastgele UUID bunu pratik olarak imkânsız kılar.
- Birleştirme (merge) kolaylığı: İki veritabanını (ör. şirket birleşmesi, çoklu bölge replikasyonu) birleştirirken auto-increment ID'ler çakışır; UUID'ler çakışmaz.
Eksiler: performans ve depolama maliyeti
BIGINT'in (8 bayt) iki katı yer kaplar — milyonlarca satır ve çok sayıda yabancı anahtarda bu fark birikir.
Bu problemin kökeni şudur: çoğu ilişkisel veritabanı motoru (MySQL/InnoDB, PostgreSQL, SQL Server) birincil anahtar indeksini B-tree yapısında tutar ve yeni satırların sıralı eklenmesini bekleyecek şekilde optimize edilmiştir. Auto-increment bu varsayıma uyar; her yeni satır indeksin sonuna eklenir. Tamamen rastgele bir v4 UUID ise indeksin rastgele bir noktasına düşer — bu da sayfa bölünmesine (page split) ve önbellek isabet oranının düşmesine yol açar.
| Etki alanı | Auto-increment (BIGINT) | v4 UUID (rastgele) |
|---|---|---|
| Anahtar boyutu | 8 bayt | 16 bayt |
| İndeks ekleme sırası | Sıralı (indeks sonuna) | Rastgele (indeksin her yerine) |
| Sayfa bölünmesi (fragmentation) | Minimal | Yüksek olabilir |
| Kayıt sayısını gizleme | Hayır (sızdırır) | Evet |
| Dağıtık/çevrimdışı üretim | Hayır (çakışma riski) | Evet (çakışmasız) |
Not: Gerçek etki; veritabanı motoru, indeks türü ve donanıma (SSD/NVMe) göre değişir. NVMe SSD'lerde rastgele I/O maliyeti eski dönemlere göre belirgin şekilde azalmıştır.
v7 UUID'i hemen deneyin
Zaman sıralı, veritabanı dostu v7 UUID üretimi — art arda üretilen değerler sözlüksel olarak da zaman sırasına uyar.
UUID Üreticiyi Aç →Auto-increment, v4 UUID ve v7/ULID karşılaştırması
Aşağıdaki tablo, birincil anahtar seçiminde en sık karşılaştırılan üç yaklaşımı özetler. v7 ve ULID, "UUID'in dağıtık üretim avantajı" ile "auto-increment'in sıralı indeks avantajı"nı birleştirmeyi hedefler:
| Özellik | Auto-increment | v4 UUID | v7 UUID / ULID |
|---|---|---|---|
| Çakışmasız dağıtık üretim | Hayır | Evet | Evet |
| Sıralı indeks eklemesi | Evet | Hayır | Evet (yaklaşık) |
| Kayıt sayısını gizler | Hayır | Evet | Kısmen (zaman sızdırır) |
| Boyut | 8 bayt | 16 bayt | 16 bayt (ULID: 26 karakter metin) |
| Ekosistem desteği | Evrensel | Çok yaygın | Artan, bazı ORM'lerde ek kütüphane gerekir |
v7 ve ULID'in "kısmen gizler" notu önemlidir: zaman damgası içerdikleri için bir kaydın yaklaşık ne zaman oluşturulduğunu ifşa ederler (tam sayıyı değil). Kayıt zamanının gizli kalması kritikse (ör. hassas finansal veriler), v4 tercih edilmelidir.
Hangi durumda hangisini kullanmalı?
- Küçük/orta ölçekli, tek veritabanlı uygulama: auto-increment (BIGINT) genelde en basit, performanslı seçimdir.
- Mikroservis mimarisi veya çok bölgeli veritabanı: v7 UUID veya ULID — dağıtık üretim + sıralı indeks avantajını birlikte sunar.
- URL'de ID gösterilecek, kayıt sayısı gizli kalmalı (ör. sipariş no): v4 UUID veya ULID.
- Çevrimdışı çalışan mobil/masaüstü istemciler: v4 veya v7 UUID zorunludur — auto-increment çevrimdışı üretilemez.
- Eski, değiştirilemeyen auto-increment şema: dışarıya gösterilecek ayrı bir "public_id" (UUID) sütunu ekleyip iç ilişkilerde auto-increment'i koruyabilirsiniz.
Pratik öneriler özeti
| # | Öneri |
|---|---|
| 1 | Mümkünse v4 yerine v7 UUID veya ULID kullanın — indeks parçalanması riskini azaltır. |
| 2 | UUID'i metin (VARCHAR(36)) değil, yerel binary/UUID tipinde saklayın — depolama ve karşılaştırma performansı daha iyidir. |
| 3 | Yüksek yazma hacimli tablolarda önce ölçüm yapın — NVMe SSD rastgele I/O maliyetini büyük ölçüde azaltmış olabilir. |
| 4 | Mevcut auto-increment şemayı bozmadan, dışarıya gösterilecek bir public_id (UUID) sütunu ekleyebilirsiniz. |
| 5 | Kayıt zamanının kesinlikle gizli kalması gerekiyorsa v7/ULID yerine v4'ü tercih edin. |
UUID versiyonlarının farkını daha derin incelemek isterseniz "UUID Sürümleri Arasındaki Fark (v1, v4, v5)" rehberimize, temel kavramlara ise "UUID Nedir, Ne İşe Yarar?" yazımıza göz atabilirsiniz.