GUID / UUID veritabanı anahtarlarının avantajları ve dezavantajları


222

Geçmişte tüm veritabanı anahtarları GUID / UUID değerleri olsaydı, veritabanları arasında hareketli girişlerin çok daha kolay hale getirileceği bir dizi veritabanı sistemi üzerinde çalıştım . Bu yolda birkaç kez gitmeyi düşündüm, ancak özellikle performans ve telefon üzerinden okunabilen URL'ler hakkında her zaman biraz belirsizlik var.

Herkes bir veritabanında GUID'leri ile kapsamlı çalıştı? Bu yolla ne gibi avantajlar elde edebilirim ve olası tuzaklar nelerdir?


1
Jeff'in " Birincil Anahtarlar: Kimlikler ve GUID'ler " adlı bir yayını vardır .
jfs

1
uzaktaki müşteriler için Hi-Lo da kullanabilir: stackoverflow.com/questions/282099/whats-the-hi-lo-algorithm
Neil McGuigan


Jeff Atwood'un " Birincil Anahtarlar: Kimlikler ve GUID'ler " hakkındaki gönderisi için güncellenmiş konum . @Jfs referans için teşekkürler.
Adam Katz

@jfs Bağlantı olarak değiştirildi blog.codinghorror.com/primary-keys-ids-versus-guids
cr0ss

Yanıtlar:


229

Avantajları:

  • Onları çevrimdışı oluşturabilir.
  • Çoğaltmayı önemsiz kılar (int'lerin aksine, GERÇEKTEN zorlaştırır)
  • ORM genellikle onlar gibi
  • Uygulamalar arasında benzersiz. Bu yüzden bizim app (ayrıca guid) bizim CMS (guid) PK kullanabilirsiniz ve biz ASLA bir çatışma olacak biliyorum.

Dezavantajları:

  • Daha büyük alan kullanımı, ancak alan ucuz (er)
  • Ekleme siparişini almak için kimliğe göre sipariş verilemiyor.
  • Bir URL'de çirkin görünebilir, ancak gerçekten, WTF bir URL'ye GERÇEK DB anahtarı koymaya çalışıyorsunuz !? (Bu nokta aşağıdaki yorumlarda tartışılmıştır)
  • Manuel hata ayıklama yapmak daha zor, ama o kadar zor değil.

Şahsen, onları çoğu PK için iyi bir boyutta kullanıyorum, ancak her yerde çoğaltılan bir sistemde "eğitildim", bu yüzden onlara sahip olduk. YMMV.

Yinelenen veri şey çöp olduğunu düşünüyorum - ancak bunu yinelenen veri alabilirsiniz. Yedek anahtarlar genellikle çalıştığım yerde kaşlarını çattı. WordPress benzeri sistemi kullanıyoruz:

  • satır için benzersiz kimlik (GUID / her neyse). Asla kullanıcı tarafından görülemez.
  • public ID bir alandan ONCE üretilir (örneğin, başlık - makalenin başlığı yapın)

GÜNCELLEME: Yani bu çok + 1'ed alır ve GUID PK'ların büyük bir dezavantajına işaret etmem gerektiğini düşündüm: Kümelenmiş Endeksler.

Bir GUID'de çok fazla kaydınız ve kümelenmiş bir dizininiz varsa, sonunda değil (hızlı olan) öğeler listesindeki rastgele noktalara (nokta budur) eklediğiniz için ekleme performansınız SUCK olacaktır.

Ekleme performansına ihtiyacınız varsa, belki bir otomatik inc INT kullanın ve bunu başka biriyle paylaşmak istiyorsanız bir GUID oluşturun (yani, URL'deki bir kullanıcıya gösterin)


184
[WTF, bir URL'ye REAL DB anahtarı koyuyor musunuz ??] Neden sizi rahatsız ettiğinden emin değilsiniz. Başka ne kullanardınız? Yığın Taşmasına Bakın ... URL'nin her yerinde KİMLİK değerleri vardır ve gayet iyi çalışır. URL'lerde DB anahtarlarının kullanılması güvenliği zorlamanıza engel olmaz.
Euro Micelli

20
Hayır, değil, ama SEO gibi şeyler genellikle bir anahtar yoksa daha iyidir - özellikle bir GUID kadar bir şey. Tabii ki, kolayca etrafında çalışabilir, bu yüzden biraz fazla süpürme ifadesi olduğunu tahmin ediyorum
Nic Wise

7
İyi yanıt, ayrıca GUID'leri kullanmanın performans dezavantajları hakkında bilgi eklemeniz iyi olur; örneğin, birleştirme, sıralama ve dizine ekleme, tamsayıları kullanmaktan daha yavaş olacaktır. Kılavuzlar harika, ancak performans kritik olduğunda acı olabilecek bir maliyetle geliyorlar.
Doktor Jones

26
Bir şeyi aklınızda bulundurun, insanlar genellikle sayfa, soru, forum başlıklarını değiştirir. SEO için, URL'de küçük bir kimlik gibi bir şeye sahip olmak İYİDİR, böylece başlık değişirse hala eski bir URL'den gelen kişileri nereye yönlendireceğinizi bilirsiniz. example.com/35/old-and-bustedsadece example.com/35/new-hotnessoldunuz ve uygulama sadece başlığı kontrol edebilir ve kullanıcıyı 301 ile yönlendirebilir.
Xeoncross

9
Bir GUID'yi endekslemek pahalı ve yavaştır, bu da onları birincil anahtarlar için gerçekten zayıf aday yapar.
Matthew James Davis

14

@Matt Sheppard:

Diyelim ki bir müşteri tablonuz var. Elbette bir müşterinin masada birden fazla var olmasını istemezsiniz veya satış ve lojistik departmanlarınızda çok fazla karışıklık olur (özellikle müşteri hakkındaki birden çok satır farklı bilgiler içeriyorsa).

Böylece, müşteriyi benzersiz bir şekilde tanımlayan bir müşteri tanımlayıcınız vardır ve tanımlayıcının müşteri tarafından (faturalarda) bilindiğinden emin olursunuz, böylece iletişim kurmaları gerektiğinde müşteri ve müşteri hizmetleri çalışanları ortak bir referansa sahip olurlar. Yinelenen müşteri kaydı olmadığını garanti etmek için, müşteri tanımlayıcısındaki birincil anahtar veya müşteri tanımlayıcı sütunundaki NOT NULL + UNIQUE kısıtlaması aracılığıyla tabloya benzersiz bir kısıtlama eklersiniz.

Daha sonra, bazı nedenlerden dolayı (ki düşünemiyorum), müşteri tablosuna bir GUID sütunu eklemeniz ve bunu birincil anahtar yapmanız istenir. Müşteri tanımlayıcı sütunu artık benzersizlik garantisi olmadan bırakılırsa, GUID'ler her zaman benzersiz olacağından kuruluş genelinde gelecekte sorun olmasını istersiniz.

Bazı "mimar" size söyleyebilir "oh, ama biz uygulama katmanında gerçek müşteri benzersizlik kısıtlama ele !". Sağ. Genel amaçlı programlama dillerine ve (özellikle) orta kademe çerçevelere ilişkin moda her zaman değişir ve genellikle veritabanınızı asla dışarıda bırakmaz. Ve bir noktada mevcut uygulamadan geçmeden veritabanına erişmeniz için çok iyi bir şans var. == Sorun. (Ama neyse ki, siz ve "mimar" çoktan kayboldunuz, bu yüzden karışıklığı temizlemek için orada olmayacaksınız.) Başka bir deyişle: Veritabanında (ve diğer katmanlarda da) açık kısıtlamalar koruyun zaman).

Başka bir deyişle: Tablolara GUID sütunları eklemek için iyi nedenler olabilir, ancak gerçek (== GUID olmayan) bilgilerde tutarlılık konusundaki isteklerinizi düşürme cazibesine kapılmayın .


1
Dinle! SQL karşılaştırma sayfanızı seviyorum btw. Son derece kullanışlı. Kaçırdığım tek şey bir değişim günlüğü.
Henrik Gustafsson

3
Bu cevabın açıklığa kavuşturulması gerektiğini düşünüyorum: UUID'lerin hiçbir zaman birincil anahtar olarak kullanılmadığını varsayar. Bu varsayımın nereden geldiğini bilmiyorum, ancak henüz bu şekilde kullanmanıza izin vermeyen bir sistem görmedim. Eski bir cevap olduğunu biliyorum, dağıtılmış sistemlerde UUID kullanmanın avantajlarının o zamanlar kadar geniş bir şekilde anlaşılmadığını düşünüyorum.
tne

12

Neden kimse performanstan bahsetmiyor? Birden fazla birleşiminiz olduğunda, hepsi bu kötü GUID'lere dayanarak performans zeminden geçecek :(


1
Bu konuda ben UUID (veya benzeri) tanıtmak gerekir durumda olduğu gibi ayrıntılı, ancak birincil Anahtar olarak kullanmak konusunda endişe miyim.
JoeTidee

1
UUID'ler tamsayıların sadece 4 katı büyüklüğündedir ... (veritabanınızda UUID türü varsa)
Jasen

11

GUID'ler, "tek değişkenler" olarak kullanıldıklarında ileride çok fazla soruna neden olabilir ve yinelenen verilerin tablolarınıza girmesine izin verebilir. GUID'leri kullanmak istiyorsanız, lütfen diğer sütun (lar) da UNIQUE kısıtlamalarını korumayı düşünün.


11
Bu sorunun kalbidir: Bir GUID tanıtmak herhangi bir satırı benzersiz kılar. Ancak sıraların yapay olmayan kısımları aniden kopyalar içerebilir (gerçeğin çeşitli versiyonları).
Troels Arvin

8
Telafi etmek için +1. Ne demek istediğini anlıyorum, ama kötü ifade edildi.
Stefano Borini

11

Başlıca avantajları, veritabanına bağlanmadan benzersiz kimlikler oluşturabilmenizdir. Ayrıca kimlikler global olarak benzersizdir, böylece farklı veritabanlarındaki verileri kolayca birleştirebilirsiniz. Bunlar küçük avantajlar gibi gözüküyor ama geçmişte çok fazla iş tasarrufu sağladım.

Ana dezavantajlar biraz daha fazla depolama alanına ihtiyaç duyuyor (modern sistemlerde sorun değil) ve kimlikler gerçekten insan tarafından okunamıyor. Hata ayıklama sırasında bu bir sorun olabilir.

Dizin parçalanması gibi bazı performans sorunları vardır. Ancak bunlar kolayca çözülebilir (jimmy nillson tarafından tarak kılavuzları: http://www.informit.com/articles/article.aspx?p=25862 )

Düzenle , bu soruya verdiğim iki yanıtı birleştirdi

@Matt Sheppard Sanırım farklı GUID'leri olan satırları birincil anahtar olarak çoğaltabileceğiniz anlamına geliyor. Bu, yalnızca GUID'lerle değil, her türlü vekil anahtarla ilgili bir sorundur. Ve dediği gibi, anahtar olmayan sütunlara anlamlı benzersiz kısıtlamalar ekleyerek kolayca çözülebilir. Alternatif doğal anahtar kullanmak ve gerçek sorunları var ..


Tarak kılavuzları ve indeksleme (INSERT performans) sorununun çözülmesine yardımcı olanları biliyorum. " ana dezavantajlar biraz daha fazla depolama alanına ihtiyaç duyuyor " Bu, büyük veritabanı dosya boyutu nedeniyle performansa çarpacak mı?
Amit Joshi

8

Bu sütunu kümelenmiş bir dizin olarak da (nispeten yaygın bir uygulama) kullanıyorsanız, GUIDS'i birincil anahtarlar olarak kullanmayla ilgili düşünülmesi gereken bir diğer küçük sorun. Bir kılavuzun doğası zaten sıralı olarak başlamaması nedeniyle insertte bir vuruş yapacaksınız, böylece eklediğinizde sayfa bölünmeleri vb. Sistemin yüksek IO'ya sahip olup olmayacağı düşünülecek bir şey ...


6

Birincil-anahtarlar-kimlikleri-versus-Guıd'lerinin

Birincil Anahtar Olarak GUID'lerin Maliyeti (SQL Server 2000)

Efsaneler, GUID ve Otomatik Etkileşim (MySQL 5)

Bu gerçekten istediğin şey.

UID Artıları

  • Her masada, her veritabanında, her sunucuda benzersiz
  • Farklı veritabanlarındaki kayıtların kolayca birleştirilmesini sağlar
  • Veritabanlarının birden çok sunucu arasında kolay dağıtımını sağlar
  • Veritabanına gidiş yapmak yerine herhangi bir yerde kimlik oluşturabilirsiniz
  • Çoğu çoğaltma senaryosu yine de GUID sütunları gerektirir

GUID Eksileri

  • Geleneksel 4 baytlık indeks değerinden 4 kat daha büyüktür; dikkatli olmazsanız bunun ciddi performans ve depolama sonuçları olabilir
  • Hata ayıklamak hantal (burada kullanıcı kimliği = '{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • Oluşturulan GUID'ler en iyi performans (örneğin, SQL 2005'te newsequentialid ()) ve kümelenmiş dizinlerin kullanımını etkinleştirmek için kısmen sıralı olmalıdır

1

Gerçekte ele alınmayan bir şey var, yani birincil anahtarlar olarak rastgele (UUIDv4) kimlikleri kullanmak birincil anahtar dizininin performansına zarar verecektir . Tablonuz anahtar etrafında kümelenmiş olsun veya olmasın gerçekleşecektir.

RDBM'ler genellikle birincil anahtarların benzersizliğini sağlar ve büyük bir dallanma faktörüne (bir ikili arama ağacının dallanma faktörüne 2 sahiptir) sahip bir arama ağacı olan BTree adlı yapıda bir anahtarla arama yapılmasını sağlar. Şimdi, sıralı bir tamsayı kimliği eklerin yalnızca bir tane olmasına neden olur ağacın tarafında ve yaprak düğümlerinin çoğuna dokunulmamasına neden olacaktır. Rastgele UUID'lerin eklenmesi, eklemelerin yaprak düğümlerini dizinin her tarafına bölmesine neden olur.

Aynı şekilde, saklanan veriler çoğunlukla geçiciyse, genellikle en son verilere erişilmesi ve bunlara karşı birleştirilmesi gerekir. Rastgele UUID'lerde kalıplar bundan faydalanmayacak ve daha fazla dizin satırına çarpacak, böylece bellekte daha fazla dizin sayfası gerekiyor. En son verilere en çok ihtiyaç duyulursa sıralı kimliklerde, sıcak dizin sayfaları daha az RAM gerektirir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.