Normalleştirme: Bir yıl gibi statik, sayısal değerleri kendi tablolarına ayırmak uygun mu?


16

Başka bir veritabanı tasarımcısı ile normalizasyon hakkında ilginç bir tartışma yaşıyorum. Bu örnekte, bir GameTitles masamız var ve her kayıt oyunun piyasaya sürüldüğü yılı içermelidir. 2NF'nin her şeyin normalleştirilmesi gerektiğini zorunlu kıldığını, bu nedenle uyumlu olması için yıl alanının GameTitles tablosu tarafından referans verilen kendi birincil anahtarıyla bir ReleaseYears tablosuna bölünmesi gerektiğini söylüyor. GameTitles tablosunda bir alan olarak kalması gerektiğini söylüyorum.

Bunun benim argümanım, bir yılın sadece doğası gereği statik olan ilkel olmayan bir sayısal değer olmasıdır (yani, 2011 her zaman 2011 olacaktır). Bu nedenle, kendi tanımlayıcısı olarak hizmet eder ve olduğu gibi referans olması için hiçbir şeye ihtiyaç duymaz. Bu da ek bakım sağlar, çünkü şimdi sadece referans için tabloya yeni bir yıl eklemeniz gerekir. Tabloyu geniş bir yelpazeyle önceden doldurursanız, potansiyel olarak bunlara referansları olmayacak ekstra kayıtlarınız vardır. Bu, artık ekstra bir tablonuz, kayıt ek yükünüz ve yılın kendisi için ek birincil anahtarınız olduğu için veritabanı boyutunu da artırır. Yılı GameTitles tablosunda bir alan olarak tutarsanız, tüm bu ek bakım ve ek yükü ortadan kaldırmış olursunuz.

Bunun üzerine düşünceler?

edit: Bunu StackOverflow'a göndermek istedim. Birisi bunu silmek için oy kullanabilir veya dikkat çekmek için işaretleyebilir mi?


6
Neden öyle? burada iyi bir uyum gibi görünüyor.
Leigh Riffel

Sormak istediğim soru, bunu normalleştirme veya gerçek üretim ihtiyaçları hakkında mı soruyorsunuz? Üretim için bunun geçerli bir şey olup olmadığını sorardım.
jcolebrand

Yanıtlar:


14

Diğer veritabanı tasarımcısı sadece yanlış, ancak mantığınız da yanlış. Tek bir aday anahtarı olan "game_title" olan bu tabloyla başladığınızı varsayın.

Table: game_titles

game_title                      year_first_released
--
The first game                  1998
The second game                 1999
Best game: the third one        2001
The fourth game                 2003
Forty-two, the end of games     2011

Kendinize bu soruları sorarak 2NF'de olup olmadığını değerlendiriyorsunuz.

S: Her şeyden önce, 1NF'de mi?

C: Evet, öyle.

S: Asal özellikler (aday anahtarın parçası olan özellikler) nelerdir?

C: "game_title" tek ana özelliktir.

S: Asal olmayan özellikler nelerdir?

C: "year_first_released" yalnızca.

S: "year_first_released" işlevsel olarak "game_title" nin tamamına mı yoksa sadece bir kısmına mı bağlı?

C: Tek aday anahtar "game_title" tek bir sütundur; parçaları bile yok. Dolayısıyla "year_first_released" işlevsel olarak "game_title" in tamamına bağlıdır.

Voilà. 2NF buldunuz.

Resmi terimlerin bazılarını önce 1NF'de olup olmadığını sorarak ve ardından bu soruyu cevaplayarak kesebilirsiniz.

S: Kompozit aday anahtarlar var mı?

C: Hayır.

Voilà. Yine 2NF buldunuz.

Tanım olarak, bir tablonun 2NF'yi ihlal etmesi için birden fazla sütunu olan en az bir aday anahtarına sahip olması gerekir.

İşte arkadaşınızın fikrini reddetme nedenleriniz.

  • Bir yıl sadece ilkel olmayan sayısal bir değerdir.
  • Bir yıl doğası gereği durağandır.
  • Bir yıl kendi tanımlayıcısı olarak hizmet eder.
  • Bir yıllık tablo ek bakım sağlar.
  • Yıllar tablosunda referans verilmeyen fazladan satırlar olabilir.
  • Yıllar tablosu veritabanı boyutunu artırır.

Bu nedenlerin hiçbirinin bir tablonun 2NF'de olup olmadığıyla hiçbir ilgisi yoktur.

Bir veritabanı tasarlarken, bakım sorunlarını, veritabanı boyutunu, referanslandırılmamış satırları, aralık kısıtlamalarını vb. Dikkate almak yanlış değildir. Bu şeylere normalleşme demek yanlış.

Oh, ve yukarıda verdiğim iki sütunlu tablo - 5NF'de.


2
Güzel yapılmış. İlk cümlenizden başka bir şey söylemeyen bir cevap yayınlamak istedim ... "Diğer veritabanı tasarımcısı basitçe yanlış", nedenini çok iyi ele aldınız.
Mark Storey-Smith

5

Herhangi bir özellik için ayrı bir tablo oluşturmanın normalleştirmeyle ilgisi yoktur. 2NF, 3NF, BCNF, 4NF, 5NF, anahtar olmayan bağımlılıkların ortadan kaldırılmasıyla ilgilidir. Yeni bir tablodaki herhangi bir tek özniteliği kaldırır ve bunu bir yabancı anahtar özniteliğiyle değiştirirseniz, tablodaki bağımlılıklar mantıksal olarak eskisiyle aynı olur - dolayısıyla tablonun gözden geçirilmiş sürümü, tablodan daha fazla veya daha az normalleştirilmez. önceydi.


Buna bir şey eklemek istiyorum , ama ne olduğundan emin değilim. Bir şeye 1: 1 korelasyonu olan bir tabloya (bu durumda olduğu gibi 1 anahtarın tam olarak 1 değere veya bir satırdan bir satıra) taşınmasının, arama gerekmiyorsa fayda sağlamadığını söylüyorsunuz, değil mi? Ancak, yıla nadiren ihtiyacınız varsa ve sadece 255 yıl veya daha az bir aralığa bakıyorsanız potansiyel bir arama avantajı vardır. Burada kaydedilen birkaç baytla muhtemelen kaçabilirsiniz, ancak normalde bunlar yine de 4baytta tahsis edildiğinden, bu makul bir varsayım değildir.
jcolebrand

1
@jcolebrand: Söylediklerinle aynı fikirde. Yine de sorunun cevabı aynıdır: bunu yapıp yapmadığınızın normalleştirme ile ilgisi yoktur.
nvogel

Hemfikirim. Dediğim gibi, benimki "OP'nin burada bir şey eksik olduğunu hissediyorum" gibi yarı yürekli bir soruydu ... çünkü bu konsepte nereye gideceğinden emin değilim.
jcolebrand

5

Benim açımdan, ayrı bir yıl tablosu yalnızca "yayın yılı" bir takvim yılı değil, örneğin birden çok takvim yılına yayılabilecek bir mali yıl (örn. Ekimden ekime kadar) ise anlamlı olur.

Bu tablo daha sonra mali yılın tanımını (gerçek başlangıç ​​ve bitiş tarihi) tutacaktır.


1
+1, sadece nitelikleri olacak bir tabloya ihtiyacınız var :)
Jack diyor denemek topanswers.xyz

2

Gönderen http://en.wikipedia.org/wiki/Second_normal_form :

bir 1NF tablosu, ancak herhangi bir aday anahtar K ve bir aday anahtarın bileşeni olmayan herhangi bir A özelliği göz önüne alındığında, A'nın sadece bir parçası olmaktan ziyade K'nın tamamına bağlı olması durumunda 2NF'de bulunur.

Yılın aday anahtarın bir parçası olup olmadığını belirtmediniz, ama önemli olduğundan emin değilim, çünkü her iki durumda da 2NF yıl söz konusu olduğunda tatmin olur.

Pratik düzeyde, listelediğiniz tüm nedenlerden dolayı yılı ayırmak kötü bir fikirdir.


2

Boyutu nedeniyle ya da kullanılmayan satırları olacak ayrı tabloya karşı argüman sevmiyorum. Bu masaya 1000 yıl koymuş olsanız bile, boyut ihmal edilebilir.

Yani, masanın hiç gerekli olduğunu düşünmüyorum. Yıl için ayrı bir masaya sahip olmanın anlamı nedir? Bu veriler zaten ana tablodadır ve ikinci bir tablo oluşturarak kesinlikle hiçbir şey kaydetmezsiniz.

Argüman, her satırın bir günü temsil ettiği ve başka niteliklere (haftanın günü, UTC ofseti, tatil olsun, vb.) Sahip olduğu bir takvim tablosu için farklı olabilir.

Ama yalnız mı? Hayır, hiç fayda görmüyorum ... Ve diğerlerinin de işaret ettiği gibi, onlara bunun neden daha normal olduğunu düşündüklerini sorun? Ya da ne kazanıyorlar? Gibi sorgular yazmaya çalışıyorsanız

WHERE othertable.year = 2011

Onun yerine

WHERE dt >= 20110101 AND dt < 20120101

Sonra ikincisinin performans (dt dizinlendiğini varsayarak) ve depolama için çok daha iyi olduğuna ikna etmeye çalışacağım. Kodlama sadeliği çok önemliyse, kalıcı bir hesaplanmış sütunun başka bir tablodan daha iyi olacağını söyleyebilirim.


1

Bir nokta dışında Catcall'ın cevabına tamamen katılıyorum: "yıl" her zaman ilkel bir değer olmayabilir, ancak sanırım bu bir veritabanı tasarımından çok bir iş mantığı kavramından daha fazlası.

Aynı tasarımı koruyarak, yılların yalnızca serbest bırakılmasına izin verilen yıllar olması gerektiğini varsayalım. Bu şekilde, ilkel sayısal değerlerle uğraşmazsınız, daha ziyade bunların bir alt kümesiyle ilgilenirsiniz ve bu alt kümenin ilkel bir uygulaması olmadığından, kendiniz (ayrı bir tablo?) Yapmanız ve referans vermeniz gerekir. (bir FK ile). Bu şekilde, hala yıllardan bahsediyoruz, ancak onları farklı bir şekilde yönetmemiz gerekiyor, çünkü kavramsal olarak anlamlarını değiştirdiler. Bununla birlikte, hala "serbest bırakılma yılı" dır, ancak alan adı bilgisindeki biri için ne anlama geldiklerinden kavramsal olarak farklıdırlar.

Bu özel durum için, yine Catcall'un cevabının doğru olduğunu söylüyorum, ama sadece bunu belirtmek istedim. (Üzgünüm, henüz yorum yapmak için yeterli temsilciniz yok.)

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.