Diseño de DB / Entidad: tabla relacionada con cualquiera de varias tablas
-
03-07-2019 - |
Pregunta
Un Informe puede tener varios gráficos. La tabla Gráfico tiene el siguiente aspecto:
- Gráfico - Id , ChartId , ReportId , ...
El ChartId anterior se puede asignar al ChartId a uno de los siguientes tipos de gráficos:
- Línea : ChartId , Espesor , YAxis , XAxis , Color , ...
- Pie : ChartId , Radio , Color , ...
- Barra : ChartId , Ancho , Color , Borde , .. .
Estoy usando SQL Server y desafortunadamente soluciones alternativas como el uso de CouchDB, etc. no son opciones viables. También tengo la intención de asignar estas tablas a entidades que usan Entity Framework.
Este diseño es mi primera puñalada y veo múltiples problemas con este diseño:
- Gráfico . ReportId no puede ser una clave foránea en varias tablas, por lo que aplicar un FK es un problema.
- Al ejecutar una consulta SQL (o Linq), tendré que ejecutar dos consultas para obtener el tipo de gráfico y luego consultar esa tabla. O tendré que ejecutar una unión en todas las tablas para obtener los datos del gráfico.
- Al hacer una unión con los Tipos de gráficos, el ChartId en estas tablas debe ser único, por lo que Chart . ChartId se asigna a uno solo de Línea . ChartId o Barra . ChartId o Pie . ChartId .
- Mapear esto con EF será complicado.
Me imagino que este es un problema lo suficientemente común como para que haya soluciones prescritas y formas establecidas de manejarlo.
¿Estoy en el camino correcto con el diseño? Y si es así, cómo superar los problemas anteriores (FK, join, identificación única en varias tablas y mapeo).
Solución
Esta answer es bastante completo sobre las estrategias. Y el artículo del Equipo SQL sobre implementación de la herencia de tablas en SQL Server me llevó a donde quería.
Solución
¿Ha considerado poner los Gráficos en la misma tabla y usar una Tabla por patrón de herencia de jerarquía ? El enlace allí muestra cómo implementar esto en Entity Framework. Si es viable o no depende de cuán diferentes serán todos esos tipos de gráficos y cuántos campos necesitará cada uno.
También hay Tabla por tipo herencia que es más similar a lo que ya estás describiendo.
Otros consejos
Me gustaría abordar esto con un esquema de herencia de tabla:
Chart (ChartId, ChartTypeId)
PK (ChartId, ChartTypeId)
CHECK ChartTypeId IN ('Line', 'Bar', 'Pie')
LineChart (ChartId, ChartTypeId)
PK (ChartId, ChartTypeId)
FK (ChartId, ChartTypeId) -> Chart
CHECK ChartTypeId IN ('Line')
Para agregar un gráfico, primero agregue a la base " Tabla de gráficos y luego al subtipo apropiado tabla de cartas. Las restricciones de verificación mantienen todo en línea.
Gráficos lineales. Los gráficos circulares y los gráficos de barras son formas especializadas de gráficos.
Búsqueda "generalización especialización modelado relacional" para buenos artículos sobre este patrón.
O, tendré que ejecutar una unión contra todas las tablas para obtener los datos del gráfico.
Sí, y eso está bien.