Tablolardaki birincil anahtarlar için en iyi uygulama nedir?


256

Tablolar tasarlarken, benzersiz ve birincil anahtarı yaptığım bir sütuna sahip olma alışkanlığı geliştirdim. Bu, gereksinimlere bağlı olarak üç şekilde gerçekleştirilir:

  1. Otomatik olarak artan kimlik tamsayı sütunu.
  2. Benzersiz tanımlayıcı (GUID)
  3. Satır tanımlayıcı sütunu olarak kullanılabilen kısa karakter (x) veya tamsayı (veya diğer nispeten küçük sayısal tür) sütun

Sayı 3, oldukça küçük bir arama için kullanılır, çoğunlukla benzersiz bir statik uzunluk dize koduna sahip olabilen tabloları veya bir yıl veya başka bir sayı gibi sayısal bir değeri okuyabilir.

Çoğunlukla, diğer tüm tablolarda otomatik olarak artan bir tamsayı veya benzersiz tanımlayıcı birincil anahtarı bulunur.

Soru :-)

Son zamanlarda tutarlı satır tanımlayıcı olmayan veritabanları ile çalışmaya başladım ve birincil anahtarlar şu anda çeşitli sütunlar arasında kümelenmiş. Bazı örnekler:

  • datetime / karakter
  • tarih saat / tam sayı
  • tarih saat / varchar
  • karakter / nvarchar / nvarchar

Bunun için geçerli bir durum var mı? Bu durumlar için her zaman bir kimlik veya benzersiz tanımlayıcı sütunu tanımlardım.

Buna ek olarak, birincil anahtarlar olmadan birçok tablo var. Bunun için geçerli nedenler nelerdir?

Tabloların neden oldukları gibi tasarlandığını anlamaya çalışıyorum ve bu benim için büyük bir karışıklık gibi görünüyor, ama belki de bunun için iyi nedenler vardı.

Yanıtları deşifre etmeme yardımcı olacak üçüncü bir soru: Bileşik birincil anahtarı oluşturmak için birden çok sütunun kullanıldığı durumlarda, bu yöntemin bir vekil / yapay anahtar yerine belirli bir avantajı var mı? Ben daha çok performans, bakım, yönetim vb.


Veritabanı Becerilerini buldum : Birincil Anahtarları Seçmek İçin İyi Bir Yaklaşım İyi Bir Okumak ve Belirtilen Noktaların çoğunu takip ediyorum.
user2864740

Yanıtlar:


254

Birkaç kurala uyuyorum:

  1. Birincil anahtarlar gerektiği kadar küçük olmalıdır. Sayısal türler karakter biçimlerinden çok daha kompakt bir biçimde saklandığından sayısal bir türü tercih edin. Çünkü birincil anahtarların çoğu başka bir tablodaki yabancı anahtarlar ve birden çok dizinde kullanılır. Anahtarınız ne kadar küçükse, dizin o kadar küçük olur, önbellekteki daha az sayfa kullanırsınız.
  2. Birincil anahtarlar asla değişmemelidir. Birincil anahtarın güncellenmesi her zaman söz konusu olmamalıdır. Bunun nedeni, büyük olasılıkla çoklu dizinlerde kullanılması ve yabancı anahtar olarak kullanılmasıdır. Tek bir birincil anahtarın güncellenmesi değişikliklerin dalgalanma etkisine neden olabilir.
  3. Mantık modeli birincil anahtarınız olarak "sorun birincil anahtarınızı" KULLANMAYIN. Örneğin, pasaport numarası, sosyal güvenlik numarası veya çalışan sözleşme numarası, bu "birincil anahtar" gerçek dünyadaki durumlar için değişebilir.

Yedekte veya doğal anahtarda, yukarıdaki kurallara atıfta bulunuyorum. Doğal anahtar küçükse ve asla değişmeyecekse, birincil anahtar olarak kullanılabilir. Doğal anahtar büyükse veya değişme olasılığı yüksekse yedek anahtarları kullanırım. Birincil anahtar yoksa, yine de bir yedek anahtar yaparım çünkü deneyim, şemanıza her zaman tablo ekleyeceğinizi ve birincil anahtarı yerleştirmenizi dilediğini gösterir.


3
Bunu sevdim! "Kurallarınız" için herhangi bir belgeleriniz var mı? Teşekkürler!
Lloyd Cotten

4
Hayır, sadece deneyim. "Küçük" veritabanları ile uğraşırken bu şeyler çok önemli değil. Ama büyük db ile uğraşırken tüm küçük şeyler önemlidir. Metin veya kılavuzları kullanmaya kıyasla int veya long pk ile 1 milyar satırınız olduğunu düşünün. Çok büyük bir fark var!
Logicalmind

44
Yapay bir anahtar kullandığınızda, bu benzersiz dizini doğal anahtarın üzerine koymayı unutmayın (eğer gerçekte mevcut değilse).
HLGEM

3
@Lloyd Cotten: Büyük bir veri motoru sağlayıcısı, kural 1'i desteklemek için şunları söylüyor: skyfoundry.com/forum/topic/24 . Beni Ints
hobs'a

4
"doğal anahtarın küçük olduğunu ve asla değişmeyeceğini" bilseniz bile, iki kez düşünün. "Biz asla bu kodları yeniden kullanmak" ünlü son sözler .... Küçük, asla değişen kategorilere giren tek şey hakkında iso ve diğer standartlar (ülke kodları, iata havaalanı kodları). "Bu iç marka için 2 harfli temsil nedir" gibi şeyler ... "" o "asla değişmeyecek varsayalım önce iki kez düşünün, bir veritabanı yeniden oluşturma uzakta bir finans karar.
Andrew Hill

90

Doğal ayetler yapay anahtarlar veritabanı topluluğu arasında bir tür dini tartışmadır - bu makaleye ve bağlantı verdiği diğerlerine bakın . Ben lehine ne olduğum zaman sahip yapay tuşları, ne de bir hiç onlara sahip. Örneğin, duruma göre karar verirdim:

  • Amerika Birleşik Devletleri: Texas için state_id = 1 yerine state_code (Texas için 'TX' vb.)
  • Çalışanlar: Genellikle yapay bir çalışan_kimliği oluştururdum, çünkü çalışan başka bir şey bulmak zor. SSN veya muadili işe yarayabilir, ancak henüz SSN'sini sağlamayan yeni bir marangoz gibi sorunlar olabilir.
  • Çalışan Maaş Geçmişi: (çalışan_kimliği, başlangıç_tarihi). Ben ediyorum değil yapay bir employee_salary_history_id oluşturun. Hangi noktaya hizmet eder ( "aptalca tutarlılık" dışında )

Yapay anahtarların kullanıldığı her yerde, doğal anahtarlar üzerinde her zaman benzersiz kısıtlamalar beyan etmelisiniz. Örneğin, gerekirse state_id kullanın, ancak state_code üzerinde benzersiz bir kısıtlama beyan etmeniz daha iyi olur, aksi takdirde sonuçta aşağıdakileri elde edeceğinizden emin olabilirsiniz:

state_id    state_code   state_name
137         TX           Texas
...         ...          ...
249         TX           Texas

9
Bazı durumlarda SQL Server 2005/2008 ile doğal (metin) anahtar int anahtarından daha hızlı olabilir. Ben birincil anahtar olarak kullanmak ve bir int vekil daha hızlı (ve genellikle daha uygun) 7-8 karakter dostu kodu olan bir uygulama var. Yine de, farklı bir uygulama örneğine (daha büyük bir sitede toplanan birden fazla site) çakışmadan güvenli bir şekilde aktarabileceğimiz, insan tarafından okunabilir / unutulmaz bir koda sahip olabilmemiz için koda ihtiyacımız vardı.
lambacck

1
+1 İyi cevap. Bununla birlikte, personel memurunun bir çalışan tanımlayıcısının güvenilir kaynağı olmasını, yani gerçek hayatta SSN, referans alma, vs. gibi tanımlayıcıları kullanması muhtemel çalışanları doğrulamaktan sorumlu memur olmasını istiyorum. Personel departmanı güvenilir olmalıdır DBMS değil, çalışan tanımlayıcılarının kaynağı!
gün

@ onedaywhen- Yapmazdım. personel memuruna güvenin. İnsanlar ayrılıyor, yenileri geliyor ve farklı fikirleri var. Onlara benzersiz olduğunu düşündükleri / kullanmak istedikleri tanımlayıcıya erişim sağlayın, ancak db için dba kendi kararını vermelidir
Dave Pile

1
SSN'nin her ülkede benzersiz olması gerekmediğini unutmayın. En azından Avusturya'da, birden fazla kişi aynı numarayı paylaşabilir
maja

Ayrıca bazı ülkelerde (sanırım ABD'de bile) aslında SSN'yi paylaşmamanızı tavsiye ediyorlar.
Stijn de Witt

25

Sadece gözden kaçan bir şey hakkında fazladan bir yorum. Bazen yedek anahtar kullanmamanın alt tablolarda faydaları vardır. Diyelim ki bir veritabanında birden fazla şirket çalıştırmanıza izin veren bir tasarımımız var (belki de barındırılan bir çözümdür, ya da her neyse).

Diyelim ki şu tablo ve sütunlarımız var:

Company:
  CompanyId   (primary key)

CostCenter:
  CompanyId   (primary key, foreign key to Company)
  CostCentre  (primary key)

CostElement
  CompanyId   (primary key, foreign key to Company)
  CostElement (primary key)

Invoice:
  InvoiceId    (primary key)
  CompanyId    (primary key, in foreign key to CostCentre, in foreign key to CostElement)
  CostCentre   (in foreign key to CostCentre)
  CostElement  (in foreign key to CostElement)

Geçen bit mantıklı değil Bu durumda, Invoice.CompanyIdiki yabancı anahtarlar, birinden bir parçasıdır CostCentre masa ve birinden CostElement masaya. Birincil anahtar ( InvoiceId , CompanyId ) 'dir.

Bu modelde, bir şirketten bir CostElement ve başka bir şirketten bir CostCentre'ı bağlamak ve referans vermek mümkün değildir . CostElement ve CostCentre tablolarında bir yedek anahtar kullanılmış olsaydı, olurdu.

Vidalama şansı ne kadar az olursa o kadar iyidir.


6
Yedek anahtarlar kullanılırken bu değerin altında belirtilen bir dezavantajdır. Tablonun bir yedek anahtarı varsa, yine de bu tür kısıtlamalar için kullanabilirim. Ne yazık ki, kısıtlama bir dizin gerektiriyor ve (surrogate_key) tek başına benzersiz olduğunda (surrogate_key, other_column) üzerinde benzersiz bir dizin oluşturmak garip. Ayrıca, (other_column) bir harita tablosunda genellikle tamamen gereksizdir (çünkü surrogate_key) yabancı tabloda benzersizdir. Suretler gerçekten şeyleri berbat edebilir.
Samuel Danielson

24

Doğal anahtarları basit bir nedenden - insan hatası - kullanmaktan kaçınırım. Doğal benzersiz tanımlayıcılar genellikle mevcut olsa da (SSN, VIN, Hesap Numarası vb.), Bir insanın doğru girmesi gerekir. SSN'leri birincil anahtar olarak kullanıyorsanız, biri veri girişi sırasında birkaç sayı aktarır ve hata hemen bulunmazsa, birincil anahtarınızı değiştirmekle karşılaşırsınız.

Birincil anahtarlarımın tümü arka planda veritabanı programı tarafından işlenir ve kullanıcı bunların farkında değildir.


1
Birincil anahtarlar olarak SSN'leri veya Vergi Kimliklerini kullanan birkaç veritabanıyla çalıştım. Depolama ve yabancı anahtar referansları konusunda verimsiz. Bir kişinin SSN'sinin değişebileceğinden bahsetmiyorum bile. Bu yüzden sana tamamen katılıyorum.
Alex Jorgenson

13

Birincil anahtarınızı çeşitli alanlardan yapmada sorun yok, bu bir Doğal Anahtar .

Bir Yedek Anahtar oluşturmak için bir Kimlik sütunu (aday alanlarındaki benzersiz bir dizinle ilişkilendirilmiş) kullanabilirsiniz .

Bu eski bir tartışma. Çoğu durumda yedek anahtarları tercih ederim.

Ama anahtar eksikliğinden dolayı hiçbir mazereti yok.

RE: DÜZENLE

Evet, bununla ilgili çok fazla tartışma var: D

Doğal anahtarlar olmasının yanı sıra doğal anahtarlarda belirgin bir avantaj görmüyorum. İdPerson yerine her zaman Name, SocialNumber veya benzeri bir şey düşüneceksiniz .

Yedek anahtarlar, doğal anahtarların sahip olduğu bazı sorunların cevabıdır (örneğin değişiklikleri yaymak).

Vekillere alıştıkça daha temiz ve yönetilebilir görünüyor.

Ama sonunda, bunun sadece bir tat meselesi - ya da zihniyet - olduğunu öğreneceksiniz. İnsanlar doğal anahtarlarla "daha iyi düşünürler" ve diğerleri bunu yapmaz.


13
İnsanlar doğal anahtarlarla "daha iyi düşünüyor". Makineler ve veritabanları, yapma.
09:00

11

Tabloların her zaman birincil anahtarı olmalıdır. Başlamadığında, Otomatik Geliştirme alanları olmalıdır.

Bazen insanlar birincil anahtarı atlar, çünkü çok fazla veri aktarırlar ve süreci yavaşlatabilir (veritabanına bağlı olarak). ANCAK, sonra eklenmelidir.

Bağlantı tablosu hakkında bazı bir yorum , bu doğru, bütünlüğü korumak için FK olması gereken bir istisna AMA alanları olmalı ve bazı durumlarda bağlantılarda çoğaltmaya izin verilmiyorsa bu alanlar da birincil anahtar olabilir ... basit bir biçimdir, çünkü istisna programlamada sık sık bir şeydir, verilerinizin bütünlüğünü korumak için birincil anahtar mevcut olmalıdır.


Katılıyorum. Ve çok fazla verinin eklenmesi durumunda, birincil anahtar kısıtlamasını kaldırın (veya TSQL'de INSERT IDENTITY ON kullanın) ve daha sonra tekrar koyun :)
Andrew Rollings

1
İstisnalar var: Bağlantı tabloları açıkça
annakata

Başka bir neden: PK / benzersiz anahtar yoksa, tablo tarayıcıları (yani Access / SQL Server Management Studio gibi bir şey) tek bir satırı çoğaltılmış satırla güncellemeyi / silmeyi reddeder. Bunun için SQL yazmanız gerekecek.
Dennis C

PK'yi veri ambarı bilgi tablosundan çıkarmak oldukça yaygındır. Oracle'da ROWID sözde sütununa kısa vadede benzersiz bir tanımlayıcı olarak başvurabilirsiniz (yani bir yerde saklamayın ve değişmemesini
bekleyin

9

Tüm bu iyi cevapların yanı sıra, sadece okuduğum iyi bir makaleyi paylaşmak istiyorum, Büyük birincil anahtar tartışması .

Sadece birkaç nokta alıntı yapmak için:

Geliştirici, her tablo için birincil anahtar seçerken birkaç kural uygulamalıdır:

  • Birincil anahtar, her kaydı benzersiz şekilde tanımlamalıdır.
  • Bir kaydın birincil anahtar değeri boş olamaz.
  • Kayıt oluşturulduğunda birincil anahtar / değer çiftinin olması gerekir.
  • Birincil anahtar sabit kalmalıdır; birincil anahtar alanlarını değiştiremezsiniz.
  • Birincil anahtar kompakt olmalı ve mümkün olan en az özniteliği içermelidir.
  • Birincil anahtar değeri değiştirilemez.

Doğal anahtarlar kuralları çiğneme eğilimindedir. Yedek anahtarlar kurallara uygundur. (Bu makaleyi okursanız iyi olur, zaman ayırmaya değer!)


7

Birincil anahtarla ilgili özel olan nedir?

Şemadaki bir tablonun amacı nedir? Bir tablonun anahtarının amacı nedir? Birincil anahtarla ilgili özel olan nedir? Birincil anahtarların etrafındaki tartışmalar, birincil anahtarın bir tablonun parçası olduğu ve bu tablonun bir şemanın parçası olduğu noktasını gözden kaçırıyor gibi görünüyor. Tablo ve tablo ilişkileri için en iyi olanı kullanılan anahtarı kullanmalıdır.

Tablolar (ve tablo ilişkileri) kaydetmek istediğiniz bilgilerle ilgili gerçekleri içerir. Bu gerçekler bağımsız, anlamlı, kolay anlaşılır ve çelişkili olmamalıdır. Tasarım açısından, şemaya eklenen veya şemadan kaldırılan diğer tablolar, söz konusu tabloyu etkilememelidir. Yalnızca bilginin kendisiyle ilgili verilerin depolanması için bir amaç olmalıdır. Bir tabloda nelerin depolandığını anlamak için bir bilimsel araştırma projesi yapılmasını gerektirmemelidir. Aynı amaç için saklanan hiçbir bilgi bir kereden fazla saklanmamalıdır. Anahtarlar, kaydedilen bilginin bir kısmı veya bir kısmıdır ve birincil anahtar, tabloya birincil erişim noktası olacak özel olarak belirlenmiş anahtardır (yani, yalnızca eklemek için değil, veri tutarlılığı ve kullanımı için seçilmelidir verim).

  • ASIDE: Maalesef, çoğu zaman uygulama programcıları tarafından tasarlanan ve geliştirilen veritabanlarının yan etkisi (bazen ben olduğum), uygulama veya uygulama çerçevesi için en iyi olanın genellikle tablolar için birincil anahtar seçimini yönlendirmesidir. Bu, tamsayı ve GUID anahtarlarına (bunlar uygulama çerçeveleri için kullanımı basit olduğu için) ve monolitik tablo tasarımlarına (bellekteki verileri temsil etmek için gereken uygulama çerçevesi nesnelerinin sayısını azalttığından) yol açar. Bu uygulama odaklı veritabanı tasarım kararları, ölçekte kullanıldığında önemli veri tutarlılığı sorunlarına yol açar. Bu şekilde tasarlanan uygulama çerçeveleri doğal olarak bir seferde tablolara yol açar. Tablolarda ve zaman içinde doldurulmuş verilerde “kısmi kayıtlar” oluşturulur. Çok tablolu etkileşimden kaçınılır veya kullanıldığında, uygulama düzgün çalışmadığında tutarsız verilere neden olur. Bu tasarımlar anlamsız (veya anlaşılması zor) verilere, tablolara yayılmış verilere (geçerli tabloyu anlamak için diğer tablolara bakmanız gerekir) ve çoğaltılmış verilere yol açar.

Birincil anahtarların gerektiği kadar küçük olması gerektiği söylendi. Anahtarların sadece gerektiği kadar büyük olması gerektiğini söyleyebilirim. Bir tabloya rastgele anlamsız alanlar eklemekten kaçınılmalıdır. Rastgele eklenen anlamsız bir alandan, özellikle başka bir tablodan birincil olmayan anahtara birleştirme bağımlılığını yok ettiğinde bir anahtar yapmak daha da kötüdür. Bu, yalnızca tabloda iyi bir aday anahtarı yoksa makul olur, ancak bu oluşum, tüm tablolar için kullanılıyorsa kesinlikle kötü bir şema tasarımının bir işaretidir.

Birincil anahtarın güncellenmesi her zaman söz konusu olmadığı için birincil anahtarların asla değişmemesi gerektiği de söylendi. Ancak güncelleme, silme ve ardından ekleme ile aynıdır. Bu mantıkla hiçbir zaman bir anahtar içeren bir tablodan kayıt silmemeli ve sonra ikinci anahtarla başka bir kayıt eklememelisiniz. Yedek birincil anahtarı eklemek, tablodaki diğer anahtarın var olduğu gerçeğini kaldırmaz. Bir tablonun birincil olmayan bir anahtarını güncellemek, diğer tabloların bir yedek anahtar aracılığıyla bu anlama bağımlı olması durumunda verilerin anlamını yok edebilir (örneğin, durum açıklaması 'İşlendi' yerine 'İptal edildi olan yedek anahtarlı bir durum tablosu 'kesinlikle verileri bozar). Her zaman söz konusu olmaması gereken, veri anlamını yok etmektir.

Bunu söyledikten sonra, bugün işletmelerde var olan birçok kötü tasarlanmış veritabanına minnettarım (anlamsız-vekil-anahtarlı-veri-bozuk-1NF behemoths), çünkü bu, uygun veritabanı tasarımını anlayan insanlar için sonsuz miktarda çalışma olduğu anlamına gelir. . Ama üzücü tarafta, bazen beni Sisifos gibi hissettiriyor, ama bahse girerim (çarpışmadan önce) 401k'lik bir heck vardı. Önemli veritabanı tasarımı soruları için bloglardan ve web sitelerinden uzak durun. Veritabanları tasarlıyorsanız, CJ Date'e bakın. SQL Server için Celko'ya da başvurabilirsiniz, ancak önce burnunuzu tutarsanız. Oracle tarafında Tom Kyte'e başvurun.


1
"Bu mantıkla hiçbir zaman bir anahtar içeren bir tablodan kayıt silmemeli ve sonra ikinci anahtarla başka bir kayıt eklememelisiniz." - Bunun için bir dava var ve bu da yabancı bir anahtardaki "SİLME SINIRI" yan tümcesinin etkili bir şekilde yapacağı şeydir. Bazı durumlarda (denetim izinin gerekli olduğu durumlarda) "silinmiş" bir boole alanı, kaydın silinmesine izin vermekten daha iyi olabilir.
Waz

6

Varsa, doğal bir anahtar genellikle en iyisidir. Bu nedenle, datetime / char satırı benzersiz bir şekilde tanımlar ve her iki parça da satır için anlamlıysa, bu harika.

Sadece datetime anlamlıysa ve karakter onu benzersiz kılmak için taranmışsa, bir tanımlama alanı ile de gidebilirsiniz.


9
Genellikle en iyisi? Bilimsel bir dayanağım yok ama çoğu insanın doğal yerine yedek bir anahtar tercih ettiği konusunda neredeyse pozitifim. Çoğu durumda doğal bir anahtar yoktur.
JC.

3
Veri tabanınızdaki herhangi bir satır için DAİMA doğal bir anahtar olmalıdır. Bu "doğal" anahtar, iş dünyasında veya teknik sisteminizde üretilen bir şey olabilir, ancak her zaman var olmalıdır.
Tom H

2
Eğer dünyanızda, tablodaki bir satırı tanımlamanın tek yolu olarak belirlenen şey buysa, o zaman evet. Tabii ki, bir tasarımcı bir PK için bir GUID oluşturmayı seçtiğinde, bunun nedeni genellikle GERÇEK doğal anahtarı bulmak için çalışma yapmadı, bu durumda GUID doğal anahtar DEĞİLDİR.
Tom H

8
2. Anahtarınızı doğal dünyadan alırsanız, doğal dünya anahtarınızı kırmak için değişecektir. Telefon numarasını kullanırsanız, aynı evden iki kullanıcı alırsınız. Soyadını kullanırsanız, evlenirler. SSN kullanırsanız, gizlilik yasaları değişir ve bunları kaldırmanızı gerektirir.
James Orr

2
@Marry: RE: # 2. doğal dünya değişirse ve bu doğal anahtarınızın değişmesine neden olursa, doğal bir anahtar seçerken kötü bir iş yaptığınız anlamına gelir. Tanımı gereği, doğal bir anahtar zamanla değişmez.
Tom H

6

İşte 25 yıldan fazla geliştirme deneyiminden sonra karar verdiğim kendi kuralım.

  • Tüm tablolarda otomatik olarak artan tek bir sütun birincil anahtarı bulunmalıdır.
  • Güncellenebilir olması gereken herhangi bir görünüme dahil edin
  • Birincil anahtarın, uygulamanız bağlamında bir anlamı olmamalıdır. Bu, SKU veya hesap numarası veya çalışan kimliği veya uygulamanız için anlamlı başka herhangi bir bilgi olmaması gerektiği anlamına gelir. Yalnızca bir varlıkla ilişkilendirilmiş benzersiz bir anahtardır.

Birincil anahtar, veritabanı tarafından en iyileştirme amacıyla kullanılır ve uygulamanız tarafından belirli bir varlığı tanımlamaktan veya belirli bir varlıkla ilişkili olmaktan başka bir şey için kullanılmamalıdır.

Her zaman tek değerli bir birincil anahtara sahip olmak, UPSERT'leri gerçekleştirmeyi çok kolay hale getirir.

Uygulamanızda anlamı olan çok sütunlu anahtarları desteklemek için ek dizinler kullanın.


5

Bana göre doğal anahtarlar ve yapay anahtarlar, veritabanınızda ne kadar iş mantığı istediğinize bağlıdır. Sosyal Güvenlik numarası (SSN) buna iyi bir örnektir.

"Veritabanımdaki her istemcinin bir SSN'si olacak ve olmalıdır." Bam, bitti, onu birincil anahtar yap ve onunla yap. Sadece iş kuralı değiştiğinde yandığını hatırla.

İş kurallarını değiştirme deneyimim nedeniyle doğal anahtarları kendim sevmiyorum. Ancak değişmeyeceğinden eminseniz, birkaç kritik birleşmeyi önleyebilir.


8
SSN'nin benzersiz olmasına rağmen benzersiz olmadığı veriler gördüm. Verilerinizi başka bir kaynaktan içe aktarırsanız doğal anahtarlara karşı çok dikkatli olun!
HLGEM

2
Kimlik hırsızlığına maruz kalırsanız, sosyal güvenlik numaranızı değiştirebilirsiniz. Sayınızı değiştirecekleri dört durum daha vardır ve bunlar ssa.gov sitesinde listelenir.
Zvi Twersky

4

Steven A. Lowe'un orijinal veri yapısının tasarımcısı için hazırladığı gazete terapisinin gerekli olduğundan şüpheleniyorum.

Bir kenara, birincil anahtar olarak GUID'ler bir performans domuz olabilir. Ben tavsiye etmem.


2
Bunun bir performans domuzunun erken optimizasyon olduğunu söylemek. Bazı durumlarda kılavuzlar gereklidir (bağlantısı kesilen istemciler, gelecekteki tablo birleştirme, çoğaltma)
JC.

2
"Erken optimizasyon" SO (IMHO) üzerinde aşırı bir ifade olduğunu! Evet, bazı durumlarda GUID'ler gerekebilir, ancak Andrew gerekli olsun ya da olmasın varsayılan veri türü olarak kullanılmamaları gerektiğine işaret eder.
Tony Andrews

Tamam, aslında erken bir optimizasyon değildi. Demek istediğim, çoğu insanın performans farkını fark etmek için gereken hacmi deneyimlememesi. Evet, asla bir rehbere ihtiyacınız olmayacağını biliyorsanız otomatik girişim kullanın.
JC.

Veya her ikisini de kullanın. Güzel hızlı seçimler ve birleşimler için int / long tabanlı bir birincil anahtarınız ve ardından bir kılavuz alanınız olsun. En azından ben bunu yapıyorum. Bu yanlış mı? Bunu yapmamalı mıyım? :)
Andrew Rollings

Her iki sütunu da kullanıyorum. Ama yanlış olup olmadığından emin değilim. @AndrewRollings'i buldunuz mu?
YÒGÎ

3

Birden çok alandan oluşan bir 'bileşik' veya 'bileşik' birincil anahtar kullanmalısınız.

Bu mükemmel kabul edilebilir bir çözümdür, daha fazla bilgi için buraya gidin :)


3

Ben de her zaman sayısal bir kimlik sütunu kullanıyorum. Oracle'de (18,0) sayısını (12,0) üzerinde gerçek bir sebep olmadan kullanıyorum (ya da uzuntan çok int ne olursa olsun), belki sadece birkaç milyar satır almaktan endişelenmek istemiyorum db!

Ayrıca, temel izleme için yararlı göründüğü için oluşturulmuş ve değiştirilmiş bir sütun (zaman damgası) da ekliyorum.

Diğer sütun kombinasyonlarında benzersiz kısıtlamalar oluşturmayı umursamıyorum, ancak kimliğimi, oluşturduğum, değiştirilmiş temel gereksinimleri gerçekten seviyorum.


2
Ayrıca bağlantı / birleştirme tabloları, yalnızca veri içeren tablolarda kimlikleri koyma işaret etmeliyim.
JeeBee

3

Doğal birincil anahtarları arıyorum ve bunları mümkün olduğunca kullanıyorum.

Hiçbir doğal anahtar bulunamazsa, SQL Server ağaç kullandığından ve her zaman ağaçlarda sonuna anahtar eklemek kötü çünkü INT ++ için bir GUID tercih ederim.

Çoktan çoğa kuplaj olan tablolarda, yabancı anahtarların bileşik birincil anahtarını kullanıyorum.

SQL Server'ı kullanmak için yeterince şanslı olduğum için, profiler ve sorgu analizörü ile yürütme planlarını ve istatistiklerini inceleyebilir ve anahtarlarımın nasıl kolayca performans gösterdiğini öğrenebilirim.


Bu ifadeyi yedeklemek için herhangi bir belgeleriniz var mı: 'hiçbir doğal anahtar bulunamazsa, SQL Server ağaç kullandığından INT ++ için bir GUID tercih ederim ve ağaçların sonuna her zaman anahtar eklemek kötüdür.' Şüpheci değil, sadece bazı belgeleri derlemeye çalışıyorum.
Lloyd Cotten

1
@Lloyd - Kendimi çok etkileyici bulduğum bir şeye ilgi duyduğuna sevindim.
Msdn.microsoft.com/en-us/library/ms177443(SQL.90).aspx

2

Her zaman bir bağımsız numara veya kimlik alanı kullanırım.

SSN'yi birincil anahtar olarak kullanan bir müşteri için çalıştım ve daha sonra HIPAA düzenlemeleri bir "MemberID" olarak değiştirilmek zorunda kaldı ve ilgili tablolardaki yabancı anahtarları güncellerken tonlarca soruna neden oldu. Bir kimlik sütununun tutarlı bir standardına bağlı kalmak, tüm projelerimde benzer bir sorundan kaçınmama yardımcı oldu.


6
Bir geliştirici tarafından doğal anahtarın yetersiz seçilmesi, doğal anahtarların kötü olduğu anlamına gelmez.
Tom H

1
Kullanımı zor bir araç bir şekilde o alete karşı bir nokta değil mi?
Sqeaky

1

Tüm tabloların birincil anahtarı olmalıdır . Aksi takdirde, sahip olduğunuz bir HEAP'tır - bu, bazı durumlarda istediğiniz şey olabilir (veriler daha sonra bir hizmet aracısı aracılığıyla başka bir veritabanına veya tabloya çoğaltıldığında ağır ek yükü).

Düşük satır hacmine sahip arama tabloları için, bir INT'den daha az yer kapladığından, ancak performans farkı göz ardı edilebilir olduğundan, birincil anahtar olarak 3 CHAR kodu kullanabilirsiniz. Bunun dışında, ilişkili tablolardan gelen yabancı anahtarlardan oluşan birleşik birincil anahtar içeren bir referans tablonuz yoksa, her zaman bir INT kullanırdım.


1

Eğer gerçekten bu eski tartışmada ileri geri okumak istiyorsanız, Stack Overflow'da "doğal anahtar" için bir arama yapın. Sonuç sayfalarını geri almalısınız.


1

GUID'ler birincil anahtar olarak kullanılabilir, ancak iyi performans göstermesi için doğru GUID türünü oluşturmanız gerekir.

COMB GUID'leri oluşturmanız gerekir. Bu konuda iyi bir makale ve performans istatistikleri Birincil Anahtarlar olarak GUID'lerin Maliyeti .

Ayrıca SQL'de COMB GUID'leri oluşturmaya yönelik bazı kodlar, Identident ( arşiv ) ve Uniqueidentifier'tadır .


5
IMHO, guid's yalnızca veritabanları arasında veri senkronizasyonu yapmanız gerektiğinde kullanılmalıdır. Otomatik olarak oluşturulan bir kimliğin sorunlu olduğu. Bir kılavuz kullanma ile temel bir sayısal tür kullanma arasındaki fark, bir kılavuzun satır başına 16 bayt gerektirmesi, bir numerik ise çok daha küçük olmasıdır.
Logicalmind

Yukarıda verdiğim bağlantıya giderseniz, COMB Kılavuzlarını kullanarak performansta çok az fark vardır.
Donny V.

0

Çok fazla birleştirme yapıyoruz ve kompozit birincil anahtarlar sadece bir performans domuzu haline geldi. Basit bir int veya long, ikinci bir aday anahtar girmiş olsanız bile birçok sorunu halleder, ancak bir alana üçe karşı katılmak çok daha kolay ve daha anlaşılır.


1
Kompozit anahtarlar yayılmadığından, ihtiyacınız olan gerçek iki tabloya katılmak için şimdi 6 tabloyu geçmeniz gerektiğinde bu strateji dağılmaktadır. Ayrıca, BÜYÜK bir performans domuzu olabilen çoklu uçlar için döngüler / imleçlerin kullanılmasını gerektirir.
Tom H

2
Yeni bir şey öğrenmek için çok büyük değilim. Söylediklerinizin bir örneğini görmek isterim, bu dini argümanların bazılarına biraz rasyonel bir gerçek enjekte etmek faydalı olacaktır.
Dan Blair

0

Doğal anahtar tercihimi konusunda ön sıralarda olacağım - veritabanı yönetimi hayatınızı daha kolay hale getirecekleri için mümkün olan yerlerde kullanın. Şirketimizde tüm tabloların aşağıdaki sütunlara sahip olduğu bir standart oluşturdum:

  • Satır Kimliği (GUID)
  • Oluşturan (dize; geçerli kullanıcının adının varsayılanı vardır ( SUSER_SNAME()T-SQL'de))
  • Oluşturuldu (DateTime)
  • Zaman Damgası

Satır Kimliği'nin tablo başına benzersiz bir anahtarı vardır ve her durumda satır başına otomatik olarak oluşturulur (ve izinler herkesin düzenlemesini önler) ve tüm tablolarda ve veritabanlarında benzersiz olması garanti edilir. Herhangi bir ORM sistemi tek bir kimlik anahtarına ihtiyaç duyarsa, bu tek kullanılan anahtardır.

Bu arada, gerçek PK mümkünse doğal bir anahtardır. İç kurallarım şuna benzer:

  • İnsanlar - yedek anahtar kullanın, örneğin INT. Dahili ise, Active Directory kullanıcı GUID'si kabul edilebilir bir seçimdir
  • Arama tabloları (örn. StatusCodes) - kısa bir CHAR kodu kullanın; INT'lerden hatırlamak daha kolaydır ve çoğu durumda kağıt formları ve kullanıcılar kısaltmak için kullanırlar (örneğin, "Süresi Doldu" için Durum = "E", "Onaylandı" için "A", "Asbest Algılanmadı" için Örnekte ")
  • Bağlantı tabloları - FK'lerin kombinasyonu (örn. EventId, AttendeeId)

İdeal olarak, doğal, insan tarafından okunabilir ve akılda kalıcı bir PK ve ORM dostu bir tablo başına bir ID GUID ile sonuçlanır.

Dikkat: benim tuttuğum veritabanları milyonlarca veya milyarlarca yerine 100.000 kayda eğilimlidir, bu yüzden tavsiyemi kontrendike eden daha büyük sistem deneyimine sahipseniz, beni görmezden gelmekten çekinmeyin!


1
Güçlü bir doğal anahtarı olmayan tablolar için her ikisini GUID ve INT SK'leri oluşturmayı mı öneriyorsunuz ?

Yapmanız gerekmiyor, ancak faydaları: a) ihtiyacınız varsa çoğaltmayı kolaylaştırıyor, b) ORM ile uğraşırken, kaydetmeden önce nesneye kodda benzersiz bir kimlik atayabilirsiniz (bu, belki de kaydetmeden önce bir oturum önbelleğine kaydederek, nesneniz üzerinde birçok düzenleme yapmanız gerekir). Anahtar, bu görüntüdeki INT'dir; GUID sadece bir bonus.
Keith Williams
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.