Ya sea para crear o no tablas separadas para diferentes tipos de productos?

25

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 ...

payling
fuente
2
En este punto, le sugiero que cree hojas de cálculo que imiten el diseño de su tabla y las llenen de datos. Esto expondrá cualquier debilidad que pueda existir.
Michael Riley - AKA Gunny
¿Cómo apuntará las claves externas a diferentes productos si están en tablas diferentes? Lea sobre la herencia de la tabla por favor.
Neil McGuigan el

Respuestas:

8

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

  • Cree una tabla primaria que contenga solo las columnas que comparten todos los tipos
  • Cree cada tipo de producto como su propia tabla con sus columnas individuales, con un extra: un enlace a la tabla principal
  • Cree cada tabla de 'enlace': Product_Option, Model_option, etc. con enlaces a las teclas respectivas.
  • Para aquellos con enlaces recíprocos (MODEL_OPTION, OPTION_MODEL) adelante, cree esas tablas también. Esto agregará claridad en sus uniones para cualquiera que lo vea.

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.

Derek Downey
fuente
55
Ahora solo hay 4 tipos, pero ¿qué pasa si se agregan más después? Estoy seguro de que la tabla principal de productos de Amazon se llamaba originalmente "Libros", pero ¿crees que ahora tienen una tabla separada para cada tipo de producto? No creo que cada tipo deba tener su propia tabla, pero podría usar un modelo EAV para propiedades adicionales que cada tipo podría tener en común.
Aaron Bertrand
1
@Aaron Fair señala sobre el aumento futuro de los tipos de productos. Si este escenario pudiera expandirse a más de 10 tipos de productos, lo reconsideraría. Pero, creo que las tablas de productos específicos son una elección de diseño justa para una pequeña cantidad de tipos de productos.
Derek Downey
1
Opción C: ¿Es necesario tener una tabla de enlaces? Me imagino que la PK Product_Option coincidiría con la PK de la tabla Product y eso crearía la asociación para vincular ambas tablas.
payling
Usando Product_option como ejemplo, el esquema sería (en mi opinión): id, productID, optionID. productIDsería un FK para product.id, y optionIDes un FK para option.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.
Derek Downey
Vale, entiendo. Leí mal lo que escribiste ... Vaya.
payling
7

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.

Mark Storey-Smith
fuente
2

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 .

Michael Riley - AKA Gunny
fuente
Esta solución es similar a la opción B (si la entiendo correctamente, lo que no estoy seguro de hacer). Tendría una tabla maestra (Productos) y una tabla de "enlace" (también conocida como tabla adyacente / BillsofMaterials) para crear las asociaciones entre modelos, opciones, kits, etc. ¿Es correcto?
payling
Creo que el problema está nublado debido a las opciones. Vamos a sacar opciones de la discusión por un momento. Las piezas son la unidad más pequeña. Un grupo de piezas forma un modelo. Un grupo de piezas de repuesto en forma de kit constituye un subconjunto del modelo. Hasta aquí todo bien. Ahora las partes tienen opciones, supongamos por simplicidad, esto abarca dos categorías de color (negro, rojo, cromo) y material (metal, madera, plástico). También mencionaste que los modelos tienen opciones. ¿Las opciones de modelo están separadas de las opciones de parte o los modelos solo parecen tener opciones porque las partes hacen que los modelos sean diferentes?
Michael Riley - AKA Gunny
Las piezas no tienen "opciones" en mi diseño. Defino la opción como algo que va en un modelo que le proporciona una funcionalidad extendida. Una opción está compuesta de partes. Un modelo puede tener muchas opciones diferentes. Una opción puede caber en muchos modelos diferentes también.
Payling
No es así como formuló su pregunta. Cita: "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 ..." En este punto te sugiero cree hojas de cálculo que imiten el diseño de su tabla y complételas con datos. Esto expondrá cualquier debilidad que pueda existir.
Michael Riley - AKA Gunny
0

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.

Alan McBee
fuente
Los campos nulos serían mínimos, porque aproximadamente el 75% de los campos se usarían en cada tabla. Creo que estoy más preocupado por las relaciones entre los tipos de productos. Tendré tres o más tablas de enlaces que apuntan a la misma tabla. Model_has_Option dos claves principales, ambos identificadores de producto de la tabla de productos, si tuviera que usar solo una tabla para representar los tipos de productos. Me preocupa más si eso es lo correcto o no.
payling
Si bien hay muchos factores que afectan la decisión "correcta", hay dos factores generales a considerar. 1: requisitos generales de rendimiento; 2: adaptabilidad / complejidad / mantenibilidad. Uno de esos dos probablemente es un poco más importante que el otro. Si necesita velocidad, desnormalice apegándose a la Opción A. Tendrá duplicación; Eso es lo esperado. Si necesita jugar con el esquema regularmente y la velocidad no es EL factor más importante, entonces la Opción B. Lo hace "correcto" al conocer sus prioridades, no al adherirse a "las mejores prácticas de otra persona".
Alan McBee