Ci sono molti motivi per cui l'uso di un grande "tavolo dei geni" è sbagliato. Proverò a illustrare i problemi con un database di esempio preparato. Supponiamo che tu stia cercando di modellare eventi sportivi. Diremo che vuoi modellare i giochi e le squadre che giocano in quei giochi. Un disegno con più tabelle potrebbe apparire come questo (questo è molto semplicistico di proposito quindi non farti intrappolare in luoghi dove potrebbe essere applicata più normalizzazione):
Teams
Id | Name | HomeCity
Games
Id | StartsAt | HomeTeamId | AwayTeamId | Location
e un singolo database di tabelle sarebbe simile a questo
TeamsAndGames
Id | TeamName | TeamHomeCity | GameStartsAt | GameHomeTeamId | GameAwayTeamId | Location
Per prima cosa, diamo un'occhiata agli indici su quei tavoli. Se avessi bisogno di un indice sulla città natale per una squadra, potrei aggiungerlo alla tabella Teams
o alla tabella TeamsAndGames
piuttosto facilmente. Ricorda che ogni volta che crei un indice, questo deve essere memorizzato su disco da qualche parte e aggiornato man mano che le righe vengono aggiunte alla tabella. Nel caso della tabella Teams
questo è piuttosto semplice. Inserisco una nuova squadra, il database aggiorna l'indice. Ma per quanto riguarda TeamsAndGames
? Bene, lo stesso vale per l'esempio Teams
. Aggiungo una squadra, l'indice viene aggiornato. Ma succede anche quando aggiungo un gioco! Anche se quel campo sarà nullo per un gioco, l'indice deve comunque essere aggiornato e memorizzato su disco per quel gioco comunque. Per un indice, questo non suona male. Ma quando hai bisogno di molti indici per le entità multiple stipate in questa tabella, perdi molto spazio per memorizzare gli indici e un sacco di tempo del processore aggiornandoli per cose che non applicano.
Secondo, coerenza dei dati. Nel caso dell'utilizzo di due tabelle separate, posso utilizzare chiavi esterne dalla tabella Games
alla tabella Teams
per definire quali squadre stanno giocando in un gioco. E supponendo di rendere le colonne HomeTeamId
e AwayTeamId
non annullabili, il database garantirà che ogni partita che ho inserito abbia 2 squadre e che quei team esistano nel mio database. Ma per quanto riguarda lo scenario a tavolo unico? Bene, dato che ci sono più entità in questa tabella, quelle colonne dovrebbero essere nullable (potresti renderle non annullabili e inserire i dati spazzatura lì, ma questa è solo un'idea orribile). Se queste colonne sono annullabili, il database non può più garantire che quando inserisci una partita abbia due squadre.
Ma cosa succederebbe se decidessi di andarci comunque? Si impostano le chiavi esterne in modo tale che quei campi rimandino a un'altra entità nella stessa tabella. Ma ora il database si limiterà a verificare che tali entità esistano nella tabella, non che siano il tipo corretto. Si potrebbe facilmente impostare GameHomeTeamId
sull'ID di un altro gioco e il database non si lamenterà affatto. Se l'hai provato nello scenario a più tabelle, il database avrebbe reagito.
Potresti provare a mitigare questi problemi dicendo "beh, ci assicureremo solo di non farlo mai in codice". Se sei sicuro della tua capacità di scrivere codice senza errori la prima volta e nella tua capacità di tenere conto di ogni strana combinazione di cose che un utente potrebbe provare, vai avanti. Personalmente non sono sicuro della mia capacità di fare nessuna di queste cose, quindi lascerò che il database mi fornisca una rete di sicurezza extra.
(Questo diventa ancora peggio se il tuo progetto è uno in cui copi tutti i dati rilevanti tra le righe invece di usare chiavi esterne. Qualsiasi incongruenza / altre incoerenze dei dati sarà difficile da risolvere. Come puoi sapere se "Jon" è un errore di ortografia di "John" o se era intenzionale (perché sono due persone separate)?)
In terzo luogo, quasi tutte le colonne devono essere annullabili o devono essere riempite con dati copiati o illeggibili. Un gioco non ha bisogno di un TeamName
o TeamHomeCity
. Quindi, ogni gioco ha bisogno di qualche tipo di segnaposto o deve essere annullabile. E se è nullable, il database farà felicemente una partita senza TeamName
. Prenderà anche una squadra senza nome, anche se la tua logica aziendale dice che non dovrebbe mai accadere.
Ci sono una manciata di altri motivi per cui vorrai tabelle separate (compreso il mantenimento della sanità mentale degli sviluppatori). Ci sono anche alcuni motivi per cui un tavolo più grande potrebbe essere migliore (la denormalizzazione a volte migliora le prestazioni). Questi scenari sono pochi e distanti tra loro (e di solito vengono gestiti meglio quando si hanno metriche sul rendimento per dimostrare che questo è davvero il problema, non un indice mancante o qualcos'altro).
Infine, sviluppa qualcosa che sarà facile da mantenere. Solo perché "funziona" non significa che sia OK. Cercare di mantenere tavoli divini (come le lezioni di dio) è un incubo. Ti stai solo preparando per il dolore più tardi.