Guid vs INT - Birincil anahtar olarak hangisi daha iyi?


97

Ben nedenlerle kullanmayı etrafında okuma veya olmasın olmak ettik Guidve int.

intdaha küçük, daha hızlı, hatırlaması kolay, kronolojik bir diziyi tutar. Ve Guidgelince, bulduğum tek avantaj benzersiz olmasıdır. Hangi durumda bir Guiddaha iyi intve neden olurdu ?

Gördüğüm kadarıyla, intçoğu durumda alakasız olan sayı sınırı dışında hiçbir kusur yok.

Tam olarak neden Guidyaratıldı? Aslında basit bir masanın birincil anahtarı olarak hizmet etmekten başka bir amacı olduğunu düşünüyorum. (Herhangi bir Guidşey için kullanarak gerçek bir uygulama örneği ?)

SQL Server'da (Guid = UniqueIdentifier) ​​türü


1
Birincil anahtardan ziyade , vekil anahtar yani doğal anahtar olmayan bir anahtar (yani gerçek dünyada kullandığımız anahtar) demek istediğinizi düşünüyorum . Muhtemelen kümelenmiş indeksi kastediyorsunuz.
birgün,

Ayrıca (Birincil) KEY ve INDEX arasındaki farkı da unutmayın.
Allan S. Hansen


2
" intsayıların haricinde, çoğu durumda alakasız olan bir kusur yoktur.": aslında, INT - GUID bağlamında, imzalı bir üst limitin, 32-bit INTimzalı üst limitin göz önüne alındığında tamamen alakasız olduğu , 64-bit BIGINTneredeyse tüm kullanımların ötesindedir (alt sınırda numaralandırmaya başlarsanız daha INTda iyidir ; aynı şey geçerlidir ) ve hala bir GUID'in (16 yerine 8 bayt) boyutunun yarısı kadardır ve sıralıdır.
Solomon Rutzky

Yanıtlar:


89

Bu, burada ve burada Stack Overflow'ta istendi .

Jeff'in gönderisi GUID kullanmanın artılarını ve eksilerini açıklıyor.

GUID Artıları

  • Her masada, her veritabanında ve her sunucuda benzersiz
  • Farklı veritabanlarından kayıtların kolayca birleştirilmesini sağlar
  • Birden fazla sunucu arasında veritabanlarının kolay dağıtımına izin verir
  • Veritabanına gidiş dönüş yapmak yerine, istediğiniz yerde kimlikler oluşturabilirsiniz.
  • Çoğaltma senaryolarının çoğu yine de GUID sütunu gerektirir

GUID Eksileri

  • Geleneksel 4-byte endeks değerinden 4 kat daha büyüktür; Dikkatli olmazsanız, bunun ciddi performans ve depolama etkileri olabilir
  • Hata ayıklamak için hantal ( where userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • Oluşturulan GUID'ler, en iyi performans için (örneğin, newsequentialid()SQL Server 2005+ sürümünde) ve kümelenmiş indekslerin kullanılmasını sağlamak için kısmen sıralı olmalıdır

Performans konusunda eminseniz ve kayıtları çoğaltmayı veya birleştirmeyi planlamıyorsanız, kullanın intve otomatik artışını ayarlayın ( SQL Server'da kimlik çekirdeği ).


20
GUID yaklaşımının bir başka ifadesi, onu son kullanıcınız için bir tanımlayıcı olarak kullanamayacağınızdır. Kullanıcılarınızın size telefonda "BAE7DF4-DDF-3RG-5TY3E3RF456AS10" Siparişi ile ilgili bir sorunlarının olduğunu söylemelerini bekliyor musunuz? :)
Brann

3
Sıralı kılavuzlar kullanmazsanız ve birincil anahtarınız kümelenmişse (SQL Server varsayılan), tüm veri ekleriniz tablo boyunca rastgele dağılır ve verilerinizin büyük parçalanmasına neden olur. Bu, verilerin normalde kronolojik gibi bir düzende ekleneceğini varsayar.
datagod,

6
Sıralı kılavuzlar, yalnızca SQL örneği yeniden başlatılana kadar sıralıdır. O zaman, ilk değer, kök değerin üretilme biçiminden ötürü bir öncekinden daha düşük olacaktır ve her türlü soruna tekrar tekrar neden olacaktır.
mrdenny

20
@Brann İdeal olarak, PK değerlerinizi son kullanıcılara ilk etapta vermeyeceksiniz. Bunu yapmanın biraz yaygın olduğunu biliyorum ve bunu yapmamayı öğrenmeden önce kendimde yaptığım bir şeydi. Ancak yapılmaması gerektiğinden, INT'yi GUID yerine tercih etmenin belirli bir nedeni geçerli değil.
Solomon Rutzky

2
Seçimi @ChadKuehn UNIQUEIDENTIFIERüzerinde INTçünkü INT, bir değil yeterince gerçek iken bir üst sınırı vardır, sınırsız varlık beri oldukça zayıf muhakeme olan pratik yarar. INTBir'in etkin kapasitesini , 1 yerine alt sınırda (-2.14 milyar) başlayarak kolayca iki katına çıkarabilirsiniz. Veya, eğer tam 4.3 milyar yeterli değilse, o zaman BIGINThala sadece 8 bayt olan GUID için 16 ile karşılaştırıldı ve sıralı.
Solomon Rutzky

18

Verilerinizi harici bir kaynakla senkronize ediyorsanız, kalıcı bir GUID çok daha iyi olabilir. Bir GUID kullandığımız yere hızlı bir örnek, müşterilerini ağlarını taramak ve belirli otomatik keşif sınıfları yapmak, bulunan kayıtları saklamak ve ardından tüm müşteri kayıtlarının merkezi bir veritabanına entegre edilmesi için gönderilen bir araçtır. geri döndük. Bir tamsayı kullanırsak, 7,398 "1" değerine sahip olurduk ve hangisinin "1" olduğunu takip etmek çok daha zor olurdu.


3
GUID'ler kesinlikle dış tanımlayıcılar olarak iyidir ve kümelenmemiş bir dizini "dış anahtar" olarak tutacağım. Yine de, kümelenmiş dizin ve yabancı anahtar ilişkilerinin temeli olan "iç anahtar" olarak bir int tutacağım. Bir şey bir mimari sınırı geçecekse (örneğin, başka bir uygulamayla iletişim kurma), karıştırılamayan bir şeyin olmasını takdir ediyorum.
Greg,

15

Başarı ile melez bir yaklaşım kullandım. Tablolar BOTH bir otomatik artan birincil anahtar tamsayı idsütunu VE bir guidsütun içerir. guidBenzersiz global olarak satırı tanımlamak için gerekli ve olarak kullanılabilir idsıralama ve sıranın insan tanımlama, sorgular için kullanılabilir.


3
idZaten insanlar bir satırı tanımlamak için yeterliyse , GUID hangi değeri veriyor ?
Martin Smith,

6
Kimlik, bu tablodaki satırı tanımlar. GUID (en azından teoride) bu sırayı bilinen evrendeki herhangi bir yerde tanımlar. Projemde, Android cep telefonlarının her biri, yerel bir SQLite veritabanındaki tablonun yapısal olarak özdeş bir kopyasına sahip. Satır ve GUID'leri Android'de üretilir. Ardından, Android arka uç veritabanına senkronize edildiğinde, yerel satır diğer Android cep telefonlarından oluşturulan satırlarla çakışma korkusu olmadan arka uç masaya yazılır.
rmirabelle

2
@ MartinSmith Bu yaklaşımı kendim kullandım ve oldukça iyi çalışıyor. GUID, yalnızca Notlandırılmamış bir dizine sahip alternatif bir anahtardır ve uygulamadan iletilir, ancak yalnızca birincil tabloda bulunur. İlgili tüm tablolar INTPK ile ilgilidir. Her iki dünyanın da en iyisi olduğu için, bu yaklaşımın çok daha yaygın olmadığını garip buluyorum. Görünüşe göre çoğu insan problemleri çok mutlakçı terimlerle çözmeyi tercih ediyor gibi görünüyor; uygulamanın hala global benzersizlik ve / veya taşınabilirlik için GUID'leri kullanması için PK'nın bir GUID olması gerekmediğinin farkında değil.
Solomon Rutzky

1
@ rmirabelle Bu yaklaşımı düşündüm ve tereddüt ettim, ama cevabınız beni ikna etti. Temel olarak, bir iş öğesi için benzersiz bir tanımlayıcıya ihtiyaç duyduğum bir durumdayım (herhangi bir yerden ağ üzerinden gelebilir), ancak önce veritabanına gitmek istemiyorum. GUID'ler bunun için iyi bir çözüm ama sıralı kümelenmiş bir anahtarım yoksa JOIN'lerin daha yavaş olacağını tahmin ediyorum.
kolay

1
@easuter PK ile ilgili iki FK'nin bir birleşimini oluşturması gereken çoktan çoğa "köprü" tablolarında olduğu gibi "sadece bunun için" kimlik alanları eklememeyi kabul ediyorum. Fakat burada bir takas değil çünkü kimlik alanı sadece onun için değil. Sistemin verimli çalışmasına izin vermek oldukça önemlidir ;-). Guıd dıştan, o değil üretildiğinden, VE, ben senin durumunda iddia ediyorum garantili pragmatik olduklarını bile birbirinden farklı. Ancak veri bütünlüğünün sorumluluğu
GUID'in

1

En iyi uygulamalardan bazıları, kullanacağınız tüm değer kümesini mümkün olan en az bellekle barındıran bir veri türü kullanmanız gerektiğini belirtiyor. Örneğin, küçük bir işletmede işveren sayısını saklamak için kullanıyorsanız ve 100'e ulaşmanız pek mümkün değilse, int (hatta smallint) de olsa, hiç kimse bigint değeri kullanmayı önermez.

Tabii ki, bunun dezavantajı "Ölçeklenebilirliğe hayır demek!" Gibidir.


Ayrıca, bunun tamamen ilişkili olmadığını biliyorum, ancak bununla ilgili başka bir faktör var. İstisnai değilken, mantıklı olması durumunda genellikle otomatik olarak üretilmemiş bir birincil anahtar kullanmanızı öneririm. Örneğin, sürücü bilgilerini kaydediyorsanız, "Kimlik" için yeni bir otomatik oluşturulmuş sütun oluştururken zahmet etmeyin, yalnızca lisans numarasını kullanın.

Bunun kulağa çok açık geldiğini biliyorum ama bunun çok sık unutulduğunu görüyorum.

Bağlam için: cevabın bu kısmı, PK'nızın bir kayıt için benzersiz veri tanımlayıcısı olmasını istediğiniz veri teorik bir yaklaşımdan ele alındı. Çoğu zaman zaten var olduklarında bunları yaratırız, bu nedenle önceki cevap.

Bununla birlikte, bu veri noktaları üzerinde sıkı bir kontrol sahibi olmanız çok nadirdir ve bu nedenle düzeltmeler veya ayarlamalar yapmanız gerekebilir. Bunu birincil tuşlarla yapamazsınız (peki, yapabilirsiniz, ama bu bir acı olabilir).

Açıklamalar için @VahiD teşekkür ederiz.


anlamlı birincil anahtarlar kullanılması hiç önerilmez, senaryonun altında düşünün, birisi yanlış lisans numarası girdi ve bu kimliği 3-4 tabloda yabancı anahtar olarak kullandınız, bu hatayı nasıl düzeltirsiniz? basitçe lisans numarasının düzenlenmesi bu durumda yeterli olamazdı.
VahiD

1
Komik: Yorumunuzu okudum ve "evet, elbette" dedim, sonra cevabımı okumak için geri döndüm ve "bunu söyledim mi" diye düşündüm? Birkaç yılda işler nasıl değişiyor. Muhtemelen daha teorik bir arka plandan geliyordum, ancak üzerinde sıkı bir kontrol sahibi olmadığınız sürece (nadiren) fazla bir fayda sağlamıyor. Cevabı güncelleyeceğim.
Alpha,

yıllarda gelişme için oy :)
VahiD

1

Otomatik artış kimliklerini kullanmak, işletme faaliyetleriniz hakkında bilgi sızdırabilir. Bir mağaza işletiyorsanız ve order_idbir satın almayı genel olarak tanımlamak için kullanıyorsanız , herkes aylık satış sayınızı basit aritmetik olarak öğrenebilir.


0

GUID'lerin nasıl oluşturulduğuyla ilgili başka bir şey. mrdenny, newsequentialid () kullanılsa bile, örneklerin yeniden başlatılmasının, önceki işlemlerde geride bırakılan "deliklerle" başlamasına neden olduğunu doğruladı. "Sıralı" GUID'leri etkileyen bir başka şey ağ kartıdır. Doğru hatırlıyorsam, NIC'in kullanıcı kimliği GUID algoritmasının bir parçası olarak kullanılır. Bir NIC değiştirilirse, şeylerin sıralı yönünü korumak için UID'nin daha yüksek bir değer olacağının garantisi yoktur. Ayrıca, birden çok NIC'nin algoritmayı kullanarak değerlerin atanmasını nasıl etkileyebileceğinden de emin değilim.

Sadece bir düşünce ve umarım doğru hatırlıyorum. İyi günler!


2
Bobo8734 olan Veritabanı Yöneticilerine hoş geldiniz. Bu yorumlar için bazı kaynaklar bulabilir misiniz? Eğer onlardan emin değilseniz, belki tek bir cevaptan çok bir yorum olarak (daha iyi bir cevabınız varken) sunulabilirler.
LowlyDBA

-6

İkisini de kullan

Kullanım int / Bigint İlköğretim Anahtarı için korumak ve yabancı anahtar ilişkiler gibi kullanımı kolaydır olarak.

Ancak bir sütunu GUID'e bağlayarak her satırın kendine özgü bir sütunu olması


2
Bu önerinin ardındaki nedeninizi açıklamak kimseye zarar vermez, eminim.
Andriy M,

KILAVUZ 36 karakter uzunluğunda belirli bir dava için arama yapmanız zor olacaktır ..
Abdul Hannan Ijaz

1
Pekala, ancak bu OP'nin neden her ikisini de kullanması gerektiğini intve guidcevabınızdakileri önerdiğiniz gibi açıklamıyor . Ayrıca, önerinizi sadece bana açıklamaktan bahsetmiyordum - demek istediğim , cevabınızı güncellemek isteyebilirsiniz . Bu arada, başka bir cevaplayıcının sizin gibi aynısını (az ya da çok) önerdiğini biliyor musunuz ?
Andriy M

Evet, aynı şeyi kastediyordum .. BTW :) harika
Abdul Hannan Ijaz
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.