5

Przechowuję dane na temat statystyk baseballu i chciałbym to zrobić przy trzech stołach: graczach, statkach do mrugnięcia i statkach pitchingowych. Na potrzeby tego pytania każdy gracz będzie miał statystyki mrugnięcia lub statystyki pitchowania, ale nie obie.W jaki sposób znormalizujesz relacje jeden-do-jednego-lub-drugiego?

Jak normalizować taki związek w 3NF?

+0

Już masz rozwiązanie. Użyj trzech tabel opisanych w twoim pytaniu, używając klawiszy opisanych przez Stevena A. Lowe'a poniżej. Możesz mieć dalsze problemy z normalizacją _inside_ tabel statystyk, ale poprawnie modelujesz relacje między graczami i statystykami. –

+0

@Steven, Zgadzam się, że dzbany nietoperzy (w NL i interleague play), ale to jest dla narzędzia fantasy baseball projektu i statystyki batting miotaczy nie liczą. –

Odpowiedz

6

playerID byłby klucz obcy w obu BattingStats i stoły PitchingStats

[i pamiętaj, aby umieścić jakiś wymiar czasu (sezon, rok, et al) w statystykach tabelach]

a przy okazji, jest to złe założenie: o ile mi wiadomo, dzbany mogą również walczyć!

2

Czy naprawdę nie należy używać więcej niż 3 stolików. Normalization zwykle oznacza rozbicie jednego nie znormalizowanego modelu na wiele znormalizowanych relacji.

Jeśli można mieć więcej niż 3 tabele, można rozważyć następujące (w 3NF):

Players:  ([player_id], name, date_of_birth, ...) 
Batters:  ([batter_id], player_id) 
Pitchers:  ([pitcher_id], player_id) 
Batting_Stats: ([batter_id, time_dimension], stat_1, stat_2, ...) 
Pitching_Stats: ([pitcher_id, time_dimension], stat_1, stat_2, ...) 

Atrybuty w [] zdefiniować klucz podstawowy, ale surrogate key może być używany, jeśli preferowane. Atrybut player_id w Batters and Pitches powinien mieć wartość unique constraint, a także powinna być relacją Players (1). Batting_Stats i Pitching_Stats również powinny mieć klucz obcy odpowiednio do Batters i Pitching.

Należy jednak pamiętać, że powyższe nie oznacza, że ​​gracz może być tylko pałkarziem lub tylko dzbankiem.


UPDATE:

Jedną z metod Jestem świadomy, aby wymusić, że gracz jest tylko ciasto lub tylko dzban, to przez ten model:

Players:  ([player_id], name, date_of_birth, ...) 
Roles:   ([role_id, role_type], player_id) 
Batting_Stats: ([role_id, role_type, time_dimension], stat_1, stat_2, ...) 
Pitching_Stats: ([role_id, role_type, time_dimension], stat_1, stat_2, ...) 

role_type powinien zdefiniuj dzban lub ciasto. Batting_Stats i Pitching_Stats powinny mieć kompozytowy klucz obcy do Roles przy użyciu (role_id, role_type). Unikalne ograniczenie na Rule w player_id zapewniłoby, że gracz może mieć tylko jedną i tylko jedną rolę. Na koniec dodaj check constraints, aby Batting_Stats.role_type = 'Batter' i Pitching_Stats.role_type = 'Pitcher'. Te ograniczenia sprawdzające gwarantują, że Batting_Stats zawsze opisuje pałkarz i notuje dzban. To samo dotyczy Pitching_Stats.

+0

Nie jest dla mnie oczywiste, w jaki sposób wstawienie tabelek Batters i Pitchers poprawia model danych lub czyni go bardziej normalnym. Tabele te wydają się powtarzać dane, które byłyby obecne, gdyby player_id był używany bezpośrednio w tabelach Batting_Stats i Pitching_Stats. –

+0

@Larry: Te tabele definiują zestaw paczek i zestaw miotaczy z "puli graczy". To * jest * nową informacją. Następnie statystyki mrugnięcia mogą odnosić się tylko do gracza z "zestawu mrugnięć", a tak samo do pitchowania. –

+0

Ale ta sama informacja byłaby dostępna poprzez zbadanie kolumny player_id w Batting_Stats i Pitching_Stats. Widzę jednak jeden dodatkowy przypadek, który jest obsługiwany przez twój projekt - definiując rolę gracza przy braku jakichkolwiek statystyk. Jeśli jest to wymagane, dodatkowe tabele spełnią tę potrzebę (podobnie jak dodatkowa kolumna role_type w Grach). –

1

Wiem, jak zaimplementowałem to z praktycznego punktu widzenia (utworzyłem widok UNIONED nad rozłącznymi tabelami i umieściłem unikalny indeks na identyfikatorze gracza - dlatego mogą pojawić się tylko w jednej tabeli).

Lub w tabeli graczy, zapisz, jaki typ mają statystyki, a następnie uwzględnij to w relacji FK z tabel statystyk.

Ale jeden z nich jest prawdopodobnie bliżej metalu niż chcesz.