Ci sono molte ragioni per cui usare una grande "divina tabella" è male. Proverò ad illustrare i problemi con un database di esempio composto. Supponiamo che tu stia cercando di modellare eventi sportivi. Diremo che vuoi modellare i giochi e le squadre che giocano in quei giochi. Un design con più tabelle potrebbe apparire così (questo è molto semplicistico di proposito, quindi non lasciarti sorprendere in luoghi in cui potrebbe essere applicata più normalizzazione):
Teams
Id | Name | HomeCity
Games
Id | StartsAt | HomeTeamId | AwayTeamId | Location
e un unico database di tabelle sarebbe simile a questo
TeamsAndGames
Id | TeamName | TeamHomeCity | GameStartsAt | GameHomeTeamId | GameAwayTeamId | Location
Innanzitutto, diamo un'occhiata a come creare indici su quelle tabelle. Se avessi bisogno di un indice nella città natale per una squadra, potrei aggiungerlo facilmente al Teams
tavolo o al TeamsAndGames
tavolo. Ricorda che ogni volta che crei un indice, questo deve essere archiviato sul disco da qualche parte e aggiornato come le righe vengono aggiunte alla tabella. Nel caso del Teams
tavolo questo è piuttosto semplice. Ho inserito un nuovo team, il database aggiorna l'indice. Ma che dire di TeamsAndGames
? Bene, lo stesso vale per ilTeams
esempio. 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 archiviato su disco per quel gioco. Per un indice, questo non suona troppo male. Ma quando hai bisogno di molti indici per le molteplici entità stipate in questa tabella, perdi molto spazio nella memorizzazione degli indici e un sacco di tempo del processore per aggiornarli per cose in cui non si applicano.
In secondo luogo, coerenza dei dati. Nel caso di usare due tavoli separati, posso usare le chiavi esterne dal Games
tavolo al Teams
tavolo per definire quali squadre stanno giocando in una partita. E supponendo che renda le colonne HomeTeamId
e AwayTeamId
non annullabili, il database assicurerà che ogni partita che inserisco abbia 2 squadre e che quelle squadre esistano nel mio database. Ma per quanto riguarda lo scenario a tabella singola? Bene, poiché ci sono più entità in questa tabella, quelle colonne dovrebbero essere nullable (potresti renderle non nullable e inserire dati spazzatura lì, ma questa è solo un'idea orribile). Se quelle colonne sono nullable, il database non può più garantire che quando si inserisce una partita abbia due squadre.
E se decidessi di provarci comunque? Le chiavi esterne vengono impostate in modo tale che quei campi rimandino a un'altra entità nella stessa tabella. Ma ora il database si assicurerà solo che quelle entità esistano nella tabella, non che siano del tipo corretto. Potresti facilmente impostare GameHomeTeamId
l'ID di un altro gioco e il database non si lamenterà affatto. Se lo provaste in uno scenario con più tabelle, il database si adatta.
Puoi provare a mitigare questi problemi dicendo "beh, ci assicureremo solo di non farlo mai nel codice". Se sei sicuro della tua capacità di scrivere codice privo di bug per la prima volta e della tua capacità di prendere in considerazione ogni strana combinazione di cose che un utente potrebbe provare, vai avanti. Personalmente non sono sicuro della mia capacità di fare una di queste cose, quindi lascerò che il database mi dia una rete di sicurezza extra.
(Questo peggiora anche se il tuo progetto è quello in cui copi tutti i dati rilevanti tra le righe invece di usare chiavi esterne. Qualsiasi ortografia / altre incongruenze di dati saranno difficili da risolvere. Come puoi sapere se "Jon" è un errore di ortografia di "John "o se fosse intenzionale (perché sono due persone separate)?)
Terzo, quasi ogni colonna deve essere nullable o deve essere riempita con dati copiati o spazzatura. Un gioco non ha bisogno di un TeamName
o TeamHomeCity
. Quindi o ogni gioco ha bisogno di qualche tipo di segnaposto o deve essere nullable. E se è nullable, il database farà felicemente una partita senza TeamName
. Ci vorrà anche una squadra senza nome, anche se la tua logica aziendale dice che non dovrebbe mai accadere.
Ci sono una serie di altri motivi per cui vorresti tabelle separate (inclusa la conservazione della sanità mentale degli sviluppatori). Ci sono anche alcuni motivi per cui una tabella più grande potrebbe essere migliore (la denormalizzazione a volte migliora le prestazioni). Questi scenari sono pochi e lontani tra loro (e di solito sono meglio gestiti quando si hanno metriche delle prestazioni per mostrare 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 le tabelle degli dei (come le classi degli dei) è un incubo. Ti stai solo preparando per il dolore più tardi.