Estoy en el proceso de diseño de una base de datos y tengo dudas sobre mis decisiones de diseño iniciales ...
Los tipos de productos son los siguientes ... Modelos, piezas, kits de piezas de repuesto y opciones.
Opción A (primer diseño): planeaba tener tablas separadas para los tipos de productos anteriores. Yo diría que aproximadamente el 75% de los campos serían los mismos en cada tabla.
Creé cada tipo de producto como tablas separadas debido a las asociaciones que necesito crear entre ellos. Por ejemplo, un modelo puede tener muchas opciones y una opción puede tener muchos modelos. Una opción también puede tener muchas partes y una parte puede tener muchas opciones ... y así sucesivamente ...
Opción B: en lugar de tener tablas separadas, podría crear una tabla llamada Producto que abarque modelos, piezas, kits de piezas de repuesto y opciones. Podría tener un campo llamado tipo para diferenciar entre modelo, opciones, etc. Supongo que una desventaja es que varios campos nunca se usarían (dejarían nulo) para ciertos tipos de productos. Supongo que aquí es donde entrarían en juego "no las mejores prácticas".
La opción B reduciría en gran medida la complejidad del diseño db. Tampoco tendría que preocuparme por hacer referencia a un montón de tablas al extraer datos para consultas ...
Respuestas:
Si esta fuera mi decisión de diseño, probablemente iría con más de una 'Opción C' (opción a modificada).
Primero, ¿por qué no 'Opción B'?
Por un lado, me gusta la claridad de que cada producto tiene su propia mesa. Si se trata de una tabla grande con un campo para determinar el tipo, la relación no es tan clara.
Por otro lado, la estrategia de indexación siempre requeriría que ese campo de tipo sea listado. Como solo son 4 tipos, la cardinalidad del índice es extremadamente baja (
SELECT * FROM product_table WHERE type='X'
básicamente está haciendo un escaneo completo de la tabla de todos modos)Opcion C
La desventaja es la complejidad de asegurarse de evitar a los huérfanos cuando las cosas se actualizan / eliminan, y al diseñar inicialmente las consultas que usan estas tablas.
fuente
productID
sería un FK paraproduct.id
, yoptionID
es un FK paraoption.id
. Eso es lo que quise decir con tabla de enlaces. Y sí, es necesario en este diseño permitir que un solo producto se vincule a múltiples opciones.Le sugiero que comience con el modelo relacional "correcto", su opción A. Si el uso típico de ese modelo lo lleva a la desnormalización en algunas áreas, no tenga miedo de hacerlo.
Estuve discutiendo con un colega la semana pasada cómo los diseños de esquemas a menudo se consideran algo que está escrito en piedra y que nunca puede cambiar. Es extraño, considerando que la refactorización es una práctica aceptada en todas las demás capas de una aplicación, que refactorizar un esquema de base de datos todavía se considera poco práctico.
Si la interfaz de la base de datos está bien diseñada, no hay nada que le impida adaptar el esquema a medida que aprende más sobre los patrones de uso de los sistemas.
fuente
Esto suena muy similar a las listas de materiales / herencia de cardinalidades múltiples que Paul Neilsen describe en el Capítulo 17 de La Biblia de SQL Server 2008 .
El capítulo completo es una muy buena lectura y la sección específica que aborda su problema de muchos a muchos se encuentra en las páginas 416-419.
Esta es la mejor discusión que he visto sobre el tipo de diseño de datos de piezas explotadas .
fuente
Si puede obtener imágenes de un escenario probable en el que habría consultas frecuentes sobre los cuatro tipos de productos (y eso me parece probable), entonces su opción B es la mejor.
En lugar de dejar muchos campos anulables no utilizados en la tabla Producto, ¿por qué no agregar una tabla ModelProduct, una tabla PartProduct, una tabla ReplacementPartKitProduct y tener solo los campos que son distintos para esos tipos en esas tablas? Use la misma clave principal en esas tablas que su tabla de productos. Únase a la tabla Producto y Modelo Producto cuando desee trabajar con Modelos. ¿Necesita determinar si el registro del Producto que tiene es una Parte? Simplemente haga una unión izquierda de Product a PartProduct, y si PartProduct. [PrimaryKey] no es nulo, tiene una Parte. Si es nulo, no es una Parte. Alternativamente, puede agregar un campo ProductType a la tabla Producto.
fuente