Yedek / doğal anahtarlar / işletme anahtarları [kapalı]


174

İşte yine başlıyoruz, eski argüman hala ortaya çıkıyor ...

Bir işletme anahtarı birincil anahtar olarak daha iyi olsaydı, yoksa işletme anahtarı alanında benzersiz bir kısıtlamaya sahip bir yedek kimliğimiz (yani bir SQL Server kimliği) olmasını ister miydik?

Lütfen teorinizi destekleyecek örnekler veya kanıtlar sağlayın.


24
@Joachim Sauer: Bir şeyin öznel olup olmadığı hakkındaki bir tartışma, söz konusu şeyin nesnelliği veya öznelliği ile hiçbir şekilde ilişkili olmadan, öznel olabilir. Bir şeyi objektif yapan kesin objektif kriterleri belirtmeye hazır değilseniz. Sakal yapmak için kaç tane tüy gerektiği gibi "açık konseptler" denilen şeyler vardır. Nesnel olarak çene kılları olmayan bir kişinin sakalı olmadığını ve inç uzunluğunda 5.000 kılı olan birinin sakalı olduğunu söyleyebilir, ancak objektif bir karar vermek için orta öznel yargının bir yerinde olması gerekir.
ErikE

@Manrico: Kendinize şunu sormanız gerekiyor: Yedek anahtar kullanmazsam, birincil anahtarım hala değişmez olacak mı? Cevap hayırsa, bir yedek anahtar kullanmayı ciddi olarak düşünmelisiniz. Ayrıca, birincil anahtar kısmen kullanıcı girdilerinden oluşuyorsa, yedek anahtar kullanmayı düşünmelisiniz. Neden? Veri anomalileri tehlikesi nedeniyle.
code4life

@TylerRick Ama bu çok iyi bir soru değil. Askerin mükemmel bir şekilde farkında olduğu “dini savaş” tarafından kanıtlandığı gibi, açıkça olmadığı zaman tüm durumlar için geçerli olan bir çözüm ister (alıntı: "İşte yine başlıyoruz, eski argüman hala ortaya çıkıyor. .. "). Dünyanın değişip değişmediğini merak etmek yerine ve nihayet her zaman bir taraf seçmek için zorlayıcı bir neden sağlandı, her somut durum için bu soruyu tekrar tekrar sormaya devam etmek ve emin olmadığınız zaman SO'ya göndermek daha iyidir. . Bu sadece dogmatizmi ortaya çıkarır.
MarioDS

Yanıtlar:


97

Her ikisi de. Pastanı al ve ye.

Birincil anahtarla ilgili özel bir şey olmadığını unutmayın, ancak bu şekilde etiketlenmesi gerekir. NOT NULL UNIQUE kısıtlamasından başka bir şey değildir ve bir tablonun birden fazla değeri olabilir.

Yedek bir anahtar kullanırsanız, iş kurallarına göre benzersizliği sağlamak için yine de bir iş anahtarı istersiniz.


7
Birden fazla "aday" anahtarınız varsa (alanlar veya aynı boyutta alanların NULL UNIQUE DEĞİLDİR), muhtemelen Boyce-Codd Normal Formunu ihlal edersiniz. BCNF 3NF'nin ötesindedir, bu yüzden pek çok insan bunun için endişelenmez. Bununla birlikte, BCNF'de olmanın çok yararlı olduğu durumlar vardır.
Alan

2
Kabul. Asıl soru şu olmalı: Tablolarıma benzersiz bir yedek anahtar eklemeli miyim? Tamamen başka bir soru, mantıksal bir birincil anahtar için ne kullanılacağıdır. Her ikisi de aslında boş olmayan benzersiz dizin kısıtlamalarıdır.
dkretz

1
"Her problem başka bir dolaylı ses seviyesi ile çözülür" ... Yedek anahtarlar tam da budur: başka bir dolaylı seviye
Steve Schnepp

5
Birçok yorumun bir vekil anahtar olmadan bir ilişki kuramayacağını iddia etmek tuhaf görünüyor. Çoğu durumda, vekil anahtar gereksizdir. Neden değer getirmeyen ancak teknik borç ekleyen bir şey eklemeliyiz (ve bazı durumlarda, aniden benzersiz olmayan bir sonucun benzersiz olmasına neden olur).
Wil Moore III

2
NULL UNIQUE kısıtlamasından daha fazlasıdır. Birincil anahtar, verilerinizin fiziksel sırasını belirleyen kümelenmiş bir dizin olarak kullanılır. Genel olarak, sırayla arttığından ve verileriniz diskteki EOF'a ekleneceğinden Tamsayı'nın dengelenmesi kolaydır. Metin veya GUID (UUID) gibi daha az ardışık veri kullanırsanız, çok daha fazla disk IO ve dizini dengeleme çabası olacaktır, bence bu büyük bir fark
Jin

124

Yedek anahtarları kullanmanın sadece birkaç nedeni:

  1. Kararlılık : Bir işletme veya doğal ihtiyaç nedeniyle bir anahtarın değiştirilmesi ilgili tabloları olumsuz etkileyecektir. Vekil anahtarlar nadiren, eğer varsa, değere bağlı bir anlam olmadığı için değiştirilmelidir.

  2. Sözleşme : PK'ları için çeşitli adlara sahip tablolara nasıl katılacağınızı düşünmek yerine standartlaştırılmış Birincil Anahtar sütun adlandırma kuralına sahip olmanızı sağlar.

  3. Hız : PK değerine ve türüne bağlı olarak, bir tamsayının bir yedek anahtarı daha küçük, dizine eklenmesi ve aranması daha hızlı olabilir.


2
Şimdi, yedek anahtarlar ve doğal anahtarlar hakkında çok şey okuduktan sonra, yedek anahtarları kullanmanın daha iyi olduğunu düşünüyorum. Ancak, veritabanımda doğal anahtarlar (bir NVARCHAR (20)) benzersiz olmalıdır. Her bir ek üzerinde herhangi bir değeri (NOT NULL UNIQUE kısıtlaması kullanarak) tekrarlamamak için bu sütundaki her veriyi kontrol etmem gerekirse nasıl daha fazla hız alabileceğimi anlamıyorum.
VansFannel

70

Görünüşe göre hiç kimse vekil olmayan anahtarları ("doğal" demekten çekinmeyin) hiçbir şey söylemedi. İşte gidiyor ...

Yedek anahtarların bir dezavantajı , anlamsız olmalarıdır (bazıları tarafından bir avantaj olarak belirtilir, ancak ...). Bu bazen sorgunuzda gerçekten gerekli olduğundan çok daha fazla tabloya katılmaya zorlar. Karşılaştırmak:

select sum(t.hours)
from timesheets t
where t.dept_code = 'HR'
and t.status = 'VALID'
and t.project_code = 'MYPROJECT'
and t.task = 'BUILD';

karşısında:

select sum(t.hours)
from timesheets t
     join departents d on d.dept_id = t.dept_id
     join timesheet_statuses s on s.status_id = t.status_id
     join projects p on p.project_id = t.project_id
     join tasks k on k.task_id = t.task_id
where d.dept_code = 'HR'
and s.status = 'VALID'
and p.project_code = 'MYPROJECT'
and k.task_code = 'BUILD';

Birisi aşağıdakilerin ciddi bir şekilde düşünmediği sürece iyi bir fikir mi ?:

select sum(t.hours)
from timesheets t
where t.dept_id = 34394
and t.status_id = 89    
and t.project_id = 1253
and t.task_id = 77;

"Ama" birisi diyecektir, "MYPROJECT veya VALID veya HR kodu değiştiğinde ne olur?" Hangi cevabım şöyle olacaktır: "Neden olur ihtiyaç değiştirmek için?" Bunlar, bazı dış organların bundan böyle 'VALID'in' İYİ 'olarak yeniden kodlanması gerektiğine karar vermesi anlamında "doğal" anahtarlar değildir. "Doğal" tuşların sadece küçük bir yüzdesi bu kategoriye girer - SSN ve Posta kodu her zamanki örneklerdir. Kişi, Adres gibi tablolar için kesinlikle anlamsız bir sayısal anahtar kullanırdım - ama her şey için değil , bu yüzden çoğu insan burada savunuyor gibi görünüyor.

Ayrıca bakınız: başka bir soruya cevabım


14
-1 Birincil anahtar olarak doğal anahtarlar, her alt tablo için, birden fazla alandan (bir yedek anahtar durumunda olan bir tane yerine) oluşturulabilen ebeveynin anahtarını ve ayrıca çocuğu eklemeniz gerektiğinde sorun yaşar. tuşuna basın. Öyleyse TABLEA'dan başlayarak ilişkinin 1-0 olduğunu düşünün. *: TABLEA PK: ID_A TABLEB PK: ID_A ID_B TABLEC PK: ID_A ID_B ID_C TABLED PK: ID_A ID_B ID_C ID_D. Sorunu görüyor musunuz? Üst anahtar alt tablolarda yayılır. TABLEA'nın birincil anahtarı değişirse ne olur? Şimdi tüm çocuk masaları PK'yi yeniden düzenlemelisiniz.
Alfredo Osorio

9
@Alfredo: evet tabii ki bir değiş tokuş var. Ancak, 20 yılı aşkın deneyimimde, bir tablonun PK değişikliğinin tanımını nadiren gördüm. Düzenli olarak olsaydı, muhtemelen doğal anahtarlardan da kaçınırdım. Gerçekte, bunun çok nadir gerçekleştiği durumlarda, genişletilmiş etkiyi vurmaya hazırım.
Tony Andrews

10
Katılmıyorum. Genellikle bazı dış organların (müşteri), doğal bir anahtarın düzenlenmesi ve dolayısıyla sistem boyunca yayılması gerektiğine dair yasa düzenlediği durumdur. Bunun düzenli olarak gerçekleştiğini görüyorum. Anahtarın değiştirmeye gerek duymayacağından emin olmanın tek yolu, tanım gereği anlamsız olmasıdır. Dahası, modern veritabanları iç birleşimleri son derece verimli bir şekilde idare eder, bu nedenle suretler kullanmaktan potansiyel olarak büyük alan kazanımları, birçok iç birleşim yapmak zorunda kalmama avantajından ağır basar.
TTT

8
@TTT: Sonra tasarımın başlaması zayıftı. Yine, erkekler burada erkeklerden ayrılıyor: doğal anahtarı ne zaman kullanacaklarını ve vekil ne zaman kullanacaklarını doğru seçerek. Buna genel dogma olarak değil, tablo başına karar verirsiniz.
DanMan

7
Ayrıca 20 yılı aşkın tecrübem var ve fikrinizi ikinci sıradayorum. Bir zamanlar vekil anahtarlarla oracle veri ambarı oluşturdum ve veri bakımı cehennem gibiydi. Verilerinize asla doğrudan erişemezsiniz. her şey için her zaman sorgular yazmanız gerekir ve bu, yedek anahtarları işlemeyi çok korkunç hale getirir.
SQL Police

31

Yedek anahtarın ASLA değiştirmek için bir nedeni yoktur. Doğal anahtarlar için aynı şeyi söyleyemem. Soyadları, e-postalar, ISBN kopyaları - hepsi bir gün değişebilir.


31

Yedek anahtarlar (genellikle tamsayılar), tablo ilişkilerinizi daha hızlı ve depolama ve güncelleme hızında daha ekonomik hale getirmenin katma değerine sahiptir (daha da iyisi, yedek anahtarları kullanırken, iş anahtar alanlarının aksine, yabancı anahtarların güncellenmesine gerek yoktur, o zaman zaman değişir).

Tablonun birincil anahtarı, esas olarak birleştirme amaçları için satırı benzersiz bir şekilde tanımlamak için kullanılmalıdır. Bir Kişiler tablosu düşünün: isimler değişebilir ve benzersiz oldukları garanti edilmez.

Düşünen Şirketler: Merkia'daki diğer şirketlerle iş yapan mutlu bir Merkin şirketidir. Şirket adını birincil anahtar olarak kullanmayacak kadar zekisiniz, bu nedenle Merkia hükümetinin benzersiz şirket kimliğini 10 alfasayısal karakterden tamamen kullanıyorsunuz. Sonra Merkia, şirket kimliklerini değiştirdi çünkü iyi bir fikir olacağını düşündüler. Tamam, db motorunuzun basamaklı güncellemeler özelliğini kullanıyorsunuz, ilk etapta sizi içermemesi gereken bir değişiklik için. Daha sonra işiniz genişler ve şimdi Freedonya'daki bir şirketle çalışıyorsunuz. Freedonya şirket kimliği 16 karaktere kadar. Birincil anahtarı (ayrıca yabancı anahtarlarda) bir Ülke alanı ekleyerek, şirket kimliği birincil anahtarını (Siparişler, Sorunlar, Para Transferleri vb. Yabancı anahtar alanları) genişletmeniz gerekir. Ah! Freedonya'da iç savaş, o ' üç ülkeye ayrılmıştır. İş arkadaşınızın ülke adı yenisiyle değiştirilmelidir; kurtarma güncellemeleri basamaklı. BTW, birincil anahtarınız nedir? (Ülke, Şirket Kimliği) veya (Şirket Kimliği, Ülke)? İkincisi katılmaya yardımcı olur, birincisi başka bir dizinden kaçınır (veya Siparişlerinizin ülkeye göre gruplanmasını istiyorsanız belki de çok sayıda).

Tüm bunlar kanıt değildir, ancak birleştirme işlemi de dahil olmak üzere tüm kullanımlar için bir satırı benzersiz bir şekilde tanımlayan bir yedek anahtarın bir iş anahtarına tercih edildiğinin bir göstergesidir.


En havalı kullanıcı adıyla tüm internetleri kazanın!
Iain Holder

1
Bir aşağı oy budur: "Buna katılmıyorum."
jcollum

5
Aşağı okun ipucu "Bu cevap yararlı değil", "Buna katılmıyorum" diyor. Belki de bu özel cevapta anlamlar yakındır, ancak genellikle aynı değildir.
tzot

1
Birisi cevabınızın yanlış olduğunu düşünüyorsa, o da soruyu yanlış yönde (doğru yönün tersine) yönlendirdiğini düşünecek ve bu nedenle cevabınızı "yararsız" dan daha kötü olarak değerlendirecektir, zihninde bir aşağı oyu haklı çıkarmak.
Erwin Smout

1
Evet, vekil anahtarlar bir hastalıktır. Biri vahşi doğaya sızıyor ve onu bir anahtar olarak kullanıyorsunuz, şimdi kendi yedek anahtarınıza ihtiyacınız var. Ardından anahtarınız vahşi doğaya sızıyor (bir url aracılığıyla söyleyin) ve hastalık yayılıyor.
Samuel Danielson

25

Genel olarak yedek anahtarlardan nefret ediyorum. Sadece kaliteli doğal anahtar olmadığında kullanılmalıdır. Bunu düşündüğünüzde, tablonuza anlamsız veri eklemenin işleri daha iyi hale getirebileceğini düşünmek oldukça saçmadır.

İşte nedenlerim:

  1. Doğal anahtarlar kullanıldığında, tablolar en sık aranacakları şekilde kümelenir ve böylece sorguları daha hızlı hale getirir.

  2. Yedek anahtarları kullanırken, mantıksal anahtar sütunlarına benzersiz dizinler eklemeniz gerekir. Yine de mantıksal yinelenen verileri önlemeniz gerekir. Örneğin, pk bir yedek kimlik sütunu olmasına rağmen, aynı adı taşıyan iki Kuruluşa Organizasyon tablonuzda izin veremezsiniz.

  3. Yedek anahtarlar birincil anahtar olarak kullanıldığında, doğal birincil anahtarların ne olduğu çok daha az açıktır. Geliştirirken hangi sütun kümesinin tabloyu benzersiz kıldığını bilmek istersiniz.

  4. Bir-çok ilişki zincirinde, mantıksal anahtar zincirleri. Örneğin, Örgütlerin çok sayıda Hesabı ve Hesapların çok sayıda Faturaları vardır. Organizasyonun mantıksal anahtarı OrgName'dir. Hesapların mantıksal anahtarı OrgName, AccountID'dir. Faturanın mantıksal anahtarı OrgName, AccountID, InvoiceNumber'dır.

    Yedek anahtarlar kullanıldığında, anahtar zincirler yalnızca ana ebeveyne yabancı bir anahtar kullanılarak kesilir. Örneğin, Fatura tablosunda bir OrgName sütunu yoktur. Yalnızca AccountID için bir sütunu vardır. Belirli bir kuruluşun faturalarını aramak istiyorsanız Kuruluş, Hesap ve Fatura tablolarına katılmanız gerekir. Mantıksal anahtarlar kullanırsanız, doğrudan Kuruluş tablosunu sorgulayabilirsiniz.

  5. Arama tablolarının yedek anahtar değerlerinin depolanması tabloların anlamsız tamsayılarla doldurulmasına neden olur. Verileri görüntülemek için, tüm arama tablolarına katılan karmaşık görünümler oluşturulmalıdır. Arama tablosu, bir sütun için kabul edilebilir değerler kümesini tutmak içindir. Bunun yerine bir tamsayı vekil anahtarı saklanarak kodlanmamalıdır. Normalleştirme kurallarında, değerin kendisi yerine bir tamsayı saklamanız gerektiğini öneren hiçbir şey yoktur.

  6. Üç farklı veritabanı kitabım var. Bunlardan hiçbiri yedek anahtarlar kullanarak göstermez.


7
Vekil anahtarlardan nefret ediyorum, ancak gerekli olmadıkları sürece. Kuruluş, çok fazla hataya maruz kalan doğal bir anahtar kullandığında ve bu hatalardan etkilenen bir veritabanını tolere etmek istemediğinde gereklidir.
Walter Mitty

26
-1: Düzinelerce başvuru yazdım ve sürdürdüm. Verilerle ilgili en fazla sorunu olanlar doğal anahtar kullananlardır.
Falcon

6
Bazı noktalarınız vekil anahtarın PK veya kümelenmiş sütun olması gerektiğini varsayar - doğru değil. 1 ve 5 puanlarınız, tamsayıların 4 bayt ve doğal anahtarların neredeyse her zaman çok, çok daha fazla bayt olduğu gerçeğini görmezden gelir. Kümelenmemiş her dizin, kümelenmiş dizindeki bu doğal anahtarların baytlarını yinelemelidir, böylece doğal anahtar veritabanınızdaki tablolar ve dizinler, sayfa başına çok daha az satır içerecek ve bu da çok daha kötü okuma performansına dönüşecektir. Bu, sorguları daha yavaş değil, daha yavaş hale getirir .
ErikE

3
Doğal anahtarlara karşı başka bir neden (örnekler: Atom Numaraları, VIN'ler, vb.), İş mantığı değişebilir ve bu da veri türünü artırır. Örneğin - Önce: Atomların ücretlerini izleme, Sonra: Atomların ve Bileşiklerin ücretlerini izleme. Önceki: Yük kapasitesi için Motorlu Araçların Takibi. Sonra: Yük taşıma kapasitesi için uçak, tekne, bisiklet ve insan eklenmesi.
forforf

3
Birincil anahtarın 1'den bile kısmen oluşturduğu herhangi bir tablonuz olmadığını tahmin ediyorum 1) değişebilecek ve değişecek herhangi bir özellik) veya 2) kullanıcı girişinden (örneğin dinamik olarak oluşturulan arama listeleri). Anahtar değişmezliğini garanti edemezseniz, tüm bu varlık ilişkilerini koda veya el ile "düzelt" komut dosyalarına göre güncellemeniz gerekir. Bunu hiç yapmak zorunda kalmadıysanız ... Sanırım veritabanınız hem anahtarsız hem de olağandışı ...
code4life

18

Bu sonsuz savaşta deneyimlerimi sizlerle paylaşmak istiyorum: Doğal ve yedek anahtar ikilemi üzerindeki D. Ben düşünüyorum hem vekil tuşları (yapay otomatik oluşturulan olanlar) ve (domain anlam sütun (s oluşan)) doğal tuşları var artıları ve eksileri . Durumunuza bağlı olarak, bir yöntem veya diğerini seçmek daha uygun olabilir.

Birçok insan vekil olarak neredeyse mükemmel çözüm ve doğal anahtarlar vekil anahtarlar sunarken, diğer bakış açısının argümanlarına odaklanacağım:

Yedek anahtarların dezavantajları

Yedek anahtarlar:

  1. Performans sorunlarının kaynağı:
    • Genellikle otomatik olarak artırılan sütunlar kullanılarak uygulanır:
      • Her yeni bir kimlik almak istediğinizde veritabanına gidiş-dönüş (bunun önbellek veya [seq] hilo algoritmaları kullanılarak geliştirilebileceğini biliyorum, ancak yine de bu yöntemlerin kendi dezavantajları var).
      • Bir gün verilerinizi bir şemadan diğerine taşımanız gerekiyorsa (En azından şirketimde oldukça düzenli olur) o zaman Kimlik çarpışma problemleriyle karşılaşabilirsiniz. Ve Evet, UUID'leri kullanabileceğinizi biliyorum, ancak bu süreler 32 onaltılık basamak gerektirir! (Veritabanı boyutunu önemsiyorsanız, bu bir sorun olabilir).
      • Tüm yedek anahtarlarınız için bir sıra kullanıyorsanız, o zaman - kesin olarak - veritabanınızda çekişme ile sonuçlanırsınız.
  2. Yüzüstü hata. Bir dizinin bir max_value sınırı vardır; bu nedenle - geliştirici olarak - aşağıdaki noktalara dikkat etmeniz gerekir:
    • Sekansınızı döngüye sokmanız gerekir (maksimum değere ulaşıldığında 1,2, ... 'e geri döner).
    • Sekansı verilerinizin sıralaması (zaman içinde) olarak kullanıyorsanız, döngü durumunu ele almanız gerekir (Id 1 ile sütun, Id max-değeri - 1 ile satırdan daha yeni olabilir).
    • Kodunuzun (ve dahili bir kimlik olması gerektiği gibi olmaması gereken istemci arayüzlerinizin) sıra değerlerinizi depolamak için kullandığınız 32b / 64b tamsayılarını desteklediğinden emin olun.
  3. Çoğaltılmamış verileri garanti etmezler. Her zaman aynı sütun değerlerine sahip ancak farklı bir oluşturulan değere sahip 2 satırınız olabilir. Benim için bu bir görüş veritabanı tasarımı açısından vekil anahtarların sorunu.
  4. Wikipedia'da daha fazlası ...

Doğal Anahtarlardaki Mitler

  1. Kompozit anahtarlar, yedek anahtarlardan daha az verimsizdir. Hayır! Kullanılan veritabanı motoruna bağlıdır:
  2. Doğal anahtarlar gerçek hayatta yoktur. Üzgünüm ama varlar! Örneğin, havacılık endüstrisinde, belirli bir tarifeli uçuş (havayolu, kalkış tarihi, uçuş numarası, operasyonelSuffix) için aşağıdaki grup her zaman benzersiz olacaktır . Daha genel olarak, bir dizi iş verisinin belirli bir standart tarafından benzersiz olduğu garanti edildiğinde bu veri seti [iyi] bir doğal anahtar adayıdır.
  3. Doğal anahtarlar çocuk masalarının "şemasını kirletir". Benim için bu gerçek bir problemden daha fazla bir duygu. Her biri 2 baytlık bir 4 anahtar birincil anahtarına sahip olmak, 11 baytlık tek bir sütundan daha verimli olabilir. Ayrıca, 4 sütun, üst tabloya katılmadan doğrudan alt tabloyu sorgulamak için (nerede yan tümcesinde 4 sütun kullanarak) kullanılabilir.

Sonuç

Alakalı olduğunda doğal anahtarlar kullanın ve bunları kullanmak daha iyi olduğunda yedek anahtarlar kullanın.

Umarım bu birisine yardımcı olmuştur!


3
Tarifeli uçuşun kalkış tarihi yeniden planlandığında ne olur? İlgili tüm varlıkları izlemeniz ve anahtarları silmeniz mi gerekiyor, yoksa ilgili varlıklardaki tüm anahtarları gerçekten güncelleştiriyor musunuz? Yoksa basit, tekil bir masa ile mi uğraşıyorsunuz (muhtemelen 3NF bile değil)?
code4life

Mükemmel nokta @ code4life
forcewill

@ code4life: Bu, işlevselSuffix'in atladığı yerdir. Aynı flightNumber'ı korumak için, istemci karışıklığını önlemek için sadece bir sonek ekleriz (örneğin 'D').
mwnsiri

"Her zaman aynı sütun değerlerine sahip ancak farklı bir oluşturulan değere sahip 2 satırınız olabilir", bu nedenle sütunlarınıza benzersiz veya bileşik benzersiz bir kısıtlama koymanız yeterlidir.
wha7ever

15

Her zaman ticari anlamı olmayan bir anahtar kullanın. Bu sadece iyi bir uygulama.

EDIT: Çevrimiçi bir bağlantı bulmaya çalışıyordum, ama yapamadım. Bununla birlikte, 'Kurumsal Mimari Desenleri' [Fowler] 'de, neden bir anahtar olmaktan başka bir anlamı olmayan bir anahtardan başka bir şey kullanmamanız gerektiği konusunda iyi bir açıklaması vardır. Sadece bir işi ve sadece bir işi olması gerektiği gerçeğine dayanır.


22
Martin Fowler birçok şey olabilir, ancak veritabanı tasarımında bir otorite değil.
Tony Andrews

Sonuca varmadan önce biraz akıl yürütmeniz gerektiğini düşünüyorum.
Arne Evertsson

4
@ArneEvertsoon Sebep orada. 'Sadece bir işi ve sadece bir işi olması gerçeğine dayanıyor.' Tek sorumluluk.
Iain Holder

10

Veri sınıflarınızı işlemek / oluşturmak için bir ORM aracı kullanmayı planlıyorsanız yedek anahtarlar oldukça kullanışlıdır. Bazı daha gelişmiş eşleyicilerle birlikte birleşik anahtarlar kullanabilirsiniz (read: hibernate), kodunuza biraz karmaşıklık katar.

(Tabii ki, veritabanı meraklıları bir yedek anahtar kavramının bile iğrenç olduğunu iddia edecektir.)

Ben uygun olduğunda vekil anahtarlar için uids kullanma hayranıyım. Onlarla kazanılan en büyük kazanç, anahtarı önceden bilmenizdir, örneğin, önceden tanımlanmış ve benzersiz olduğu garanti edilen kimliğe sahip bir sınıf örneği oluşturabilirsiniz, örneğin, bir tamsayı anahtarı ile varsayılan olarak 0 veya - 1 ve kaydettiğinizde / güncellediğinizde uygun bir değere güncelleyin.

UID'lerin arama ve katılma hızı açısından cezaları vardır, ancak bu, istenen olup olmadıklarına göre söz konusu uygulamaya bağlıdır.


6

Bir yedek anahtar kullanmak bence daha iyidir çünkü değişme şansı sıfırdır. Doğal bir anahtar olarak kullanabileceğiniz hemen hemen her şey değişebilir (sorumluluk reddi: her zaman doğru değil, ancak yaygın olarak).

Bir örnek araba DB'si olabilir - ilk bakışta, plakanın anahtar olarak kullanılabileceğini düşünebilirsiniz. Ancak bunlar değiştirilebilir, böylece bu kötü bir fikir olabilir. Birisi size plakalarını neden parlak yeni kişiselleştirilmiş olanına değiştiremediğini bilmek isteyen geldiğinde, uygulamayı bıraktıktan sonra bunu öğrenmek istemezsiniz .


1
Ne yazık ki arabaların değişmeyen doğal bir anahtarı var: VIN (en azından Amerika'da ...)
jcollum

@jcollum Evet tamam, bu adil bir nokta. Düşüncem yine de duruyor, örneğim olması gerektiği kadar iyi değildi.
Mark Embling

2
ISO kodlarına dayandırdığınızda, dillerin listesi doğal anahtarlara örnek olarak verilebilir. Bu nedenle, bir tablodan belirli bir dilde içerik yüklemek isterseniz languages, dil kodu (ID) zaten textstabloda olduğu için tabloya katılmanız gerekmez .
DanMan

@DanMan Orada seninle aynı fikirdeyim. Her zaman doğal bir anahtarla daha iyi çalışan bazı örnekler olacaktır. Kurallar veya ortak yaklaşımlar asla mutlak değildir ve bu bir örnek% 100 sizin yaklaşımınızla giderdim :-)
Mark Embling

5

Her zaman tek bir sütun kullanın, mümkünse anahtarı yedekleyin. Bu, ekleri / güncellemeleri / silmelerin yanı sıra eklemeleri çok daha temiz hale getirir, çünkü yalnızca kaydı korumak için tek bir bilgiyi izlemekle sorumlusunuz.

Ardından, gerektiğinde, işletme anahtarlarınızı benzersiz bir karşıtlık veya dizin olarak istifleyin. Bu, veri bütünlüğünü koruyacaktır.

İş mantığı / doğal anahtarlar değişebilir, ancak tablonun fiziksel anahtarı ASLA değişmemelidir.


4

Bir datawarehouse senaryosunda, vekil anahtar yolunu izlemenin daha iyi olduğuna inanıyorum. İki sebep:

  • Kaynak sistemden bağımsızsınız ve buradaki değişiklikler - veri türü değişikliği gibi - sizi etkilemez.
  • Yedek anahtarlarınız için yalnızca tamsayı veri türlerini kullanacağınız için DW'nizin daha az fiziksel alana ihtiyacı olacaktır. Ayrıca dizinleriniz daha iyi çalışır.

2

Yedek anahtarlar, işletme bilgileri değiştiğinde veya özdeş olduğunda yararlı olabilir. Sonuçta, işletme adlarının ülke genelinde benzersiz olması gerekmez. Biri Kansas'ta ve diğeri Michigan'da olmak üzere Smith Electronics adlı iki işletme ile uğraştığınızı varsayalım. Onları adrese göre ayırt edebilirsiniz, ancak bu değişecektir. Devlet bile değişebilir; Kansas City, Kansas'tan Smith Electronics nehir boyunca Kansas City, Missouri'ye taşınırsa? Bu işletmeleri doğal anahtar bilgilerden ayrı tutmanın belirgin bir yolu yoktur, bu nedenle yedek anahtar çok yararlıdır.

Yedek anahtarı bir ISBN numarası gibi düşünün. Genellikle, bir kitabı başlığa ve yazara göre tanımlarsınız. Ancak, HP Willmott tarafından "Pearl Harbor" başlıklı iki kitabım var ve bunlar sadece farklı sürümler değil, kesinlikle farklı kitaplar. Böyle bir durumda, kitapların görünüşüne veya daha öncekine karşı kitaplara atıfta bulunabilirim, ancak geri çekilmem için ISBN de var.


1
Sanırım buradaki örneğinize katılmıyorum. ISBN numarası bir kitabın özelliğidir. Bir yedek anahtar, satır verilerinin geri kalanından bağımsızdır, bu nedenle ISBN zaten her kitabı benzersiz olarak tanımlasa da, bu konum bir kitap tablosu için ayrı bir yedek anahtar kullanarak savunur.
Christopher Cashell

Alternatif olarak, ISBN'yi yedek anahtar olarak düşünün. Anlamsız bir tanımlayıcıdır, sadece belirli bir kitaba uygulanan bir koddur. Bir kitap tablosu yapıyorsanız, ISBN de birincil anahtar olabilir (her satırda bir kitabınız olduğunu ve her zaman bir kitabınız olacağını varsayarsak).
David Thornley

@Christopher Cashell - Bir yıl önce bu gönderiye rastladım ama bir şeyler eklemeyi düşündüm. ISBN'lerin benzersiz olduğu garanti edilmez ve kopyaları olabilir. Birkaç yıl boyunca bir kütüphanede çalışan bir arkadaşım var ve genellikle yinelenen ISBN'lere sahip kitaplarla karşılaştılar. Sorun, ISBN'nin benzersizliğinin, tüm yayınlar için tüm sayıların olmasını sağlayan tek bir gövde yerine yayıncıda görevlendirilmesidir. benzersizdir ve bu yayıncıların her zaman birlikte hareketleri yoktur.
Thomas

2
Bir yıl önce bu yazıyla karşılaştım ve ISBN'nin aslında doğal anahtarlar olduğunu belirtmek istedim. Bir vekil anahtardan farklı olarak, anahtar değerin kendisinde pişmiş bir anlam vardır. Örneğin, anahtarın bir kısmı yayıncıyı tanımlar. Ayrıca, yukarıda belirttiğim gibi, benzersiz oldukları garanti edilmez. Benzersiz olmaları gerekiyordu , ancak bu benzersizlik yayıncılardan geliyor ve her zaman mükemmel değildi.
Thomas

Teknik olarak şirketler devletler arasında hareket edemezler; olan şey yeni eyalette yeni bir şirket yaratılması ve varlıkların devredilmesidir. Bu veritabanı bilgileri için de geçerlidir.
Warren Dew

2

Bir hatırlatma olarak, kümelenmiş indeksleri rasgele vekil anahtarlara yerleştirmek iyi bir uygulama değildir, yani SQL Server'ın bu verileri fiziksel olarak sıralayama yeteneği olmadığı için XY8D7-DFD8S'yi okuyan GUID'ler. Bunun yerine, bu tablolara benzersiz indeksler yerleştirmelisiniz, ancak ana tablo işlemleri için SQL profiler çalıştırmak ve daha sonra bu verileri Veritabanı Altyapısı Ayarlama Danışmanına yerleştirmek de yararlı olabilir.

Bkz. Konu @ http://social.msdn.microsoft.com/Forums/en-us/sqlgetstarted/thread/27bd9c77-ec31-44f1-ab7f-bd2cb13129be


Ben SQL Server eminim olabilir GUID'lerini sıralamak.
Michael Green

Bu doğru değildir, ancak GUID'i değerlendirebilirken, ortaya çıkan sıralama bir insan için saçma değildir. stackoverflow.com/questions/7810602/…
Bryan Swan

1
Gerçek bir ifade, ancak "SQL Server fiziksel olarak bunları sıralamak için hiçbir yeteneği" oldukça farklı.
Michael Green

2

Durum 1: Tablonuz,50'den az türü (araya ekleme) içerenbir arama tablosu

Kullanım iş / doğal tuşları . Örneğin:

Table: JOB with 50 inserts
CODE (primary key)       NAME               DESCRIPTION
PRG                      PROGRAMMER         A programmer is writing code
MNG                      MANAGER            A manager is doing whatever
CLN                      CLEANER            A cleaner cleans
...............
joined with
Table: PEOPLE with 100000 inserts

foreign key JOBCODE in table PEOPLE
looks at
primary key CODE in table JOB

Durum 2: Tablonuz binlerce ek içeren bir tablodur

Kullanım vekil / autoincrement tuşları . Örneğin:

Table: ASSIGNMENT with 1000000 inserts
joined with
Table: PEOPLE with 100000 inserts

foreign key PEOPLEID in table ASSIGNMENT
looks at
primary key ID in table PEOPLE (autoincrement)

İlk durumda:

  • Tablo PEOPLE içindeki tüm programcıları JOB tablosu ile birleştirme kullanmadan seçebilirsiniz, ancak yalnızca "SELECT * FOP PEOPLE WOBE WOBE = 'PRG" "

İkinci durumda:

  • Birincil anahtarınız bir tamsayı olduğu için veritabanı sorgularınız daha hızlı
  • Bir sonraki benzersiz anahtarı bulmakla uğraşmanıza gerek yok çünkü veritabanının kendisi size bir sonraki otomatik baskıyı sağlıyor.

2

Bu, bir yedek anahtarın hemen hemen her zaman mantıklı olduğu durumlardan biridir . Veritabanı için en iyi olanı veya nesne modeliniz için en iyisini seçebileceğiniz durumlar vardır, ancak her iki durumda da anlamsız bir anahtar veya GUID kullanmak daha iyi bir fikirdir. İndekslemeyi daha kolay ve daha hızlı hale getirir ve nesneniz için değişmeyen bir kimliktir.


1

Atlar için kurslar. Önyargımı belirtmek için; Öncelikle geliştiriciyim, bu yüzden esas olarak kullanıcılara çalışan bir uygulama sunmakla ilgileniyorum.

Doğal anahtarlı sistemler üzerinde çalıştım ve değer değişikliklerinin dalgalanacağından emin olmak için çok zaman harcadım.

Yalnızca yedek anahtarları olan sistemler üzerinde çalıştım ve tek dezavantajı, bölümleme için denormalize veri eksikliği oldu.

Birlikte çalıştığım çoğu geleneksel PL / SQL geliştiricisi, katılım başına tablo sayısı nedeniyle yedek anahtarları beğenmedi, ancak test ve üretim veritabanlarımız asla ter atmadı; fazladan birleşimler uygulama performansını etkilemedi. "Xa = Yb'de X iç birleşimi Y" gibi yan tümceleri desteklemeyen veritabanı lehçeleri veya bu sözdizimini kullanmayan geliştiricilerle, yedek anahtarlar için ek birleşimler sorguların okunmasını zorlaştırır ve kontrol edin: @Tony Andrews gönderisine bakın. Ancak bir ORM veya başka bir SQL oluşturma çerçevesi kullanıyorsanız bunu fark etmeyeceksiniz. Dokunarak yazma da hafifletir.


Ayrıca; vekil anahtarların tam da bu şekilde olduğunu eve götürmek istiyorsanız, bunları rasgele büyük bir sayıyla başlatın ve sekansları 1 yerine 3+ artırın. Veya birden fazla anahtar için değer üretmek üzere aynı sırayı kullanın.
WillC

1

Belki bu konuyla tamamen ilgili değil, yedek anahtarlarla uğraştığım bir baş ağrısı. Oracle önceden teslim edilen analitik, depodaki tüm boyut tablolarında otomatik olarak oluşturulan SK'ları oluşturur ve bunları gerçekler üzerine depolar. Bu nedenle, yeni sütunlar eklendikçe veya boyuttaki tüm öğeler için doldurulmaları gerektiğinde (boyutlar) yeniden yüklenmeleri gerektiğinde, güncelleme sırasında atanan SK'ler SK'ları gerçeğe depolanan orijinal değerlerle senkronize etmez, zorlar ona katılan tüm olgu tablolarının tam olarak yeniden yüklenmesi. SK anlamsız bir sayı olsa bile, orijinal / eski kayıtlar için değişememesinin bir yolu olacağını tercih ederim. Birçoğunun bildiği gibi, kutunun dışında nadiren bir kuruluşun ihtiyaçlarına hizmet eder ve sürekli olarak özelleştirmemiz gerekir. Şimdi depomuzda 3 yıl değerinde veri var, ve Oracle Financial sistemlerinden tam yeniden yükleme çok büyük. Yani benim durumumda, veri girişinden üretilmiyorlar, ancak performans raporlamasına yardımcı olmak için bir depoya ekleniyorlar. Anlıyorum, ama bizimki değişiyor ve bu bir kabus.


0

Zaman içinde veritabanı durumunda, vekil ve doğal anahtarların kombinasyonuna sahip olmak en iyisidir. örneğin bir kulübe üye bilgilerini izlemeniz gerekir. Bir üyenin bazı özellikleri hiçbir zaman değişmez. Örneğin Doğum Tarihi ancak adı değişebilir. Bu nedenle, member_id yedek anahtarıyla bir Üye tablosu oluşturun ve DOB için bir sütununuz olsun. Kişi adı adlı başka bir tablo oluşturun ve member_id, member_fname, member_lname, date_updated için sütunlara sahip olun. Bu tabloda doğal anahtar member_id + date_updated olacaktır.

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.