5

Sto memorizzando i dati sulle statistiche del baseball e vorrei farlo con tre tavoli: giocatori, battingStats e pitchingStats. Ai fini della domanda, ogni giocatore avrà statistiche di battuta o di lancio, ma non entrambi.Come si normalizzano le relazioni one-to-one-or-the-other?

Come si normalizzerebbe tale relazione in 3NF?

+0

Hai già la soluzione. Usa tre tabelle come descritto nella tua domanda, con le chiavi descritte da Steven A. Lowe, sotto. Potresti avere ulteriori problemi di normalizzazione _inside_ le tue tabelle delle statistiche, ma hai modellato correttamente la relazione tra giocatori e statistiche. –

+0

@Steven, sono d'accordo sul fatto che i lanciatori si battano (in NL e in interleague play,), ma questo è per uno stendardo da baseball fantasy e le statistiche di battuta dei lanciatori non contano. –

risposta

6

playerid sarebbe una chiave esterna in entrambi i BattingStats e tavoli PitchingStats

[e ricordate di mettere un po 'dimensione temporale (stagione, anno, et al) nelle tabelle statistiche]

e tra l'altro, questa è una cattiva ipotesi: per quanto ne so, ai lanciatori è permesso di battere anche loro!

2

Sei davvero obbligato a non utilizzare più di 3 tavoli. Normalization normalmente implica l'abbattimento di un modello non normalizzato in molte relazioni normalizzate.

Se è possibile avere più di 3 tavoli, si può prendere in considerazione quanto segue (in 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, ...) 

attributi in [] definiscono la chiave primaria, ma un surrogate key possono essere utilizzati se si preferisce. L'attributo player_id in Batters and Pitches deve avere un unique constraint e dovrebbe anche essere un foreign key alla relazione Players. Batting_Stats e Pitching_Stats dovrebbero avere anche una chiave esterna per Batters e Pitching rispettivamente.

Si noti tuttavia che quanto sopra non impone che un giocatore possa essere solo un battitore o solo un lanciatore.


UPDATE:

Un metodo sono consapevole di far valere che un giocatore è solo una pastella oppure solo una brocca, è attraverso questo modello:

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, ...) 

Il role_type dovrebbe definire un lanciatore o un battitore. Batting_Stats e Pitching_Stats devono avere una chiave esterna composita per i ruoli utilizzando (role_id, role_type). Un vincolo univoco su player_id in Ruoli garantirebbe che un giocatore possa avere solo un ruolo, e solo uno. Aggiungere infine check constraints in modo che Batting_Stats.role_type = 'Batter' e Pitching_Stats.role_type = 'Pitcher'. Questi limiti di controllo garantiscono che Batting_Stats descriva sempre un battitore e noti un lanciatore. Lo stesso vale per Pitching_Stats.

+0

Non è immediatamente ovvio per me come l'inserimento dei tavoli Batters and Pitchers migliori il modello dei dati o lo renda più normale. Queste tabelle sembrano solo ripetere i dati che sarebbero presenti se player_id venisse usato direttamente nelle tabelle Batting_Stats e Pitching_Stats. –

+0

@Larry: queste tabelle definiscono il set di battitori e il gruppo di lanciatori dal "pool di giocatori". Questo * è * nuove informazioni. Quindi le statistiche di battuta possono riferirsi solo a un giocatore dal "set battuta", e lo stesso per il lancio. –

+0

Ma quella stessa informazione sarebbe disponibile esaminando la colonna player_id in Batting_Stats e Pitching_Stats. Vedo un caso aggiuntivo gestito dal tuo progetto, tuttavia, che definisce il ruolo di un giocatore in assenza di statistiche. Se è necessario, le tabelle aggiuntive soddisfano tale necessità (così come una colonna extra role_type in Player). –

1

So come implementare ciò da un punto di vista pratico (creerei una vista UNIONed sulle tabelle disgiunte e inserirò un indice univoco nell'ID giocatore, quindi possono apparire solo in una tabella).

Oppure nella tabella dei giocatori, registrare il tipo di statistiche che hanno, quindi includerlo nella relazione FK dalle tabelle delle statistiche.

Ma uno di questi è probabilmente più vicino al metallo di quello che vuoi.