Hay varias razones por las que usar una gran "tabla de dios" es malo. Intentaré ilustrar los problemas con una base de datos de ejemplo compuesta. 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 tener este aspecto (esto es muy simple a propósito, así que no se deje atrapar en lugares donde se pueda aplicar más normalización):
Teams
Id | Name | HomeCity
Games
Id | StartsAt | HomeTeamId | AwayTeamId | Location
y una base de datos de tabla única 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 local para un equipo, podría agregarlo a la tabla Teams
o la tabla TeamsAndGames
con bastante facilidad. Recuerde que siempre que cree un índice, debe almacenarlo en un disco y actualizarlo a medida que se agregan filas a la tabla. En el caso de la tabla Teams
esto es bastante sencillo. Puse en un nuevo equipo, la base de datos actualiza el índice. ¿Pero qué hay de TeamsAndGames
? Bueno, lo mismo se aplica a partir del ejemplo Teams
. Añado un equipo, el índice se actualiza. ¡Pero también sucede cuando agrego un juego! Aunque ese campo será nulo para un juego, el índice todavía 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.
Segundo, consistencia de los datos. En el caso de usar dos tablas separadas, puedo usar claves externas de la tabla Games
a la tabla Teams
para definir qué equipos están jugando en un juego. Y, asumiendo 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, ya que hay varias entidades en esta tabla, esas columnas deben ser anulables (puede hacer que no sean anulables y meter datos de basura allí, pero eso es una idea horrible). Si esas columnas son anulables, la base de datos ya no puede garantizar que al insertar un juego tenga dos equipos.
Pero, ¿y si decides ir solo por ello? Configura las claves externas 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 que sean del tipo correcto. Usted podría establecer fácilmente GameHomeTeamId
a la ID de otro juego y la base de datos no se quejará en absoluto. Si lo intentara en el escenario de varias tablas, la base de datos generaría un ajuste.
Puede intentar mitigar estos problemas diciendo "bueno, nos aseguraremos de que nunca lo hagamos en el 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 cada combinación extraña de cosas que un usuario podría intentar, adelante. Personalmente, no confío en mi capacidad para hacer ninguna de estas cosas, así que dejaré que la base de datos me proporcione una red de seguridad adicional.
(Esto empeora aún más si su diseño es uno donde se copian todos los datos relevantes entre filas en lugar de usar claves externas. Cualquier ortografía / otras inconsistencias en los datos serán difíciles de resolver. ¿Cómo puede saber si "Jon" es un error ortográfico? de "John" o si fue intencional (porque son dos personas distintas)?
Tercero, casi todas las columnas deben ser anulables o deben rellenarse con datos copiados o de basura. Un juego no necesita un TeamName
o TeamHomeCity
. Entonces, o cada juego necesita algún tipo de marcador de posición allí o debe ser anulable. Y si es anulable, la base de datos tomará un juego sin TeamName
. También tomará un equipo sin nombre, incluso si la lógica de su negocio dice que eso nunca debería suceder.
Hay otras razones por las que querrías 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 tienes métricas de rendimiento para mostrar que ese es realmente el problema, no un índice faltante o algo más).
Finalmente, desarrolle algo que sea fácil de mantener. Solo porque "funciona" no significa que esté bien. Tratar de mantener las tablas de dioses (como las clases de dioses) es una pesadilla. Solo te estás preparando para el dolor más tarde.