Existen múltiples razones por las que usar una gran "tabla de Dios" es malo. Trataré de ilustrar los problemas con una base de datos de ejemplo inventada. Supongamos que está tratando de modelar eventos deportivos. Diremos que desea modelar juegos y los equipos que juegan en esos juegos. Un diseño con varias tablas podría verse así (esto es muy simplista a propósito, así que no te quedes atrapado en lugares donde podría aplicarse una mayor normalización):
Teams
Id | Name | HomeCity
Games
Id | StartsAt | HomeTeamId | AwayTeamId | Location
y una base de datos de una sola tabla se vería así
TeamsAndGames
Id | TeamName | TeamHomeCity | GameStartsAt | GameHomeTeamId | GameAwayTeamId | Location
Primero, veamos cómo hacer índices en esas tablas. Si necesitaba un índice en la ciudad de origen para un equipo, podría agregarlo a la Teams
tabla o a la TeamsAndGames
tabla con bastante facilidad. Recuerde que siempre que cree un índice, debe almacenarse en el disco en algún lugar y actualizarse a medida que se agregan filas a la tabla. En el caso de la Teams
tabla, esto es bastante sencillo. Puse un nuevo equipo, la base de datos actualiza el índice. ¿Pero para qué TeamsAndGames
? Bueno, lo mismo se aplica desde elTeams
ejemplo. Agrego un equipo, el índice se actualiza. ¡Pero también sucede cuando agrego un juego! Aunque ese campo será nulo para un juego, el índice aún debe actualizarse y almacenarse en el disco para ese juego de todos modos. Para un índice, esto no suena tan mal. Pero cuando necesita muchos índices para las múltiples entidades agrupadas en esta tabla, desperdicia mucho espacio almacenando los índices y mucho tiempo de procesador actualizándolos para cosas donde no se aplican.
En segundo lugar, la coherencia de los datos. En el caso de usar dos mesas separadas, puedo usar claves externas de la Games
mesa a la Teams
mesa para definir qué equipos están jugando en un juego. Y suponiendo que las columnas HomeTeamId
y AwayTeamId
no sean anulables, la base de datos garantizará que cada juego que coloque tenga 2 equipos y que esos equipos existan en mi base de datos. Pero, ¿qué pasa con el escenario de una sola mesa? Bueno, dado que hay varias entidades en esta tabla, esas columnas deben ser anulables (puede hacer que no sean anulables y colocar datos basura allí, pero eso es solo una idea horrible). Si esas columnas son anulables, la base de datos ya no puede garantizar que cuando inserte un juego tenga dos equipos.
Pero, ¿qué pasa si decides ir de todos modos? Configura las claves foráneas de modo que esos campos apunten a otra entidad en la misma tabla. Pero ahora la base de datos solo se asegurará de que esas entidades existan en la tabla, no de que sean del tipo correcto. Podrías configurar fácilmente GameHomeTeamId
la ID de otro juego y la base de datos no se quejará en absoluto. Si lo intentara en el escenario de tablas múltiples, la base de datos arrojaría un ajuste.
Puede intentar mitigar estos problemas diciendo "bueno, nos aseguraremos de que nunca lo hagamos en código". Si confía en su capacidad para escribir código libre de errores la primera vez y en su capacidad para tener en cuenta todas las combinaciones extrañas de cosas que un usuario podría intentar, siga adelante. Personalmente, no confío en mi capacidad para hacer ninguna de esas cosas, así que dejaré que la base de datos me brinde una red de seguridad adicional.
(Esto empeora aún más si su diseño es uno en el que copia todos los datos relevantes entre filas en lugar de usar claves externas. Cualquier falta de ortografía / otras inconsistencias de datos será difícil de resolver. ¿Cómo puede saber si "Jon" es un error ortográfico de "John "o si fue intencional (porque son dos personas separadas)?)
En tercer lugar, casi todas las columnas deben ser anulables o deben llenarse con datos copiados o basura. Un juego no necesita un TeamName
o TeamHomeCity
. Entonces, o cada juego necesita algún tipo de marcador de posición o debe ser anulable. Y si es anulable, la base de datos tomará un juego sin problemas TeamName
. También tomará un equipo sin nombre, incluso si la lógica de su negocio dice que eso nunca debería suceder.
Hay un puñado de otras razones por las que desearía tablas separadas (incluida la preservación de la cordura del desarrollador). Incluso hay algunas razones por las que una tabla más grande podría ser mejor (la desnormalización a veces mejora el rendimiento). Esos escenarios son pocos y distantes entre sí (y generalmente se manejan mejor cuando tiene métricas de rendimiento para mostrar que ese es realmente el problema, no un índice faltante u otra cosa).
Finalmente, desarrolle algo que sea fácil de mantener. El hecho de que "funcione" no significa que esté bien. Tratar de mantener tablas de dioses (como las clases de dioses) es una pesadilla. Simplemente te estás preparando para el dolor más tarde.