Bu özel tabloların yedek anahtarlara ihtiyacı var mı?


13

Arka fon

Bu tablolarım var

+-------------------------+  +------------------------+
|Airport                  |  |Country                 |
|-------------------------|  |------------------------|
|airport_code string (PK) |  |country_code string (PK)|
|address string           |  |name string             |
|name  string             |  +------------------------+
+-------------------------+

+-------------------------+
|Currency                 |
|-------------------------|
|currency_code string (PK)|
|name string              |
+-------------------------+

AIRPORT_CODE olan IATA (Uluslararası Hava Taşımacılığı Birliği) havaalanı kodu size uçakla seyahat ederken bagajınızı etiketleri görebilirsiniz.

resim açıklamasını buraya girin

COUNTRY_CODE olan ISO 3166-1 A3 standart ülke kodu size Olimpiyatları bunları görebilirsiniz.

resim açıklamasını buraya girin

currency_code , IS0 417 standart 3 karakterli para birimi kodudur , bunları uluslararası para birimi ekran kartlarında görebilirsiniz.

resim açıklamasını buraya girin

Sorular

Bu doğal PK'lar yeterince iyi mi?

Tüm endüstriler tarafından kabul edilen dünyaca tanınan standartları kullanmak PK'lar için yeterince iyi mi?

Bu tabloların ne olursa olsun taşıyıcılara ihtiyacı var mı?

Yanıtlar:


15

Hayır. Bu anahtarlar kesinlikle yeterince iyi!

Bunlar, eşsiz olduğu değil nadiren değişikliğe gidiyor ve anlamlı bir vekil anahtarı üzerinde bir adım olan. Bu iyi bir PK'nin tanımıdır.

Değiştirilemeyen ve sayısal tamsayı olan PK'larla ilgili kısıtlamalar İlişkisel Modelin (Codd'lar) veya herhangi bir SQL standardının (ANSI veya diğer) bir parçası değildir.


3
Birincil anahtarlar da değişmez olmalı, IATA havaalanı kodları kesinlikle değil. Bunlar IATA'nın kapısında değiştirilebilir.
James Snell

3
@JamesSnell - IATA havaalanı kodları yaklaşık olarak ülke kodları kadar değişmezdir. Belki on yılda bir değişiklikten bahsediyorsunuz . Konuyla ilgili bir tartışma için buraya bakın . Değiştirmek için çok fazla sorun olduğu için hala yürürlükte olan çok sayıda eski kod var. Ayrıca, bir CASCADE güncellemesi bunun içindir. Değişken birincil anahtarlar, büyük uygulama olmasa bile meşrudur.
Bobson

2
@EricKing Bu 3. taraf, birçok endüstrinin tüm büyük partilerinin temsilcilerinden oluşuyor, daha sonra standartlar yıllarca tartışılıyor, daha sonra makul bir fikir birliğine varılana kadar oylanıyor. Ayrıca, herhangi bir değişiklik veya yeni ekleme yapılan mekanizmalar üzerinde anlaşırlar. Bunun yanı sıra, kod listeleri standartları bir kapris üzerinde değil, dünya çapında birlikte çalışabilmek ve dünya çapında düzgün bir şekilde iletişim kurabilmek için bir şey için kontrollü, saygı duyulan, üzerinde anlaşmaya varılan bir kod listesi oluşturma ihtiyacı olduğu için oluşturulur.
Tulains Córdova

2
@ user61852 - Bu standartların birincil anahtarlar olarak yapıldığını söyleyebilirsiniz .
Bobson

3
@Bobson: "Değiştirmek için çok fazla sorun olduğu için hala mevcut olan çok sayıda eski kod var" -> muhtemelen birincil anahtarlar oldukları için mi?
Maciej

2

Sanırım ihtiyaç çok güçlü bir kelime ve katı bir anlamda, tabloların muhtemelen yedek anahtarlara ihtiyacı yoktur .

Ancak, veritabanım olsaydı, muhtemelen yedek anahtarları eklerdim. Veritabanı tasarımımın, standartlarının ne kadar kararlı olduğuna bakılmaksızın, bir grup üçüncü tarafa (IATA, ISO) bağlı olmasını istemeyebilirim. Veya, belirli bir standarda hiç bağlı kalmak istemeyebilirim (başka para birimi kodu standartları var mı? Bilmiyorum). Muhtemelen benim gibi vekil anahtarları ile tablolarım model:

+-------------------------+  +------------------------+
|Airport                  |  |Country                 |
|-------------------------|  |------------------------|
|airport_id       int (PK)|  |country_id     int (PK) |
|iata_airport_code string |  |iso_country_code string |
|icao_airport_code string |  +------------------------+
|faa_identifier    string |  
|address           string |  
|name              string |  
+-------------------------+

+-------------------------+
|Currency                 |
|-------------------------|
|currency_id int (PK)     |
|iso_currency_code string |
|name string              |
+-------------------------+

Diğer bir deyişle, bu endüstri standardı kodları benim başvurumda doğal olarak önemli olmadıkça , bunları tablolarımın PK'si olarak kullanmam. Onlar sadece etiketler. Diğer tablolarımın çoğunda zaten yedek anahtarlar olacak ve bu kurulum veri modelime tutarlılık katacaktır. Yedek anahtarları 'ekleme' maliyeti minimumdur.

Bazı yorumlara göre güncelleme:

Örnek tabloların bağlamını bilmeden, IATA Havaalanı Kodları gibi şeylerin veritabanını kullanarak uygulamaya ne kadar önemli olduğunu bilmek imkansızdır. Açıkçası, IATA kodları uygulama için merkezi olarak önemliyse ve yaygın olarak kullanılıyorsa, uygun analizden sonra kodları tablonun PK'si olarak kullanmak doğru karar olabilir.

Ancak, tablo yalnızca uygulamanın birkaç köşesinde kullanılan bir arama tablosu ise, IATA kodlarının göreceli önemi veritabanı altyapısında bu kadar önemli bir noktayı haklı göstermeyebilir. Elbette, burada ve orada birkaç sorguda ek birleştirme yapmanız gerekebilir, ancak bu çaba, IATA kodlarını yapma birincil anahtar alanı. Bazı durumlarda, sadece umurumda değil, aynı zamanda IATA kodları ile ilgilenmek de istemiyorum . @James Snell'in aşağıdaki yorumu, tablolarımın PK'sini etkilemek konusunda endişelenmek istemeyeceğim bir şeyin mükemmel bir örneğidir.

Ayrıca, tasarımda tutarlılık önemlidir. Tamamı tutarlı şekilde tasarlanmış yedek anahtarlar içeren düzinelerce tablo içeren bir veritabanınız ve ardından PK olarak üçüncü taraf kodlarını kullanan ve tutarsızlık getiren birkaç arama tablosu varsa. Bu tamamen kötü değil, ancak belgeleme ve garanti edilmeyebilecek ekstra dikkat gerektirir. Onlar iyilik uğruna arama tabloları , sadece tutarlılık için bir vekil anahtar kullanmak mükemmel para cezası.

Daha fazla araştırmaya dayalı güncelleme:

Tamam, merak beni ısırdı ve ben soruda verilen bağlantılardan başlayarak eğlence için IATA havaalanı kodları üzerinde biraz araştırma yapmaya karar verdim.

Anlaşıldığı üzere, IATA kodları, soru ortaya çıktığı kadar evrensel ve otoriter değildir. Bu sayfaya göre :

Çoğu ülke resmi havacılık yayınlarında IATA kodları yerine dört karakterli ICAO kodları kullanır .

Ayrıca, IATA kodları ve ICAO kodları, hava alanlarını tanımlamanın başka bir yolu olan FAA Tanımlayıcı kodlarından farklıdır .

Bunları ortaya çıkarmamdaki amacım, hangi kodların daha iyi veya daha evrensel veya daha yetkili veya daha kapsamlı olduğu hakkında bir tartışma başlatmak değil, veritabanı yapınızı neden rastgele bir 3. taraf tanımlayıcı etrafında tasarlamanın tam olarak yapmayı tercih ettiğim bir şey olmadığını göstermek. , bunun için belirli bir iş nedeni olmadıkça .

Bu durumda, veritabanımın birincil anahtar adayı olarak IATA kodlarını (veya herhangi bir üçüncü taraf, potansiyel olarak değiştirilebilir kodu) geçirerek ve yedek anahtar kullanarak daha iyi yapılandırılmış, daha kararlı ve daha esnek olacağını hissediyorum . Bunu yaparak, birincil anahtar seçimi nedeniyle ortaya çıkabilecek potansiyel tuzaklardan vazgeçebilirim.


1
Yani IATA standartları havayolları için yeterince iyi, ama sizin için değil mi?
Tulains Córdova

1
Tabii ki Londra Heathrow'dan bagaj aramak istediğinizde havaalanı masasına kadar tüm yollara katılmak zorunda kalacaksınız, çünkü yapamazsınız select * from baggage where airport_code = 'LHR', yani veritabanı sadece kullanılabilir, çok dar ve tescilli bir uygulama atın yaklaşım, özellikle işletme sahibi veritabanı için ödeme yapan ve bu nedenle sahibi olduğu zaman. Ayrıca PK çakışmalarını önlemek için bir veritabanından diğerine veri aktarmak gibi sıradan şeyler yapmak için kod yazmanız gerekecektir.
Tulains Córdova

1
IATA kodları değiştirilemez, bu nedenle PK adayı olarak kabul edilemezler. Örnek: IDL kodu, JFK olarak yeniden adlandırılana kadar New York'taydı. IDL kodu şimdi Mississippi'de.
James Snell

2
@EricKing IATA ve ISO, kodların yeterince kararlı, benzersiz ve evrensel olarak kabul edilmesini önemser. Bu, bir masa tasarlayan bir kişinin ilgisiyle çok örtüşüyor.
Tulains Córdova

2
@ user61852 - bunların standart kodlar olması, havayolu sisteminin bunları PK olarak kullandığı anlamına gelmez (belki burada daha fazla bilginiz var mı?). Bu kadar büyük ölçekte basamaklı bir güncellemeye sahip olmak çok kötü bir fikir gibi görünüyor.
JeffO

1

Alanlarda vekil anahtarlara sahip olmak iyi ve dikkate alınması gereken bir şey, dizin sayfası boyutunun kendisi olabilir.

Bu ilişkisel bir veritabanı olduğundan, çok fazla birleştirme yapacaksınız ve sayısal bir türden bir yedek anahtara sahip olmak veritabanında işlem yapmayı kolaylaştırabilir, yani dizin sayfası boyutu daha küçük olacak ve arama için daha hızlı olacaktır. Bu küçük bir projeyse, önemli olmayacak ve herhangi bir sorun yaşamayacaksınız, ancak uygulama büyüdükçe darboğazları azaltmak isteyeceksiniz.

Bir BIGINT, INT, SMALLINT, TINYINT veya tamsayıya benzer bir veri türüne sahip olmak, yolda bazı sorunlardan kurtarabilir.

Sadece 2 sentim

GÜNCELLEME:

Küçük proje - birkaç, hatta birkaç düzine insan tarafından kullanılır. Küçük ölçekli, demo projesi, kişisel kullanım projesi, deneyimsiz deneyiminizi sunarken bir portföye eklenecek bir şey ve benzeri.

Büyük proje - günde binlerce, on binlerce, milyonlarca kullanıcı tarafından kullanılır. Büyük bir kullanıcı tabanına sahip ulusal / uluslararası bir şirket için inşa edeceğiniz bir şey.

Genellikle ne olur, birkaç kayıt sık sık seçilir ve sunucu sonuçları hızlı erişim için önbelleğe alır, ancak her seferinde daha az kullanılan bazı kayıtlara erişmeniz gerekir, bu noktada sunucunun dizine daldırılması gerekir sayfa. (yukarıdaki örnekte havaalanı isimleriyle, insanlar sıklıkla iç havayolları uçuyor, Chichago -> Los Angeles diyorlar, ancak insanlar Boston'dan -> Zimbabve'den ne sıklıkla uçuyor)

VARCHAR kullanılırsa, veriler her zaman aynı uzunlukta değilse (hangi noktada bir CHAR değeri daha etkilidir) bu, aralıkların eşit olmadığı anlamına gelir. Bu, dizinde aramayı yavaşlatır ve sunucu zaten saniyede binlerce ve binlerce sorguyu işlemekle meşgulken, tekdüze olmayan bir dizine gidip zaman kaybetmek zorunda kalır ve aynı şeyi tekrar birleştirme işlemlerinde (daha yavaştır) optimize edilmemiş bir tablodaki düzenli seçimler için DW'yi veri alımını hızlandırmak için mümkün olduğunca az birleşimin olduğu örnek olarak alın). Ayrıca veritabanı motoru ile karışıklık olabilir UTF kullanırsanız (bazı durumlarda gördüm).

Kişisel olarak, kendi tecrübelerime göre, düzgün bir şekilde organize edilmiş bir dizin birleştirme hızını ~% 70 oranında artırabilir ve bir tamsayı sütununda bir birleştirme yapmak birleşmeyi yaklaşık% 25 kadar hızlandırabilir (verilere bağlı olarak) . Ana tablolar büyümeye başladıkça ve bu tablolar bunlara alıştıkça, birkaç bayt içeren sütunu işgal etmek yerine daha fazla yer kaplayacak bir VARCHAR / CHAR alanı olan bir tamsayı veri türüne sahip olmayı tercih eder misiniz. Disk alanından tasarruf etmek, performansı ve ilişkisel bir veritabanının genel yapısını arttırmak söz konusudur.

Ayrıca, James Snell'in belirttiği gibi:

Birincil anahtarlar da değişmez olmalı, IATA havaalanı kodları kesinlikle değil. Bunlar IATA'nın kapısında değiştirilebilir.

Bunu göz önünde bulundurarak, bir sayıya bağlı 1 kaydı güncellemek mi istiyorsunuz, yoksa o kaydı artı katıldığınız tablodaki tüm kayıtları güncellemek zorundasınız.


Bu geçerli bir düşünce, ancak bu tabloların amacı her tabloda sadece sınırlı sayıda kayıt bulunmasıdır. Aslında kod boyutunu small projectve ile kastediyorsanız bigger, bunun neden önemli olduğunu açıklığa kavuşturmak için lütfen güncelleyin.
Bobson

1
Değiştirilemeyen ve sayısal tamsayı olan PK'larla ilgili kısıtlamalar İlişkisel Modelin (Codd'lar) veya herhangi bir SQL standardının (ANSI veya diğer) bir parçası değildir.
Tulains Córdova

4
Sabit uzunluğa, kısa dizelere (ISO kodları gibi) dayalı dizinler tamsayılar kadar hızlıdır. Değişken uzunluğa dayalı dizinler, uzun dizeler değildir.
Tulains Córdova

Belirttiğim budur (yukarıdaki VARCHAR vs CHAR kısmına bakın), sabit bir uzunluk kısa dizesini sayısal bir tamsayıya karşı test etme şansım olmadı, ancak değişken bir uzunluk ve bir tamsayı ile bunu yapma şansım oldu
Toni Kostelac

2
Üyelik performansı saman adam. Genellikle, doğal anahtarları kullanmak, ilk etapta birleştirmeye ihtiyacınız olmadığı anlamına gelir.
Mike Sherrill 'Cat Recall'

1

"Daima yedek anahtarları kullanıyorum" yaklaşımını kullanırsanız, bu tür endişeleri atlayabilirsiniz. Bu iyi bir şey olmayabilir, çünkü verilerinize biraz düşünmek önemlidir, ancak kesinlikle çok fazla zaman, enerji ve çaba tasarrufu sağlar. Eğer herhangi biri bu kurala kabul ederse, listelenen örnekler kesinlikle yeterlidir çünkü değişikliği yapmak için yakın bir "kongre eylemi" gerekir.

Bu doğal anahtarlara sahip bir veritabanının geçici sorguları kesinlikle yararlıdır. Arama tablolarını ekleyerek aynı şeyi yapan görünümler oluşturmak da işe yarayabilir. Modern veritabanları, muhtemelen önemli olmadığı noktaya kadar bu tür şeyler ile çok daha iyi bir iş çıkarır.

Standartların büyük ölçüde değiştirildiği ABD'ye özgü bazı durumlar vardır: Posta kodu 5 - 9 basamaktan genişledi, Eyalet kısaltmaları tutarlı bir 2 harfe yükseldi ve dönemden kurtuldu (Illinois ne zaman hasta olduğunu hatırla) ve çoğu dünya Y2K ile uğraştı. Milyarlarca kayıt içeren tüm dünyaya yayılmış veri içeren gerçek zamanlı bir uygulamanız varsa, basamaklı güncellemeler en iyi fikir değildir, ancak hepimiz bu tür zorluklarla karşılaşan yerlerde çalışmamalıyız? Bu veri kümesiyle, kendiniz için test edebilir ve daha farklı bir cevap verebilirsiniz.


+1 Harika cevap. Çoğu zaman insanlar bu konuda çok dogmatiktir. Birçok veritabanı tasarımcısının dev bir egosu vardır ve kendilerini veritabanının ve verilerin sahibi olarak görürler. Diğerleri, veri sahibinin verileri yalnızca belirli bir uygulama aracılığıyla kullanabileceğini, çünkü anlamlandıramayacağını düşünüyor. Ayrıca, veri alma ve sorgu yazma gibi günlük olarak yapılan şeylerin canlı bir cehennemini yaparken gelecekte olabilecek veya olmayabilecek bir şey için hükümler hazırlamayı tercih ederler. Ayrıca görüşlerini destekleyen her türlü kanonik bibliyografya üretememek.
Tulains Córdova

Bu arada, "Yedek anahtarları her zaman kullanıyorum" kuralı İlişkisel Modelde (Codd) veya herhangi bir SQL standardında değildir. Oracle veri sözlüğü şeması mümkün olduğunda doğal anahtarlar ve diğer durumlarda yapay anahtarlar kullanır. PPDM ( ppdm.org ) ayrıca karma yaklaşımı tavsiye eder ve modelinde kullanır. ANSI SQL Standardı, tüm suretler hakkında hiçbir şey söylemez. Bence tüm suretler ve doğal olanlar aşındırıcıdır. Bazı doğal ve bazı vekil ilişkisel modelin öğrettiği şeydir.
Tulains Córdova
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.