Birincil anahtarlarınızı nasıl buldunuz? [kapalı]


89

Ekibimdeki oldukça hareketli bir tartışmada, çoğu insanın birincil anahtar olarak neyi sevdiğini düşünmek zorunda kaldım. Şu gruplarımız vardı:

  1. Hangi otomatik artırmanın yeterince iyi birincil anahtar olduğu Int / BigInt.
  2. Birincil anahtarı oluşturan en az 3 sütun olmalıdır.
  3. Kimlik, GUID ve insan tarafından okunabilir satır tanımlayıcılarının tümü farklı şekilde ele alınmalıdır.

PK'ler için en iyi yaklaşım nedir? Fikrini haklı çıkarırsan harika olur. Yukarıdakinden daha iyi bir yaklaşım var mı?

DÜZENLEME: İyi ölçeklenen satırlar için insan tarafından okunabilir tanımlayıcılar oluşturmak için basit bir örneği / algoritması olan var mı?


1
Bu öznel olduğu için bir topluluk wiki'si olmalıdır
John Sheehan

2
"Birincil anahtarı oluşturan en az 3 sütun olmalıdır"? Ne anlama geliyor? Daha fazla tanım verebilir misiniz? Yoksa bu # 3'ün bir parçası mı?
S.Lott

@ S.Lott PK(NEWID(),NEWID(),NEWID());-)

@pst: Bu neden bir gerekliliktir? PK'de neden üç sütun olmalı? Neden bir veya dört?
S.Lott

Üç sütunlu bir PK görebiliyordum ... LocalID (Otomatik artış int), GlobalID (GUID), ForeignId (RolesType gibi yabancı anahtar), vb. LocalID + ForiegnId bir bileşik anahtar kombinasyonu olabilir. Kılavuz, diğer web siteleri / hizmetler için kullanılır. Şahsen bunu yapmazdım, sadece Guid + ForiegnId kullanırdım.
Jerad

Yanıtlar:


78

Ara sıra bağlanan uygulamalarla veritabanları arasında herhangi bir senkronizasyon yapacaksanız, birincil anahtarlarınız için GUID'leri kullanıyor olmalısınız. Bu, hata ayıklama için bir tür acıdır, bu yüzden bu durum dışında, bu otomatik artışa bağlı kalmaya meyilliyim.

Autoincrement int varsayılan olmalı ve değil bunları kullanarak haklı olmalıdır.


3
Bir GUID gerekli değildir, yalnızca adımı 10 veya 20 olarak değiştirin veya gelecekte muhtemelen senkronize etmeniz gereken birçok sunucunun olması gerekir.
Robert C. Barth

44
Zamanın en az% 90'ında, bir GUID'e ihtiyaç duyulmaz ve alan israf eder.
Jonathan Leffler

8
GUID'lerin abartılı olduğunu cidden düşünüyorum. Henüz birincil anahtarlarım olarak GUID'lere sahip olma ihtiyacım olmadı.
Cyril Gupta

7
Veya, GUID ile alanı boşa harcamak ve çarpışma riskini almak yerine, orijinal birincil anahtarın birleşik bir anahtarını ve küçük tanımlayıcının her bir senkronizasyon kaynağı için farklı olduğu küçük bir tanımlayıcı oluşturun.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

5
ISO ülke veya dil kodları gibi herkese açık tanımlayıcılar mevcut olduğunda bile her şey için GUID'ler için çalıştığım bir mağaza. Ve bir boolean veya CHAR(1)yeterli olduğunda bile, için olduğu gibi sex. Söylemeye gerek yok, birlikte çalışmak bir kabustu.
Lumi

56

Gerçekten temel noktaya (benim gördüğüm gibi) işaret eden bir cevap görmüyorum - yani, aynı gerçek dünya varlığı için tabloda iki giriş almayacağınızı garanti eden bir birincil anahtar veritabanında modellenmiştir). Bu gözlem, birincil anahtar için neyin iyi neyin kötü seçim olduğunu belirlemeye yardımcı olur.

Örneğin, (ABD) eyalet adları ve kodlarının bir tablosunda, ad veya kod birincil anahtar olabilir - bunlar iki farklı aday anahtar oluşturur ve bunlardan biri (normalde daha kısa olan - kod), birincil anahtar. İşlevsel bağımlılıklar teorisinde (ve bağımlılıkları birleştirmek - 1NF'den 5NF'ye - birincil anahtar olmaktan çok önemli olan aday anahtarlardır.

Bir karşı örnek için, insan adları genellikle birincil anahtar için kötü bir seçim yapar. "John Smith" veya benzer isimlerle anılan birçok insan var; İkinci isimleri hesaba katarsak bile (unutmayın: herkesin bir tane yoktur - örneğin, bende yok), çoğaltma için pek çok alan vardır. Sonuç olarak, insanlar adları birincil anahtar olarak kullanmazlar. Sosyal Güvenlik Numarası (SSN) veya Çalışan Numarası gibi yapay anahtarlar icat ederler ve bunları kişiyi belirlemek için kullanırlar.

İdeal bir birincil anahtar kısa, benzersiz, akılda kalıcı ve doğaldır. Bu özelliklerin benzersiz olması zorunludur; geri kalanın gerçek dünya verilerinin kısıtlamaları göz önüne alındığında esnemesi gerekir.

Belirli bir tablonun birincil anahtarını belirlemeye gelince, bu tablonun neyi temsil ettiğine bakmanız gerekir. Tablodaki hangi sütun değerleri kümesi veya kümeleri tablodaki her satırı benzersiz bir şekilde tanımlar? Bunlar aday anahtarlardır. Şimdi, her bir aday anahtar 4 veya 5 sütundan oluşuyorsa, bunların iyi bir birincil anahtar yapmak için fazla beceriksiz olduğuna karar verebilirsiniz (özellikle kısalık nedeniyle). Bu durumlarda, yapay olarak oluşturulmuş bir sayı olan bir vekil anahtar ekleyebilirsiniz. Çoğu zaman (ama her zaman değil), vekil anahtar için basit bir 32 bitlik tam sayı yeterlidir. Daha sonra bu yedek anahtarı birincil anahtar olarak atarsınız.

Bununla birlikte, diğer aday anahtarların (yedek anahtar için de bir aday anahtardır ve seçilen birincil anahtarın) hepsinin benzersiz tanımlayıcı olarak muhafaza edildiğinden emin olmalısınız - normalde bu sütun kümelerine benzersiz bir kısıtlama koyarak.

Bazen insanlar bir satırı neyin benzersiz kıldığını belirlemekte zorlanır, ancak bunu yapacak bir şey olmalıdır, çünkü bir bilgiyi basitçe tekrarlamak onu artık doğru yapmaz. Dikkatli olmazsanız ve aynı bilgileri sakladığını iddia eden iki (veya daha fazla) satır alırsanız ve ardından bilgileri güncellemeniz gerekirse, yalnızca bir satırı güncellemeniz (özellikle imleç kullanıyorsanız) tehlikesi vardır. her satır yerine, bu nedenle satırlar eşzamanlı değildir ve hiç kimse hangi satırın doğru bilgileri içerdiğini bilmez.

Bu, bazı açılardan oldukça katı bir görüş.

Gerektiğinde bir GUID kullanmakla ilgili özel bir sorunum yok, ancak büyük olma eğilimindeler (16-64 baytta olduğu gibi) ve çok sık kullanılıyorlar. Çoğu zaman, mükemmel derecede iyi bir 4 baytlık değer yeterli olacaktır. 4 baytlık bir değerin yeterli olacağı bir GUID kullanmak, disk alanını boşa harcar ve dizin sayfası başına daha az değer olduğundan, verilere dizinlenmiş erişimi bile yavaşlatır, bu nedenle dizin daha derin olur ve daha fazla sayfanın okunması gerekir. bilgi.


10
ABD eyalet adlarına sahip örneğinizle ilgili olarak, ayrı bir vekil anahtar tercih ederim, çünkü kodlar sizin kontrolünüz dışında bir şeydir. Herhangi bir nedenle değişmeleri gerekiyorsa, sorun yaşarsınız.
Dirk Vollmar

1
(devam) Örneğin, Almanya, yeniden birleşmeden sonra 1990'larda 4 basamaklı bir posta kodu sistemini 5 basamaklı bir sistemle değiştirdi.
Dirk Vollmar

@divo: Yapay / yedek anahtarların güçlü bir savunucusuyum, ancak 4 basamaktan 5 basamaklıya kadar posta kodu değişikliğini iyi bir örnek olarak görmüyorum. Posta kodları genellikle hiçbir şeyin anahtarı olarak kullanılmaz. (Bu kodla ilgili bir şey öğrenmek için bir Posta Kodu tablosunu en son ne zaman sorgulamanız gerekti? Hayır, neredeyse yalnızca başka herhangi bir tabloda başvurulmadan bir adresin parçası olarak kullanılıyor. Önerinizin neredeyse aynı olduğunu söyleyebilirim. adreslerin kendileri için vekil anahtarlar.)
ErikE

@Emtucifor: Evet, belki ZIP çok pratik bir örnek değil, ama benim açımdan, eğer vekil anahtarınızın bir kısmı kontrolünüz dışında ise ve herhangi bir nedenle değişirse, başınız belada demektir. Yeni bir sosyal güvenlik numarası planı, yeni bir ISSN planı veya - belki daha gerçekçi - birleştirme sonrasında yeni bir ürün kimliği sistemi oluşturmaya karar veren, büyümelerini ayarlamak için çalışanlarına yeni çalışan numaraları atayan bir şirket düşünün. Bunlar, hepsi sadece kurgusal örnekler, ancak ZIP ile önceki örneğimde gösterildiği gibi, bazen iyi kurulmuş bir sistem değişebilir.
Dirk Vollmar

2
İlk noktanız doğru. Bu kısıtlamanın bir adı var. Buna "varlık bütünlüğü" denir. EI, her kuruluşun benzersiz bir kimliğe sahip olmasını gerektirir. Birincil anahtarlar, otomatik numara kullanılması dışında genellikle bu gereksinimi karşılar. Otomatik numara ile, otomatik numara haricinde aynı olan iki satır elde edebilirsiniz. Bu genellikle varlık bütünlüğünü ihlal eder.
Walter Mitty

26

Bu sadece dini bir mesele çünkü insanlar evrensel bir doğru cevap arıyor. Hem ekibinizin hem de bu SO başlığının çok fazla anlaşmazlık göstermesi, tanımladığınız tüm çözümleri farklı durumlarda kullanmak için iyi nedenler olduğuna dair bir ipucu olmalıdır.

  • Vekil anahtarlar, tablodaki başka hiçbir öznitelik veya öznitelik kümesi satırları benzersiz şekilde tanımlamak için uygun olmadığında kullanışlıdır.
  • Tabloyu daha insan tarafından okunabilir hale getirmek için mümkün olduğunda doğal anahtarlar tercih edilir. Doğal anahtarlar ayrıca bağımlı bir tablodaki yabancı anahtarın bir vekil kimlik yerine gerçek bir değer içermesine izin verir. Örneğin, kaydetmeniz gerektiğinde state(CA, TX, NY) char(2)int yerine doğal bir anahtar da kullanabilirsiniz .
  • Uygun olduğunda bileşik birincil anahtarları kullanın. idTamamen iyi bir bileşik anahtar varken gereksiz yere " " yedek anahtar eklemeyin (bu özellikle çoktan çoğa tablolarda geçerlidir). Her tablodaki üç sütunlu bir anahtarın emri mutlak saçmadır.
  • GUID'ler, birden çok sitede benzersizliği korumanız gerektiğinde bir çözümdür. Ayrıca, birincil anahtardaki değerlerin benzersiz olmasına, ancak sıralı veya ardışık olmamasına ihtiyacınız varsa kullanışlıdırlar.
  • INT ve BIGINT: Bir tablonun birincil anahtarlar için 64 bitlik bir aralık gerektirmesi yaygın değildir , ancak 64 bit donanımın artan kullanılabilirliği ile bir yük olmamalı ve taşmayacağınız konusunda daha fazla güvence sağlar. INT elbette daha küçüktür, bu nedenle alan önemliyse küçük bir avantaj sağlayabilir.

8
Bir insanın yapabileceği kadar katılmıyorum. Doğal anahtarlar korkunç. Ya verileri değiştirmek isterse? Oh, yapamazsın. Bileşik doğal anahtarlar üzerine birleşimler yazmak bir acıdır. Bu bileşik anahtarı ilgili tüm tablolarınıza taşımak bir israftır.
Robert C. Barth

2
@Robert: "ON UPDATE CASCADE" hakkında bilgi edinin. Ama dediğinizi anlıyorum ve çoğu zaman bir vekil anahtar kullanmanın en iyisi olduğuna katılıyorum, çünkü özellikler değişebilir ve benzersiz olmayabilir.
Bill Karwin

2
Birincil anahtarlar değişmez olmalıdır. Basamaklı güncellemeler, bu durumda kötü bir tasarım kararı için yalnızca çirkin bir hack'tir. Doğal tuşlar ASLA tercih edilmez. Kendilerini veba gibi yayılan bileşik anahtarlarla aynı. 3 aydan fazla veritabanı geliştirme deneyimi olan herkes bunu bilir.
FDCastel

7
@FD: Kesin ifadenize katılmıyorum ve 1992'den beri SQL veritabanları ile geliştirme yapıyorum. Ancak vekil anahtarların en iyi değişmez kalabildiği kesinlikle doğru.
Bill Karwin

20

Bu tür bilgilerin kaynağı olarak The Database Programmer blogunu seviyorum .

Bir birincil anahtar için 3 sütun mu? İş kurallarının gerektirdiği şekilde sütunların uygun benzersiz kısıtlamalara sahip olması gerektiğini söyleyebilirim, ancak yine de ayrı bir vekil anahtarım olacak. Bileşik anahtarlar, iş mantığının anahtara girdiği anlamına gelir. Mantık değişirse, tüm şemanız mahvolur.


2
Bağlantılarını değiştirdiler, işte güncellenmiş yer imi: database-programmer.blogspot.com/2008/09/…
Bryan Rehbein

Sadece böyle bir proje miras kaldı. Ve yapmak istedikleri ilk şey şemayı alt üst etti. Vekil Anahtarlar FTW. DB FTL'nizde İş Mantığı.
Jason


11

Biraz konu dışı, ama konuşmaya mecbur hissediyorum ...

Birincil anahtar bir GUID ise, yok bir hale kümelenmiş dizin . GUID'ler sıralı olmadığından, neredeyse her ekleme sırasında veriler diskte yeniden düzenlenecektir. (Yuck.) GUID'leri birincil anahtar olarak kullanıyorsanız, bunların kümelenmemiş dizinler olması gerekir.


1
Çok iyi bir nokta - bir birincil anahtarın MANTIK kavramı (bunun için bir KILAVUZ kullanmak için geçerli olabilir, özellikle çoğaltma söz konusuysa) ile Kümeleme anahtarının FİZİKSEL kavramı arasında ayrım yapmak gerekir - bu ASLA bir KILAVUZ olmamalıdır. aşırı indeks parçalanmasına yol açar
marc_s

3
Aslında bu doğru değil. Veriler, GUID'nin rasgele doğası göz önüne alındığında, tablonun herhangi bir yerinde olabilir. Yer olmaması durumunda, bir sayfa bölünmesi olacaktır, ancak kesinlikle "her ekleme sırasında disk üzerinde yeniden düzenleme" olmayacak, hatta kapanmayacaktır.
Ralph Shillington

@Ralph, haklısın, HER ekleme değil, 20 kat daha fazla performansa neden olacak kadar. sql-server-performance.com/articles/per/…
Portman

SQL Server işlevi newsequentialid (), GUID'lerle dizin parçalanma sorununu çözer (yine de, genel benzersizliğe kesinlikle ihtiyacınız yoksa 24 bayt hala biraz fazladır). Msdn.microsoft.com/en-us/library/ms189786.aspx sayfasına bakın.
ErikE

10

Ben her zaman vekil anahtarla giderim. Bir vekil anahtar (genellikle bir kimlik sütunu, otomatik artış veya GUID), anahtarın verilerin kendisinde bulunmadığı bir anahtardır. Öte yandan doğal anahtar, kendi başına satırı benzersiz bir şekilde tanımlayandır. Hayatta anlatabildiğim kadarıyla, neredeyse hiç yok gerçek doğal anahtar yoktur. Amerika Birleşik Devletleri'ndeki SSN gibi şeyler bile doğal bir anahtar değildir. Bileşik birincil anahtarlar, gerçekleşmeyi bekleyen bir felakettir. Bu verilerin hiçbirini düzenleyemezsiniz (bu, herhangi bir doğal anahtarın en büyük dezavantajıdır, bileşik olsun ya da olmasın), ancak daha da kötüsü, bir bileşik anahtarla, şimdi bu anahtar verileri her ilgili tabloya devam ettirmeniz gerekir. Ne kadar büyük bir israf.

Şimdi, vekil anahtar seçimi için kimlik sütunlarına bağlı kaldım (çoğunlukla MS SQL Server'da çalışıyorum). GUID en çok büyük olan ve Microsoft önerir Against bir olarak PK bunları kullanarak. Birden fazla sunucunuz varsa, yapmanız gereken tek şey 10 veya 20'lik bir artış yapmak veya ne düşünürseniz düşünün, senkronize etmek / genişletmek için ihtiyaç duyacağınız maksimum sunucu sayısını ve yalnızca sonraki her bir sunucudaki her tablo için çekirdeği dahil etmektir. ve asla veri çarpışması yaşamazsınız.

Elbette, artış nedeniyle kimlik sütununu bir BigInt yapıyorum (aksi takdirde uzun [64 bit] olarak bilinir).

Biraz matematik yaparak, artışı 100 yapsanız bile, tablonuzda hala 92,233,720,368,547,758 (> 92 katrilyon) satır olabilir.


9

Bence "Birincil" kelimesinin "Birincil" Anahtar ifadesinde kullanılması gerçek anlamda yanıltıcıdır.

İlk olarak, bir "anahtar" ın tablo içinde benzersiz olması gereken bir öznitelik veya öznitelikler kümesi olduğu tanımını kullanın,

Daha sonra, herhangi bir anahtara sahip olmak, çoğu kez karşılıklı olarak tutarsız birkaç amaca hizmet eder.

  1. Bu üst tabloyla ilişkisi olan alt tablolardaki bir veya daha fazla kayıtla birleşim koşullarını kullanmak için. (Bu alt tablolarda bir Yabancı Anahtarı açıkça veya örtük olarak tanımlama)
  2. (ilgili) Alt kayıtların üst sekmede bir üst kayda sahip olması gerektiğinden emin olmak; e (Alt tablo FK, üst tabloda Anahtar olarak bulunmalıdır)
  3. Tabloda belirli bir kaydı / satırı hızla bulması gereken sorguların performansını artırmak için.

  4. Aynı mantıksal varlığı temsil eden yinelenen satırların tabloya eklenmesini önleyerek veri tutarlılığını sağlamak. (Bu genellikle "doğal" anahtar olarak adlandırılır ve nispeten değişmeyen tablo (varlık) özniteliklerinden oluşmalıdır.)

Açıkçası, anlamlı olmayan, doğal olmayan herhangi bir anahtar (bir GUID veya otomatik olarak oluşturulmuş bir tam sayı gibi, # 4'ü tatmin etmekten tamamen yoksundur.

Ancak, çoğu (çoğu) tabloda, 4 numarayı sağlayabilen tamamen doğal bir anahtar, genellikle birden fazla öznitelikten oluşur ve aşırı geniş ya da 1, 2 veya 3 numaralı amaçlar için kullanılması kabul edilemez performans sonuçları.

Cevap basit. İkisini de kullan. Diğer alt tablolardaki tüm Birleştirmeler ve FK'ler için basit bir otomatik Oluşturma integral anahtarı kullanın, ancak veri tutarlılığı gerektiren her tablonun (çok az tablo yoktur) tutarsız veri satırlarının eklenmesini önleyecek alternatif bir doğal benzersiz anahtara sahip olduğundan emin olun. .. Artı, her zaman her ikisine de sahipseniz, o zaman doğal bir anahtar kullanımına karşı tüm itirazlar (ya değişirse? FK olarak anılan her yeri değiştirmem gerekiyor), çünkü bunun için kullanmıyorsunuz. .. Tutarsız yinelenen verileri önlemek için, onu yalnızca PK olduğu tek tabloda kullanıyorsunuz ...

GUID'lere gelince, onları kullanırken çok dikkatli olun, çünkü bir dizindeki kılavuzları kullanmak dizin parçalanmasını hızlandırabilir. Bunları oluşturmak için kullanılan en yaygın algoritmalar, kılavuzun "rastgele" bölümünü en önemli bit konumlarına koyar ... Bu, yeni satırlar eklendikçe düzenli dizin birleştirme / yeniden dizinleme gereksinimini artırır.


SQL Server işlevi newsequentialid (), GUID'lerin dizin parçalama sorununu çözer (yine de, genel benzersizliğe kesinlikle ihtiyacınız yoksa 24 bayt hala biraz fazladır). Msdn.microsoft.com/en-us/library/ms189786.aspx sayfasına bakın.
ErikE

oops, 16 bayt demek istemiştim.
ErikE

8

Asla yapmamanız gereken bir şey akıllı anahtar kullanmaktır. Bu, kayıt hakkındaki bilgilerin anahtarın kendisinde kodlandığı bir anahtardır ve sonunda sizi ısırır.

Bir yerde çalıştım; birincil anahtar, harf ve rakamların birleşiminden oluşan hesap kimliği idi. Herhangi bir ayrıntı hatırlamıyorum, ancak örneğin, belirli bir türdeki hesaplar, 600 ile başlayan ve başka bir türdeki hesaplar, 400 ile başlardı. Bu, müşteri her ikisini de istemeye karar verene kadar harikaydı. iş türleri. Veya yaptıkları işin türünü değiştirdiler.

Başka bir yer, ağaçtaki konumu kayıtlar için birincil anahtar olarak kullandı. Yani aşağıdaki gibi kayıtlar olacaktır.

Cat1.subcatA.record1
Cat1.subcatA.record2
Cat1.subcatB.record1
Cat2.subcatA.record1

Tabii ki, müşterilerin istediği ilk şey ağaçtaki öğeleri hareket ettirmenin bir yoluydu. Tüm yazılım seti bundan önce öldü.

Lütfen, lütfen, lütfen, korumam gereken bir kod yazıyorsanız, lütfen akıllı anahtar kullanmayın!


Tüm kalbimle katılıyorum. Smartkeys = aptal.
Robert C. Barth

2
Bu, doğal anahtarların aptal olduğu anlamına gelmez. Ama iyi nokta.

4

Birincil anahtar olarak otomatik artırmanın hayranıyım. Kalbimin derinliklerinde bunun bir kaçış olduğunu biliyorum, ancak verileri eklendiği zamana göre sıralamayı çok kolaylaştırıyor (ID DESC'E GÖRE SİPARİŞ, örneğin).

3 sütun, insanca ayrıştırmak için çok sert geliyor.

Ve bu değiş tokuş - ilişkisel yeteneğin ne kadarına ihtiyacınız var, buna karşılık BU TABLO SAĞ BURADA onu sorgulayan bir insan için anlaşılır hale getirme (saklı yordam veya programatik arayüze karşı).

otomatik artış biz insanlar içindir. :-(


4

Genellikle değişir.

Şahsen ben otomatik artırmayı seviyorum.

Ancak size söyleyebileceğim tek şey, anahtarınız olarak diğer kaynaklardan gelen verilere asla güvenmemektir. Yemin ederim, her yaptığımda beni ısırmak için geri geliyor. Bir daha asla!


3

Birincil anahtarı oluşturan en az 3 sütun olmalıdır.

Ben bunu anlamıyorum

Bir "doğal anahtardan" mı bahsediyorsunuz, örneğin "isim ve doğum tarihi"? Bir doğal anahtar varsa ideal olabilir, ancak doğal anahtar için adayların çoğu ya benzersiz değildir (aynı adı taşıyan birkaç kişi) ya da sabit değildir (birisi adını değiştirebilir).

Hangi otomatik artırmanın yeterince iyi birincil anahtar olduğu Int / BigInt.

Guid'i tercih ederim. Otomatik artırmayla ilgili olası bir sorun, değerin (ör. "Sipariş kimliği") veritabanı örneği (ör. "Satış veritabanı" tarafından) tarafından atanmasıdır. birden fazla veritabanı örneği tarafından oluşturulan verileri birleştirmeniz gerekir (örneğin, her biri kendi veritabanına sahip birkaç satış ofisinden).


Birincil anahtarların benzersiz olması gerekir, ancak sabit olmaları gerekmez. Bu nedenle yabancı anahtarlar "ON UPDATE CASCADE" ile bildirilir. Ancak birincil anahtarların sabit olduğu varsayımı, birçok uygulamayı basitleştirmeye yardımcı olur. Bu, yedek anahtarların bir avantajıdır.
Bill Karwin

3

RE GUID'leri

Bunun gerçekten GERÇEKTEN GERÇEKTEN GERÇEKTEN büyük bir veritabanı, çok fazla yük ve hızlı erişim olup olmayacağına dikkat edin .

100 ila 500 milyon kayıttan oluşan veritabanlarına sahip olduğumuz son işimde, veritabanı görevlilerimiz GUID'lere ve uygun büyüklükte bir ondalık sayıya şiddetle karşı çıktılar. (Oracle altında) bir dize Guid için dahili depolamadaki boyut farkının ondalık bir değere kıyasla aramalarda çok belirgin bir fark yaratacağını hissettiler. (Daha büyük tuşlar = geçmek için daha derin ağaçlar)

GUID'lerin rastgele yapısı, dizin sayfaları için doldurma faktörünü de önemli ölçüde azaltır - bu, yırtılmayı ve disk G / Ç'yi önemli ölçüde artırır.


"Doldurma faktörünü düşürür"? Bunun ne anlama geldiğinden emin değilim, Doldurma faktörü, endeksin oluşturulduğu sırada dizinin yaprak düzeyinde talep edilen boş alan yüzdesi olarak tanımlanan tek seferlik bir anlaşma. GUID değerleri, yaprak seviyesinin genişliği boyunca rastgele doğa dağılımına göre, sağlanan doldurma faktörünün sağladığı boş alana ekler.
Ralph Shillington

1
GUID ne zamandan beri bir dizedir? GUID'ler, herhangi bir saygın DBMS tarafından dahili olarak 16 bayt olarak depolanmalıdır. Onaltılık gösterimde 32 bayt olarak saklamak mantıksız olurdu! (veya
tireli

2

Otomatik artış sütunları. Kodumun SQL Server veya Oracle ile sorunsuz çalışmasını sağlayabiliyorum, biri kimliği kullanarak diğerini DAL'ım aracılığıyla dizileri kullanarak ve daha mutlu olamazdım. Kabul ediyorum, GUID'lerin bazen çoğaltma yapıyorsanız veya verileri daha sonra işlendikten sonra almak için uzağa gönderiyorsanız gerekli olduğunu kabul ediyorum.


2

Her zaman bir vekil anahtar kullandım - 'id' adı verilen otomatik artan bir tamsayı. Başka bir seçenek açık olsa bile bunu yapmak için birçok neden görebiliyorum:

  • Tutarlılık
  • Veriden bağımsız (benzersiz, formattaki değişikliklerle yok edilmeyen)
  • İnsan tarafından okunabilir

... ve şunları yapmamak için mantıklı bir neden yok:

  • Birleşimlerde belirsizlik? - Tabloları takma ad daha iyi bir uygulamadır, IMHO
  • Optimum tablolar? - Giriş başına bir bayt kaldırmak erken optimizasyondur, IMHO
  • Masa başı karar mı? - Artık tutarlı değil
  • Ölçeklendirme sorunları? - Eh? Neden?
  • Hiyerarşik veri yapısı? - Bu, tamamen farklı bir din konusu. Teoride birkaç durumda hayran olduğumu söylemek yeterli, ancak pratikte asla :)

Henüz aklıma gelmeyen veya karşılaşmadığım mantıklı sebepler her zaman memnuniyetle karşılanır ...


1

Bu, klasik bir "duruma bağlıdır". Her proje için tek bir doğru cevap yoktur. Farklı durumlar için farklı şeyleri severim. Bir ORM kullanıp kullanmadığıma ve neyi desteklediğine bağlıdır. Genel mimariye (dağıtılmış veya dağıtılmamış, vb.) Bağlıdır. Sadece işe yarayacağını düşündüğünüz birini seçin ve sekmeler ve boşluklar üzerinde tartışmaya devam edin.


Hala NASIL buna bağlı olduğunu bilmek istiyor; ancak bunların farkında olunarak kişinin kendi seçimine güvenmesi mümkün olabilir ...
Nicholas Leonard

1

Boyuta, bağlanan kişi sayısına ve çoklu veritabanı sunucusu durumu olup olmadığına bağlı olarak 1 veya 3 numaralı seçenekleri kullanma eğilimindeyim.

2. seçenek bana pek mantıklı gelmiyor. Üçünden herhangi biri benzersiz bir kaydı tanımlamak için yeterli değilse, o zaman mümkündür (fazladan işlemlerden geçmeden), iki kaydın üç sütunun hepsinde aynı değerlere sahip iki kaydı olabilir. Üçünün herhangi bir kombinasyonunda benzersizliği zorlamak istiyorsanız, o zaman onlar için bir dizin ekleyin.


1

Yalnızca otomatik artış int veya GUID kullanıyorum. Otomatik artışlı int kullandığım zamanın% 99'u. Veritabanlarını ilk öğrendiğimde ve onları kullanmamam için hiçbir nedenle karşılaşmadığımda (bir GUID'in neden daha iyi olacağının nedenlerini bilmeme rağmen) tam da bana bunu öğretmiştim.

Okunabilirliğe yardımcı olduğu için otomatik artışları severim. Örneğin, "129383 kaydına bir bak" diyebilirim ve birinin girip bulması oldukça kolaydır. Bir GUID ile yapılması neredeyse imkansızdır.


2
Neden öyle diyorsun? Görünüşe göre birçok kişi otomatik artış tamsayı kullanıyor. İhtiyacınız olan şey için işe yarıyorsa ve işe yarıyorsa o kadar da kötü olamaz.
dtc

1

Temel bir tanımsal cevabı geçtikten sonra, neyin iyi bir birincil anahtarı teşkil ettiği büyük ölçüde dine ve kırılma odası argümanlarına bırakılır. Her zaman benzersiz bir şekilde tek bir satıra eşlenen bir şeye sahipseniz, birincil anahtar olarak düzgün çalışacaktır. Bu noktadan sonra, başka hususlar da var:

  • Birincil anahtar tanımı aşırı derecede karmaşık değil mi? Bir "en iyi uygulamayı" takip etmek adına gereksiz karmaşıklık getirmekten kaçınıyor mu?
  • Veritabanının işlemesi için daha az ek yük gerektirecek daha iyi bir olası birincil anahtar var mı (örn. INTEGER vs. VARCHAR, vb.)?
  • Birincil anahtarımın benzersizliğinin ve tanımlı değişmezliğinin değişmeyeceğinden KESİNLİKLE emin miyim?

Bu sonuncusu, muhtemelen çoğu insanı GUID'ler veya kendi kendine artan tam sayı sütunları gibi şeyler kullanmaya yönelten şeydir, çünkü adresler, telefon numaraları, adlar / soyadlar vb. Gibi şeylere güvenmek, onu kesmeyin. Aklıma gelen insanlarla ilgili tek değişmeyen SSN'ler, ama o zaman sonsuza dek benzersiz kalanlar hakkında% 100 emin değilim.

Umarım bu biraz netlik katmaya yardımcı olur ...


SSN'lerin benzersiz olmadığı bazı tarihsel durumlar vardır.
Bill Karwin

1

Birincil anahtarlara yaklaşma şeklim (ve en iyisi olduğunu düşünüyorum) "varsayılan" bir yaklaşıma sahip olmaktan kaçınmaktır. Bu, otomatik olarak artan bir tam sayıya tokat atmak ve ona bir gün demek yerine soruna bakıp "her zaman değişmeyecek ve değişmeyecek bir sütun veya sütun grubu var mı?" Cevap evet ise, o zaman bu yaklaşımı benimsiyorum.


Bu, 'yapabildiğiniz zaman otomatik olarak artan tam sayılardan kaçınmanız' anlamına mı geliyor? Anladığım kadarıyla, endüstri uzmanları büyük ölçekli veritabanlarında en iyi performansın minimum imzalı, endeksli, artımlı tek sütunlu PK'lardan geldiğini düşünüyorlardı.
Hardryv

1
Her zaman uzmanların bu iş için en iyi aracı kullandığını düşünmüşümdür
Andrew G. Johnson

1

Hemen hemen her zaman tamsayılar.

Daha küçük / daha hızlı işlemenin yanı sıra başka iyi nedenleri de var. Hangisini yazmayı tercih edersiniz - "404040" veya "3463b5a2-a02b-4fd4-aa0f-1d3c0450026c"?


İkincisi, tire eklenmiş ve 16 tabanında bir tamsayı olabilir. Ancak evet, 404040'ın işlenmesi uzun GUID'den daha hızlıdır. Sonra tekrar, 0'ın işlenmesi daha da hızlıdır çünkü tek bir bit veri gerektirmez!
strager

1

Sadece biraz alakalı, ancak son zamanlarda küçük sınıflandırma tablolarım olduğunda yapmaya başladığım bir şey (esasen koddaki ENUM'ları temsil edenler) birincil anahtarı char (3) veya char (4) yapacağım. Sonra bu birincil anahtarları arama değerinin temsilcisi yapıyorum.

Örneğin, dahili Satış Temsilcilerimiz için bir fiyatlandırma sistemim var. Her teklif satır öğesine aşağıdakilerden birinin atandığı "Maliyet Kategorilerimiz" var ... Bu nedenle, birincil anahtarın "MTL", "SVC", "TRV", "TAX" olduğu "tCostCategories" adlı bir tür arama tablosuna sahibiz, 'ODC'. Arama tablosundaki diğer sütunlar, kodların normal ingilizce anlamları, "Malzeme", "Hizmet", "Seyahat", "Vergiler", "Diğer Doğrudan Maliyetler" gibi daha fazla ayrıntı depolar.

Bu gerçekten güzel çünkü int'ten daha fazla alan kullanmıyor ve kaynak verilere bakarken, değerin ne olduğunu bilmek için arama tablosunu bağlamanız gerekmiyor. Örneğin, bir teklif satırı şöyle görünebilir:

1 Parça Numarası 40 $ MTL
2 Diğer Parça Numarası 29,99 $ SVC
3 Parça Numarası2 150 $ TRV

Kategorileri temsil etmek için bir int kullanmak ve ardından tüm satırlarda 1, 2, 3'ü bağlamak çok daha kolay - veriler tam önünüzde ve performans hiç etkilenmiyor gibi görünüyor gerçekten test edildi.)

Gerçek soruya gelince ... RowGUID benzersiz tanımlayıcılarını seviyorum. Bu konuda% 100 değilim, ancak tüm satırlarda zaten dahili RowGuid yok mu ?? Öyleyse, RowGuid'i kullanmak aslında ints'ten (veya bu konuda başka herhangi bir şeyden) daha az yer kaplar. Tek bildiğim, eğer M $ için GreatPlains'de kullanmak için yeterince iyiyse, benim için yeterince iyi. (Eğilmeli miyim?)


1

GUID kullanmamın bir nedeni daha - hiyerarşik bir veri yapısı kullanıyorum. Yani, Birincil Anahtarların eşleştiği bir 'Şirket' ve bir 'Satıcı' tablom var. Ama aynı zamanda Şirketten 'devralan' bir 'Üretici' tablosuna da sahibim. Satıcılar ve Üreticiler için ortak olan alanlar bu tablolarda görünmez - Şirkette görünürler. Bu kurulumda, int'leri kullanmak Kılavuzlardan çok daha zahmetlidir. En azından, kimlik birincil anahtarlarını kullanamazsınız.


1
Evet yapabilirsiniz, sadece alt tip tablolarının kimlik özelliğine sahip olmasını sağlamazsınız, bunun yerine süper tip tablo değerinin açık eklerini alırlar. Lütfen stackoverflow.com/questions/2112882/…
adresini ziyaret edin

1

Onlara ne zaman güvenebilirsem, doğal anahtarları severim. Konunun uzmanlarına anlamlı gelen anahtarları kullanmak için küçük bir performans fiyatı ödemeye hazırım.

Varlıkları tanımlayan tablolar için, kişilerin yaptığı gibi tek tek örnekleri tanımlayan basit bir doğal anahtar olmalıdır. Konu varlıklardan biri için güvenilir tanımlayıcılara sahip değilse, o zaman bir vekil anahtara başvururum.

İlişkileri açıklayan tablolar için, her bileşenin ilişkiye katılan bir varlığa ve dolayısıyla bir varlık tablosundaki bir satıra başvurduğu bir bileşik anahtar kullanıyorum. Yine, bir bileşik anahtar kullanmak için performans vuruşu genellikle minimumdur.

Diğerlerinin de belirttiği gibi, "birincil anahtar" terimi biraz yanıltıcıdır. İlişkisel Veri Modelinde kullanılan terim "aday anahtarlar" dır. Tek bir tablo için birkaç aday anahtar olabilir. Mantıksal olarak, her biri bir diğeri kadar iyidir. Bunlardan birini "birincil" olarak seçmek ve tüm referansları bu anahtar aracılığıyla yapmak, tasarımcının yapabileceği bir seçimdir.


Lütfen bazı örnek güvenilir doğal anahtarları açıklayın.
ErikE

1
"güvenilir" tek başına bir anahtarın özelliği değildir. Daha ziyade, verileri sağlayan kişiler bağlamında anahtarla ilgisi vardır. Verileri gerçekten yönetecek birine satılmak üzere bir uygulama yazıyorsanız, hangi anahtarların müşteri için güvenilir olup olmayacağını tahmin etmeniz gerekir. Müşterilerin çeşitliliği göz önüne alındığında, müşterilerinizin bir kısmı için neredeyse kesinlikle yanlış tahmin edeceksiniz.
Walter Mitty

Yukarıdakileri söyledikten sonra, işte geçmişte güvendiğimiz bir anahtar örneği. Kurslarla ilgili bir veri tabanımız vardı. Ders kitapları ve kurslarla ilgili diğer kurs materyalleri, programlı kurs teklifleri, kursları öğretmek için nitelikli eğitmenler, kurs önkoşulları, eğitim vb. Kurs geliştirme yeni bir kurs oluşturduğunda, yaptıkları ilk şeylerden biri kurs kodu atamaktı. Ders kodlarının benzersiz olduğundan ve derslerin bir kez atandıktan sonra kodlarını asla değiştirmediğinden emin olmaktan sorumluydular. Bize verilen verilerin bir parçasıydı.
Walter Mitty

Güvenilir doğal anahtara bir başka güzel örnek de VIN'dir (Araç Kimlik Numarası). Son yıllarda, yeni olarak satılan her araca bağlı bir VIN vardır. Benzersiz ve değişmez olduklarına güvenilebilirler.
Walter Mitty

1

Kılavuzlar. Dönem.

Ölçeklendirmeniz gerektiğinde veya birincil anahtarı alternatif bir şekilde atamanız gerektiğinde, bunlar arkadaşınız olacaktır. Diğer her şey için dizin ekleyebilirsiniz.


ifademi netleştirmek için güncelleyin.

Pek çok farklı türde site üzerinde çalıştım. Küçük tek sunucu anlaşmalarından birden çok DB ve web sunucusu ile desteklenen büyük tekliflere kadar. Kesinlikle birincil anahtar olarak otomatik artan ints ile iyi olacak uygulamalar vardı. Ancak bunlar işleri nasıl yaptığım modeline uymuyor.

Bir GUID kullanırken kimliği herhangi bir yerde oluşturabilirsiniz. Uzak bir sunucu tarafından, web uygulamanız tarafından, veritabanının içinde veya hatta çoklu yönetici durumunda birden çok veritabanı içinde oluşturulabilir.

Öte yandan, otomatik olarak artırılmış bir INT yalnızca birincil veritabanında güvenli bir şekilde oluşturulabilir. Yine, bu olabilir sen yakından bu bir destek DB sunucuya bağlı ve dışarı ölçekleme sen ilgileniyoruz şey değildir edilecek bir uygulama varsa düzelecek.

Elbette, GUID'lerin kullanımı, her gece yeniden dizin oluşturma işlemlerine sahip olmanız gerektiği anlamına gelir. Ancak, otomatik olarak artırılmış bir INT dışında bir şey kullanıyorsanız, bunu yine de yapmalısınız. Heck, birincil olarak bir INT olsa bile, parçalanmayla başa çıkmak için yeniden oluşturulması gereken başka dizinlere sahip olmanız muhtemeldir. Bu nedenle, GUID'lerin kullanılması tam olarak başka bir sorun getirmez çünkü bu görevlerin ne olursa olsun gerçekleştirilmesi gerekir.

Dışarıdaki daha büyük uygulamalara bir göz atarsanız, önemli bir şey fark edeceksiniz: hepsi anahtar olarak Base64 kodlu GUID'leri kullanıyor. Bunun nedeni basittir, GUID'lerin kullanımı ölçeklendirmenizi sağlar dışarı IntS dışarı ölçekli çalışırken atlamak için çemberler bir sürü olabilir oysa kolayca.

En son uygulamamız, yaklaşık bir ay süren yoğun ekleme döneminden geçiyor. Bundan sonra, sorguların% 90 + 'ı raporlama için seçilir. Kapasiteyi artırmak için, bu büyük ekleme döneminde ek DB sunucuları oluşturabilirim; ve daha sonra bunları raporlama için kolayca tek bir DB'de birleştirin. Bunu INT'lerle yapmaya çalışmak tam bir kabus olurdu.

Açıkçası, bir veritabanını veya kurulum replikasyonunu her kümelediğinizde, DB sunucusu yine de tabloda GUID'lerinizin olmasını isteyecektir. Öyleyse, sisteminizin büyümesi gerektiğini düşünüyorsanız, o zaman iyi olanı seçin.


Dizinlerinizin doldurma faktörünü hiç incelediniz mi? GUID'lerin 'em İsviçre peyniri yapmasının rastgele doğası - etkililiğini önemli ölçüde azaltır.
stephbu

2
"Guids.period": Bu çok yanlış. GUID'ler uygun yerlerde kullanılmalıdır. Diğer yorumcunun da belirttiği gibi, bir programcı olarak hayatı kolaylaştırabilir, ancak DB'nin genel boyutunu ve performansını etkiler.
Mitch Wheat

Günün sonunda, uygulamalarımı birden çok veritabanı sunucusunda sorunsuz şekilde ölçeklendirebiliyorum. Ama sanırım küçük sitelerde çalışıyorsunuz.
NotMe

3
GUID mantıksal birincil anahtar için uygun olabilir , ancak ASLA KÜMELEME anahtarınız olarak bir GUID sütunu kullanmayın - ZAYIF performansa yol açan dizin parçalanmasında boğulacaksınız .....
marc_s

Kesinlikle "Guids.period" demezdim. Bu konuda - aslında 'en iyi uygulamalarla' bu kadar dolu bir sektörde bile bu tür bir ifade sizi varsayılan olarak sallantılı bir zemine sokar (özellikle bu ifadeyle). Bir GUID kadar acı veren herhangi bir şey için bazı katı gerekçeler gerekir ve JL'nin dediği gibi, çoğumuzun bunu son çare olarak düşüneceğini düşünüyorum. Sanki başlığın geri kalanını okumadan yayınlamışsınız gibi.
Hardryv

0

Bu, farkında olsanız da olmasanız da karmaşık bir konudur. Bu StackOverflow SSS bölümünün altına düşebilir.

Burada ne tür sorular sormamalıyım?

Öznel, tartışmacı veya uzun tartışmayı gerektiren sorular sormaktan kaçının. Burası cevaplanabilecek sorular için bir yer!

Bu yıllardır tartışılıyor ve yıllarca tartışılmaya devam edecek. Gördüğüm tek fikir birliği ipucu, bir OO görevlisine (GUID'ler gitmenin tek yolu!), Bir veri modelleyicisine (gitmenin tek yolu doğal tuşlar!) veya performans odaklı bir DBA (INT'ler gitmenin tek yoludur!).


Tartışmanın uzun sürmesine izin vermeyeceğim. Genel fikir birliğini görmek için merak ettim.
Perpetualcoder

1
İstediğin soruyu sor derim! Aksi takdirde, bu topluluk statik hale gelecek ve Wikipedia gibi göründüğü gibi aşırı kontrol altına alınacaktır. Bana bazı zamanlar insanların ne sormayı seçtiklerini sormalarına izin vermen gerektiği gibi geliyor. Onlara güvenin, kendilerine güvenmeye başlayabilirler!
Nicholas Leonard
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.