2010-07-13 113 views
7

我有一个网上商店,用户可以用自己的产品有小商店。这些产品中的每一个都可能有与之相关的问题,并且店主可以回答这些问题。该信息存储在3个表格中,即“问题”(QuestionID,ProductID,...)表格,“产品”(ProductID,ShopID,...)表格和“商店”(ShopID,OwnerID,...)表。在MySQL中存储冗余信息或必要时连接表是更好吗?

在“问题”表中添加ShopID(允许店主查看他的所有问题)还是加入这三个表以获得与特定商店匹配的问题是否更好?

+0

非常感谢大家的帮助。我几乎相信,存储冗余信息会更好,但我今天学到了一些新东西。 有些人指出,在产品和商店之间建立M:M关系会更好,但由于店主完全不同(甚至运输成本等完全分开),这是没有意义的(在这种情况下!)。因此,几家商店不可能共享一个产品(即使它可以说是同一产品)。 – 2010-07-13 22:11:47

回答

9

加入和避免冗余信息几乎总是更好。当您必须这样做时,您应该只有denormalize才能达到性能目标 - 并且您无法知道是否需要执行此操作,直到您首先尝试使用normalized表。

请注意,非规范化有助于读取性能,但会以减慢写入速度为代价,并使编码错误更容易导致数据不同步(因为您现在将多个地方存储在同一个地方必须确保将其全部更新)。

2

通常最好避免冗余信息。这似乎应该是一个相当便宜的连接做适当的索引,我不会以这种方式去规范化,除非我在查询计划中看到JOIN引起问题(可能是因为表中的记录数)

您还需要考虑读取与写入的比率。非规范化将有助于读取,但会增加写入开销。

+0

只有小型数据库的连接才会很便宜。如果您正在考虑产品表中的shopID索引的基数,则加入所需的时间可能很长。 – 2010-07-13 12:38:19

+0

@narcisradu - 是的,我之前不得不求助于此,但是我所做的一点是,只有在执行计划显示一个案例时才应该这样做。 – 2010-07-13 12:45:30

1

你应该有一个许多人的问题和产品之间的多对多关系:

questions_ref(question_id,question_code,问题)

product_questions(pquestion_id,question_id_fk,product_id_fk)

产品(product_id,product_name等)

如果产品可能位于多个商店(即使确定),您也应该在商店和产品之间建立多对多的关系。

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

商店(shop_id,owner_id_fk,shop_name等)

+0

我不认为这里需要多对多的关系。此外,这些表是一对多的,所以它可能是非规范化的主题。 – 2010-07-13 12:33:57

+0

只是一个说明;如果你感到困惑,'问题答案'将成为product_questions表中的一列 – DRL 2010-07-13 12:35:04

+0

@narcisradu m2m在这种情况下显然是必需的;商店可以有许多产品 - 一个产品可以在许多商店:一个问题是在许多产品上 - 一个产品可以有很多问题。 – DRL 2010-07-13 12:38:39

1

我觉得你的设计是好的。我不会将ShopID添加到表问题。必要时您应该使用连接。

顺便说一句:您应该使用产品和商店之间的m:n关系并删除商品的ShopID。因此,您可以在不同的商店中使用相同的产品,这也是产品的相同问题。

问候,拉尔斯

+2

如果店主不同,他绝对应该避免使用产品和商店之间的多对多关系。想象一下,有相同的产品,但价格不同或其他属性不同。 – 2010-07-13 12:35:43

+0

@narcisradu所以你会有每个商店的产品表?在我的示例shop_products(...,sProduct_price,sProduct_stock) – DRL 2010-07-13 13:05:15

+1

@DRL中,将店铺特定参数添加到shop_products()表格非常简单:虽然技术上确定您店铺和产品之间的M2M可能不合需要。作为店主,我希望我的数据与其他店主的数据完全分开,即使两组数据都在同一个数据库中。不,每个商店的单独产品表都是无稽之谈,但是,您确实需要商店和产品之间的1对M关系。这可以防止商店之间的数据纠缠,并将大大简化单个商店的产品数据导入和导出。这很重要,因为作为一名店主,我想迅速建立并能够快速离开。 – 2010-07-13 14:36:01

2

从设计的角度来看,不需要存储冗余数据。在你的情况下,它可能是。尝试做一些测试,如果查询时间由于冗余而得到改进,那么您应该继续进行非规范化。