Normalizacja: Czy uważa się za zgodne z podziałem statycznych liczbowych wartości jak rok na własną tabelę?


16

Prowadzę interesującą dyskusję z innym projektantem bazy danych na temat normalizacji. W tym przykładzie mamy tabelę GameTitles i każdy rekord musi zawierać rok, w którym gra została wydana. Mówi, że 2NF nakazuje znormalizować wszystko, więc aby zachować zgodność, pole roku należy podzielić na tabelę ReleaseYears z własnym kluczem podstawowym, do którego odwołuje się tabela GameTitles. Mówię, że powinno pozostać jako pole na samym stole GameTitles.

Moim argumentem za tym jest to, że rok jest po prostu nieprymitywną wartością liczbową, która z natury jest statyczna (tj. 2011 zawsze będzie 2011). Z tego powodu służy jako własny identyfikator i nie potrzebuje niczego, aby się do niego odwoływać, ponieważ jest tym, czym jest. Wprowadza to również dodatkowe czynności konserwacyjne, ponieważ teraz musisz dodać nowy rok do tabeli, aby się do niego odwołać. Jeśli wypełnisz tabelę szerokim zakresem lat, masz dodatkowe rekordy, które potencjalnie nie będą miały do ​​nich odniesień. Zwiększa to również rozmiar bazy danych, ponieważ masz teraz dodatkową tabelę, narzut rekordów i dodatkowy klucz podstawowy dla samego roku. Jeśli utrzymasz rok jako pole na stole GameTitles, wyeliminujesz wszystkie te dodatkowe czynności konserwacyjne i koszty ogólne.

Myśli na ten temat?

edit: Chcę opublikować to na StackOverflow. Czy ktoś może zagłosować za usunięciem tego lub oznaczeniem go jako uwagi?


6
Dlaczego tak? wygląda na to, że dobrze tu pasuje.
Leigh Riffel,

Pytanie, które chcę zadać, to pytanie o normalizację lub rzeczywiste potrzeby produkcyjne? W przypadku produkcji zapytałbym, czy to ważna rzecz do zrobienia?
jcolebrand

Odpowiedzi:


14

Drugi projektant bazy danych jest po prostu zły, ale twoje rozumowanie jest również błędne. Załóżmy, że zaczynasz od tej tabeli, która ma jeden klucz kandydujący „game_title”.

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

Oceniasz, czy jest w 2NF, zadając sobie te pytania.

P: Po pierwsze, czy to jest w 1NF?

Odp .: Tak, to prawda.

P: Jakie są główne atrybuty (atrybuty, które są częścią klucza kandydującego)?

Odp .: „Game_title” jest jedynym atrybutem podstawowym.

P: Jakie są atrybuty inne niż podstawowe?

Odp .: „Year_first_released” jest jedynym.

P: Czy „year_first_released” jest funkcjonalnie zależny od całości „game_title”, czy tylko od jego części?

Odp .: Jedynym kluczem kandydata „game_title” jest pojedyncza kolumna; nawet nie ma części. Zatem „year_first_released” jest funkcjonalnie zależny od całości „game_title”.

Voilà. Znalazłeś 2NF.

Możesz przejść przez niektóre formalne warunki, najpierw pytając, czy jest to 1NF, a następnie odpowiadając na to pytanie.

P: Czy są jakieś złożone klucze kandydujące?

Nie.

Voilà. Znalazłeś 2NF ponownie.

Z definicji, aby tabela mogła naruszać 2NF, musi mieć co najmniej jeden klucz kandydujący, który ma więcej niż jedną kolumnę.

Oto powody odrzucenia opinii znajomego.

  • Rok to tylko nieprymitywna wartość liczbowa.
  • Rok jest ze swej natury statyczny.
  • Rok jest jego własnym identyfikatorem.
  • Tabela lat wprowadza dodatkowe czynności konserwacyjne.
  • Tabela lat może zawierać dodatkowe wiersze, do których nie ma odniesienia.
  • Tabela lat zwiększa rozmiar bazy danych.

Żaden z tych powodów nie ma nic wspólnego z tym, czy tabela jest w 2NF.

Projektując bazę danych, nie należy brać pod uwagę problemów związanych z konserwacją, wielkości bazy danych, niepowiązanych wierszy, ograniczeń zakresu i tak dalej. Po prostu źle jest nazywać te rzeczy normalizacją.

Aha, i ta dwukolumnowa tabela, którą przedstawiłem powyżej - jest w 5NF.


2
Ładnie wykonane. Kusiło mnie, aby opublikować odpowiedź, która nie mówi nic więcej niż twoje pierwsze zdanie ... „Drugi projektant bazy danych jest po prostu zły”, dobrze wyjaśniłeś, dlaczego.
Mark Storey-Smith

5

Utworzenie oddzielnej tabeli dla dowolnego atrybutu nie ma nic wspólnego z normalizacją. 2NF, 3NF, BCNF, 4NF, 5NF dotyczą eliminacji zależności niekluczowych. Jeśli usuniesz pojedynczy atrybut do nowej tabeli i zastąpisz go atrybutem klucza obcego, to zależności w tabeli będą logicznie takie same jak poprzednio - więc poprawiona wersja tabeli nie jest bardziej lub mniej znormalizowana niż ona był wcześniej.


Chcę coś do tego dodać , ale nie jestem pewien, co. Mówisz, że przeniesienie czegoś do tabeli, która ma korelację 1: 1 (albo 1 klucz do dokładnie 1 wartości jak w tym przypadku, albo jeden wiersz do jednego wiersza) nie daje korzyści, jeśli wyszukiwanie nie jest potrzebne, prawda? Ale istnieje potencjalna korzyść z wyszukiwania, jeśli rzadko potrzebujesz roku i patrzysz na zasięg 255 lat lub mniej. Można sobie wyobrazić, że udało się uciec z kilkoma zapisanymi bajtami tutaj, ale ponieważ zwykle i tak są one przydzielane po 4 bajty, nie jest to rozsądne założenie.
jcolebrand

1
@jcolebrand: Zgadzam się z tym, co mówisz. Jednak odpowiedź na pytanie jest taka sama: czy to robisz, czy nie, nie ma to nic wspólnego z normalizacją jako taką.
nvogel,

Zgadzam się. Tak jak powiedziałem, moje było trochę beznadziejne „Czuję, że OP czegoś tu brakuje” ... ponieważ nie jestem pewien, dokąd pójść z tą koncepcją.
jcolebrand

5

Z mojego punktu widzenia osobna tabela lat ma sens tylko wtedy, gdy „rok wydania” nie jest rokiem kalendarzowym, ale np. Rokiem podatkowym, który może obejmować wiele lat kalendarzowych (np. Od października do października).

Tabela ta zawierałaby wówczas definicję (rzeczywistą datę rozpoczęcia i zakończenia) roku obrotowego


1
+1 potrzebujesz tabeli tylko wtedy, gdy będzie miała atrybuty :)
Jack mówi, spróbuj wypróbować topanswers.xyz

2

From http://en.wikipedia.org/wiki/Second_normal_form :

tabela 1NF jest w 2NF wtedy i tylko wtedy, gdy dany klucz kandydujący K i jakikolwiek atrybut A, który nie jest składnikiem klucza kandydującego, A zależy od całości K, a nie tylko od jego części.

Nie wskazałeś, czy rok jest częścią klucza kandydata, czy nie, ale nie jestem pewien, czy to ma znaczenie, ponieważ w obu przypadkach 2NF byłby zadowolony pod względem roku.

Z praktycznego punktu widzenia nie jest dobrym pomysłem oddzielenie roku ze wszystkich wymienionych powodów.


2

Nie podoba mi się argument przeciwko oddzielnej tabeli ze względu na jej rozmiar lub to, że będzie miał nieużywane wiersze. Nawet jeśli umieścisz w tej tabeli 1000 lat, rozmiar będzie znikomy.

To powiedziawszy, nie sądzę, żeby stół był w ogóle potrzebny. Po co mieć osobny stół na rok? Te dane są już w głównej tabeli, a absolutnie nic nie oszczędzasz, tworząc drugą tabelę.

Argument może być inny dla tabeli kalendarza, w której każdy wiersz reprezentuje dzień i może mieć inne atrybuty (dzień tygodnia, przesunięcie UTC, czy to święto itp.).

Ale sam rok? Nie, nie widzę żadnej korzyści ... I jak zauważyli inni, zapytaj ich, dlaczego uważają, że to jest bardziej znormalizowane? A co zdobywają? Jeśli próbujesz pisać zapytania takie jak

WHERE othertable.year = 2011

Zamiast

WHERE dt >= 20110101 AND dt < 20120101

Następnie spróbuję przekonać cię, że ten drugi sposób jest znacznie lepszy pod względem wydajności (zakładając, że dt jest indeksowany) i pamięci. Jeśli prostota kodowania jest najważniejsza, powiedziałbym, że utrwalona kolumna obliczeniowa byłaby lepsza niż inna tabela.


1

Całkowicie zgadzam się z odpowiedzią Catcall, z wyjątkiem jednego punktu: „rok” nie zawsze może być prymitywną wartością, ale wydaje mi się, że jest to bardziej koncepcja logiki biznesowej niż koncepcja projektowania bazy danych.

Utrzymując ten sam projekt, załóżmy, że lata powinny być tylko tymi, które mogą zostać wydane. W ten sposób nie masz do czynienia z prymitywnymi wartościami liczbowymi, ale raczej z ich podzbiorem, a ponieważ taki podzbiór nie ma prymitywnej implementacji, musisz zrobić własną (oddzielną tabelę?) I odwołać się do niej (z FK). W ten sposób wciąż mówimy o latach, ale musimy zarządzać nimi w inny sposób, ponieważ koncepcyjnie zmienili swoje znaczenie. Jednak wciąż są „rokiem wydania”, ale pod względem koncepcyjnym różnią się pod względem tego, co oznaczają dla kogoś w dziedzinie wiedzy.

W tym konkretnym przypadku ponownie mówię, że odpowiedź Catcall jest poprawna, ale chciałem tylko to podkreślić. (Przepraszamy, nie mam jeszcze wystarczającej liczby przedstawicieli, aby móc komentować).

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.