tabla única con columnas adicionales frente a varias tablas que duplican el esquema

13

Estoy trabajando en un proyecto en el que, en algún momento, necesitaba tomar una decisión sobre si, en la base de datos, debería tener una sola tabla con múltiples columnas que no todos los registros usan, o múltiples tablas con esquema duplicado.

Estoy creando una aplicación de información deportiva que puede manejar múltiples deportes. Podemos manejar NBA, NHL, MLB, NFL por ejemplo. Cada deporte tiene conceptos muy similares: equipos, horarios, lesiones, información del jugador ...

Nuestra fuente de datos, por supuesto, no nos da cada dato en el mismo esquema. Cada deporte tiene un esquema diferente para el que recibimos datos de nuestro proveedor.

Debido a que no había suficiente tiempo (las demandas del cliente) para hacer un análisis inicial de las fuentes de datos para determinar los puntos en común, cubrí mi apuesta y tomé la 'apuesta segura' e hice tablas separadas individuales para cada deporte en lugar de un conjunto de tablas que todos deportes utilizados

El resultado es un esquema duplicado en varias de las tablas y, por lo tanto, también interfaces duplicadas con la base de datos (por ejemplo, procesos almacenados). Tengo algo como NBA_Game, NFL_Game, NBA_Team, NFL_Team, etc. Cada tabla puede tener algunas propiedades que la otra no tiene, y varias que se comparten. continúa por ejemplo 5-10 mesas en 4 o 5 deportes. Todavía no estoy seguro de si esto es algo completamente malo: la alternativa, tener un solo conjunto de tablas con propiedades que no todos los deportes usarían, también podría haber sido difícil de manejar.

¿Alguien que haya hecho esto se ha encontrado con dificultades de este tipo de diseño y podría compartir su experiencia aquí? ¿Cosas que podrían ayudarme a saber ahora en lugar de aprender por el camino difícil? ¿Lo ha hecho de la otra manera, teniendo una gran tabla / conjunto de tablas, con columnas que no usarían todos los registros? ¿En qué dificultades te encontraste al hacer eso?

¿Hay alguna alternativa como la herencia de tablas que haya utilizado en el pasado que funcionó mejor?

Gracias

dferraro
fuente

Respuestas:

12

En definitiva, todo se reduce a uso y arquitectura.

Arquitectura

¿El sistema maneja "algún deporte"? ¿Es la idea de que te pongas el sombrero de astronauta de tu arquitectura y construyas un sistema genérico que pueda manejar cualquier tipo de deporte futuro que ni siquiera exista hoy?

Si es así, obviamente tener tablas con nombres dinámicos es un gran dolor, por lo que tendría sentido tener un esquema que soporte n deportes, si es necesario.

Dicho esto, tengo un sesgo muy fuerte en contra de este enfoque: esto casi siempre es más trabajo y conduce a peores resultados. Hacer una IU, un esquema, etc. por separado para cada deporte en última instancia conducirá a una mejor experiencia del usuario y un código más fácil de mantener, incluso si significa una cantidad superficial de duplicación (cómo evitar / minimizar esta es una pregunta separada).

¿Cómo manejas a los jugadores que practican múltiples deportes? ¿Reciben dos entradas (por ejemplo, las tratas como personas diferentes) o estás tratando de hacer algo específico con ellas?

Utilizar

Así que supongamos que no practicas deportes dinámicamente (por ejemplo, si alguien quiere agregar un deporte nuevo, requiere un esfuerzo de desarrollo para agregarlo).

¿Hay algún momento en el que muestres jugadores (o cualquier otro objeto que hayas mencionado) de más de un deporte a la vez?

Pude ver esto para una función de búsqueda, donde puedes buscar por nombre de jugador o equipo (independientemente del deporte), pero más allá de eso, no puedo imaginar muchos casos de uso.

Si nunca necesita hacer esto, entonces su enfoque está perfectamente bien. Puedes dejar de leer aquí.

Esquemas alternativos

Puntos de vista

Soy fan de KISS. En más de 15 años de desarrollo de software, continúo recurriendo a la filosofía "construir lo más simple que funciona".

Entonces, mi reacción inicial, suponiendo que una función de búsqueda entre deportes es realmente el único caso de uso, es crear vistas:

SELECT PlayerName, 'NFL' as [Sport], TeamName FROM NFL_Players JOIN NFL_Teams ... 
UNION  
SELECT PlayerName, 'NHL' as [Sport], TeamName FROM NHL_Players JOIN NHL_Teams ... 
UNION ....

Por supuesto, si agrega un nuevo deporte, debe agregarlo a la vista. También puede ser útil incluir otra información común, pero realmente depende de lo que se necesite mostrar.

Intentaría mantener todas las cosas específicas del deporte en la definición de Vista, para que el código de búsqueda no necesite tener mucho o ningún código específico (además de saber cómo vincular a /nhl/players/player-namevs /nfl/...o como su aplicación lo haga).

Herencia de mesa

La herencia de tablas puede funcionar, pero es bastante compleja. No tengo mucha experiencia con él, y de hecho, creo que cada vez que he estado involucrado en evaluarlo terminamos haciendo algo más simple (como sugiero aquí).

Entonces, personalmente, todavía tengo que encontrar por qué esto sería útil, pero tal vez haya un caso de uso convincente (que no conozco) que justifique la complejidad (por ejemplo, la herencia de tablas resuelve el caso de uso mejor que cualquier otra solución) .

Tablas separadas para atributos deportivos específicos

Podría hacer una sola playerstabla que tenga atributos comunes a todos los jugadores de todos los deportes, y luego otro conjunto de tablas como nhl_players_detailsesa contiene un ID de jugador y columnas con información adicional sobre el jugador. Si hay un montón de atributos comunes, o tiene muchos usos de "todos los jugadores de todos los deportes", entonces esto puede tener sentido.

Pares de valores clave para atributos específicos del deporte

Enfoque completamente alternativa: tener una playersmesa (de nuevo, con atributos comunes como el nombre) y luego una player_datatabla que tiene PlayerId, Sport, Attribute, Value. Los nombres de los atributos ingresados ​​serían específicos del deporte. Esto le permite esencialmente agregar nuevos atributos sin modificar el esquema (su código aún tendría que saber cargarlos / mostrarlos, por supuesto). El inconveniente es que pierde algo de integridad: el valor normalmente sería un campo de cadena, por lo que el código de su aplicación debería ser resistente y manejar posibles fallas al convertir la cadena valuea un tipo de datos específico (como un entero).

Este concepto, por supuesto, puede aplicarse a equipos, juegos, etc.

Gregmac
fuente
La búsqueda de una solución para un proyecto heredado tendrá múltiples tipos y tablas autenticables, la mención de puntos de vista aquí, que había olvidado, realmente ha ayudado a ofrecer otra posible solución a mi investigación. Gracias.
FullStackFool
5

Estás hablando de la normalización de la base de datos . Puede que le alivie saber que no existe un modelo de datos perfecto y que una mayor normalización no siempre es mejor. La normalización puede imponer costos en términos de claridad del modelo de datos y el rendimiento de la base de datos. Por lo tanto, el mejor modelo para seleccionar dependerá de sus requisitos de uso.

En la superficie, sus ejemplos parecen bastante similares en concepto (X_Game vs Y_Game y X_Team vs Y_Team) que la sobrecarga adicional de unas pocas columnas no parece irrazonable. Dicho esto, si cada deporte va a agregar varias docenas de columnas adicionales a la tabla, de hecho sería difícil de manejar.

En ese caso, es posible que desee considerar un modelo híbrido, donde los datos comunes se mantienen en una tabla central, pero los datos específicos del deporte se mantienen en una estructura de datos vinculada. Algo como:

table Game {
    gameId int,
    teamId1 int fk,
    teamId2 int fk
}

table HockeyGame {
    gameId int fk,
    penaltyMinutes int
}

table BasketballGame {
    gameId int fk,
    freeThrows int
}
Midnotion
fuente
Esto es lo que iba a proponer, más quizás una columna en la tabla de juegos que indica el tipo de juego. Me doy cuenta de que se puede inferir uniéndose en las otras mesas, pero si aumenta el número de tipos de juegos, eso comienza a ser tedioso.
Rory Hunter
Absolutamente, este es solo un modelo esqueleto para ilustrar las relaciones centrales y algunos ejemplos de lo que podrían ser datos comunes versus datos específicos del deporte.
Midnotion