2010-07-13 15 views
7

Tengo una tienda en línea donde los usuarios pueden tener pequeñas tiendas con sus propios productos. Cada uno de estos productos puede tener preguntas asociadas y el propietario de la tienda tiene la capacidad de responder esas preguntas. Esta información se almacena en 3 tablas, una tabla de "Preguntas" (QuestionID, ProductID, ...), una tabla de "Productos" (ProductID, ShopID, ...) y una "Tienda" (ShopID, OwnerID, ...) mesa.¿Es mejor almacenar información redundante o unir tablas cuando sea necesario en MySQL?

¿Es mejor tener un ShopID en la tabla 'Preguntas' (para permitir que el dueño de una tienda vea todas sus preguntas) o unir esas tres tablas para obtener Preguntas que coincidan con una Tienda determinada?

+0

Muchas gracias a todos por sus útiles respuestas. Estaba casi convencido de que sería mejor almacenar información redundante, pero hoy aprendí algo nuevo. Algunas personas señalaron que sería mejor tener una relación M: M entre productos y tiendas, pero eso no tiene sentido (¡en este caso!) Porque los propietarios de las tiendas son completamente diferentes (incluso los costos de envío, etc. están completamente separados). Por lo tanto, no hay forma de que varias tiendas compartan un producto (incluso si fuera el mismo producto, por así decirlo). –

Respuesta

9

Casi siempre es mejor unirse y evitar la información redundante. Debe solo denormalize cuando debe hacerlo para cumplir un objetivo de rendimiento, y no puede saber si necesita hacer esto hasta que pruebe primero con las tablas normalized.

Tenga en cuenta que la desnormalización ayuda a leer el rendimiento a expensas de ralentizar las escrituras y hacer que un error de codificación haga que los datos no estén sincronizados (ya que está almacenando lo mismo en más de un lugar ahora) tengo que asegurarme de actualizarlo todo).

2

En general, es mejor evitar la información redundante. Parece que debería ser una unión bastante barata para hacer dados los índices apropiados y no me gustaría desnormalizar de esa manera a menos que viera en los planes de consulta que el JOIN estaba causando problemas (quizás debido al número de registros en las tablas)

También necesitaría considerar la relación de lecturas a escrituras. La desnormalización ayudará a las lecturas, pero agregará gastos generales a las escrituras.

+0

la unión será bastante barata solo para pequeñas bases de datos. Si está considerando la cardinalidad para un índice en shopID en la tabla de productos, entonces el tiempo requerido para unirse podría ser significativo. –

+0

@narcisradu - Sí, he tenido que recurrir a esto antes, pero lo que quería decir es que debería hacerse solo cuando los planes de ejecución lo justifiquen. –

1

Usted debe tener una relación muchos a muchos entre las preguntas y los productos:

questions_ref (question_id, question_code, cuestión)

product_questions (pquestion_id, question_id_fk, product_id_fk)

productos (product_id, product_name, etc)

Si es posible que el producto esté en más de una tienda (lo cual estoy seguro) también debe tener una relación de muchos a muchos entre las tiendas y los productos.

shop_products (sproduct_id, product_id_fk, shop_id_fk, sproduct_price, other_shop_specific_param)

tiendas (shop_id, owner_id_fk, shop_name, etc)

+0

No creo que se requiera una relación de muchos a muchos aquí. Además, las tablas son uno a muchos, por lo que podría estar sujeto a la desnormalización. –

+0

Solo una nota; en caso de que esté confundido, la 'respuesta a la pregunta' sería una columna en la tabla de preguntas del producto – DRL

+0

@narcisradu m2m es claramente requerido en este caso; la tienda puede tener muchos productos; un producto puede estar en muchas tiendas: una pregunta es sobre muchos productos; un producto puede tener muchas preguntas. – DRL

1

Creo que su diseño está bien. No agregaré ShopID a la tabla Preguntas. Debe usar una unión, cuando sea necesario.

BTW: Debe usar una relación m: n entre productos y tiendas y eliminar ShopID para productos. Para que pueda tener el mismo producto en las diferentes tiendas y, también tiene las mismas preguntas para un producto.

Saludos, Lars

+2

definitivamente debe evitar el uso de una relación de muchos a muchos entre productos y tiendas si los propietarios de las tiendas son diferentes. Imagine que existe el mismo producto pero el precio difiere o cualquier otro atributo es diferente. –

+0

@narcisradu para que tenga una tabla de productos para cada tienda? es muy simple agregar parámetros específicos de la tienda a la tabla shop_products() en mi ejemplo shop_products (..., sProduct_price, sProduct_stock) – DRL

+1

@DRL: Aunque técnicamente está bien, su M2M entre tiendas y productos probablemente sea indeseable. Como propietario de una tienda, me gustaría que mis datos estén completamente separados de los datos de otro propietario de la tienda, aunque ambos conjuntos de datos vivan en la misma base de datos. Y no, las tablas de productos por tienda son absurdas, pero sí, usted quiere una relación de 1 a M entre la tienda y el producto. Esto evita el enredo de datos entre tiendas y simplificará enormemente la importación y exportación de datos de productos para una sola tienda. Eso es importante, porque como propietario de una tienda quiero configurarlo rápidamente y poder irme rápidamente. –

2

Desde el punto de vista del diseño, no es necesario almacenar datos redundantes. En tu caso podría ser. Intente hacer algunas pruebas y si el tiempo de consulta mejora debido a esta redundancia, entonces debe continuar con la desnormalización.

Cuestiones relacionadas