PostgreSQL'de birincil anahtar olarak UUID kullanmak hakkında
(maciejwalkowiak.com)- UUID, veritabanı tablolarında birincil anahtar olarak sıkça kullanılır
- Üretmesi kolaydır, dağıtık sistemler arasında paylaşılması kolaydır ve benzersizliği garanti eder
- UUID'nin boyutu düşünüldüğünde bunun doğru seçim olup olmadığı sorgulanabilir, ancak çoğu zaman buna biz karar veremeyiz
- Bu yazı, "UUID anahtar için uygun bir format mı" sorusuna odaklanmak yerine PostgreSQL'de UUID'yi birincil anahtar olarak verimli biçimde nasıl kullanabileceğinizi anlatıyor
PostgreSQL'de birincil anahtar olarak UUID kullanmak
- UUID nedir?
- UUID, veritabanı tablolarında birincil anahtar olarak sıkça kullanılır
- Dağıtık sistemler arasında kolayca paylaşılabilir ve benzersizliği garanti eder
- Boyutu nedeniyle uygunluğu sorgulanabilir, ancak çoğu zaman başka seçenek yoktur
PostgreSQL'de UUID veri tipi
-
UUID'yi string olarak saklamak
- PostgreSQL, string saklamak için
textveri tipini sunar - Ancak
texttipi, UUID saklamak için uygun değildir - PostgreSQL, UUID için özel
uuidveri tipini sunar uuidtipi 128 bitlik bir veri tipidir ve tek bir değeri saklamak için 16 bayt gerekirtexttipinde ek olarak 1 veya 4 baytlık overhead bulunur
- PostgreSQL, string saklamak için
-
Deney sonuçları
- Karşılaştırma için iki tablo oluşturuldu: biri
texttipi, diğeriuuidtipi - 10.000.000 satır eklendikten sonra tablo boyutu ve indeks boyutu karşılaştırıldı
texttipi kullanan tablo %54 daha büyük, indeks boyutu ise %85 daha büyüktü
- Karşılaştırma için iki tablo oluşturuldu: biri
UUID ve B-Tree indeksleri
-
B-Tree indeksleri ve UUID
- Rastgele UUID'ler B-Tree indeksleri için uygun değildir
- B-Tree indeksleri sıralı değerlerle iyi çalışır
- Java'nın
UUID.randomUUID()metodu UUID v4 döndürür; bu, sözde rastgele bir değerdir - UUID v7 zaman sırasına göre düzenlenmiş değerler üretir ve bu nedenle B-Tree indeksleri için daha uygundur
-
UUID v7 kullanımı
- Java'da UUID v7 kullanmak için
java-uuid-generatorkütüphanesi gerekir - UUID v7 üretmek, ekleme performansını iyileştirebilir
- Java'da UUID v7 kullanmak için
UUID v7'nin INSERT performansına etkisi
- Deney
- UUID v7 kullanan bir tablo oluşturulup 10.000 satır 10 kez eklenerek performans ölçüldü
- Sonuçlar biraz rastgele olsa da UUID v7 eklemek yaklaşık 2 kat daha hızlıydı
Ek okuma
- PostgreSQL 17'de UUID v7'nin yerel olarak desteklenmesi mümkün olabilir
- UUID v7 formatı hakkında bilgi
- UUID'nin veritabanı birincil anahtarı olarak performansa etkisi
Özet
-
UUID uzunluğu sorunu
- Optimizasyon yapılsa bile UUID, birincil anahtar için en ideal tip değildir
- Seçenek varsa TSID gibi başka alternatifler değerlendirilmelidir
-
Optimizasyon ihtiyacı
- Büyük veri kümeleri veya yüksek trafik bekleniyorsa optimizasyon düşünülmelidir
- Birincil anahtarı değiştirmek zor bir iştir; bu yüzden baştan doğru kurmak önemlidir
-
Dikkat edilmesi gerekenler
- Yazar bir PostgreSQL uzmanı olmadığını, sadece öğrendiklerini paylaştığını belirtiyor
- Faydalı bulduysanız yorum veya Twitter üzerinden geri bildirim bekliyor
GN⁺ Özeti
- Bu yazı, PostgreSQL'de UUID'yi birincil anahtar olarak kullanırken daha verimli yöntemleri ele alıyor
- Deneyler, UUID v7 kullanmanın ekleme performansını artırabileceğini gösteriyor
- Büyük veri kümeleri veya yüksek trafik beklenen durumlarda optimizasyon gerekli olabilir
- TSID gibi başka seçenekler de değerlendirmeye değer
4 yorum
UUID için standart biçim (onaltılık + tireler) yerine base62 kodlaması istemek fazla mı olur?
uuidv7 yenilmezdir
uuidv8+ ise "tanrı"dır
En büyük engel, insan dostu olmaması.. Benim için hâlâ birçok noktada bu kısım gerekiyor..
Hacker News görüşü
B-tree dostu birincil anahtar olarak
bigserialkullanılmasını ve harici kayıt konumlandırıcı seçeneği olarak dizeye kodlanmış UUID düşünülmesini öneriyorhashidskullanmayın; kriptografik kalitesi yoktur ve sıradan kullanıcılara da tanıdık gelmezVeritabanı şeması tasarlarken ilgi alanlarının ayrılması ve mekanik sempatinin ilkelerini akılda tutun
Stripe’ın tiplenmiş rastgele ID’leri aslında rastgele değil
bigserial+HMAC konumlandırıcıları tercih ediyorumPostgres’te rastgele UUID büyük bir sorun değil
serial(4 bayt) veyabigserial(8 bayt) değerlerinden daha büyüktür, ancak tüm tablo düzeyinde bu büyük bir mesele değildirPostgres’te
serialvs. rastgele UUID vs. sıralı UUID konusunu düşünmeden önce endişelenmeniz gereken çok daha fazla şey varYakın zamanda Postgres PK’si olarak ULID seçtim ve bu makaleden çok faydalandım: https://brandur.org/nanoglyphs/026-ids
ULID’yi tercih etmemin nedeni UUID türüyle uyumlu olması ve gömülü bir zaman damgası içermesi; bu sayede ID’ye göre sıralandığında zaman damgası sırasına göre de sıralanıyor
Karşılaştırmaya
int64da dahil edilse, UUID ile geleneksel yaklaşımın ek yükünü kıyaslamak iyi olurduEkleme performansı, performansı değerlendirmek için kötü bir yöntemdir
SQLite’ta UUID4’ün tercih edilme nedeni, işlem kilidi sırasında sayfa önbelleği çakışması olasılığının daha düşük olmasıdır
Tamsayı otomatik artan birincil anahtarları tercih ediyorum
UUIDv7 ekleme zamanı benchmark’ı UUID oluşturma süresini de içeriyor
PostgreSQL 17’de UUIDv7 desteğinin yer alma olasılığı düşük
python-ulidkullanmaya başladım ve ULID’nin UUID’den daha üstün olduğunu düşünüyorumUUID v7 standardı bağlantısı eski kaldığı için RFC 9562’ye bakın: https://datatracker.ietf.org/doc/html/rfc9562