【问题标题】:Is it better to store redundant information or join tables when necessary in MySQL?在 MySQL 中必要时存储冗余信息或连接表是否更好?
【发布时间】:2011-03-15 07:14:36
【问题描述】:

我有一个在线商店,用户可以在其中拥有拥有自己产品的小商店。这些产品中的每一个都可以有与之相关的问题,并且商店的所有者有能力回答这些问题。此信息存储在 3 个表中,一个“问题”(QuestionID,ProductID,...)表,一个“产品”(ProductID,ShopID,...)表和一个“商店”(ShopID,OwnerID,...)桌子。

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

【问题讨论】:

  • 非常感谢大家的有用回答。我几乎确信存储冗余信息会更好,但我今天学到了一些新东西。有人指出,最好在产品和商店之间建立 M:M 关系,但这没有任何意义(在这种情况下!),因为店主完全不同(甚至运费等也完全分开)。因此,几家商店不可能共享一种产品(即使可以说是同一种产品)。

标签: php mysql database database-design e-commerce


【解决方案1】:

加入并避免冗余信息几乎总是更好。仅当您必须这样做才能达到性能目标时才应该 denormalize - 直到您首先尝试使用 normalized 表时才知道是否需要这样做。

请注意,非规范化有助于提高读取性能,但代价是会减慢写入速度,并使编码错误更容易导致数据不同步(因为您将相同的内容存储在您现在拥有的多个位置确保全部更新)。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 仅对小型数据库而言,连接将非常便宜。如果您正在考虑产品表中 shopID 索引的基数,则连接所需的时间可能很长。
    • @narcisradu - 是的,我之前不得不诉诸于此,但我要说的是,只有在执行计划显示有案例时才应该这样做。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      我认为您的设计还可以。我不会将 ShopID 添加到表问题中。您应该在必要时使用连接。

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

      问候,拉斯

      【讨论】:

      • 如果店主不同,他绝对应该避免在产品和商店之间使用多对多的关系。假设有相同的产品,但价格不同或任何其他属性不同。
      • @narcisradu 这样您就可以为每个商店提供一个产品表吗?在我的示例 shop_products(..., sProduct_price, sProduct_stock) 中将商店特定参数添加到 shop_products() 表中非常简单
      • @DRL:虽然技术上没问题,但您在商店和产品之间的 M2M 可能是不可取的。作为店主,我希望我的数据与另一个店主的数据完全分开,即使两组数据都存在于同一个数据库中。不,每个商店单独的产品表是无稽之谈,但是是的,您确实希望商店和产品之间存在一对多的关系。这可以防止商店之间的数据纠缠,并将大大简化单个商店的产品数据的导入和导出。这很重要,因为作为店主,我想快速设置并能够快速离开。
      • @DRL:不,他在产品表中已经有shopid。据我了解,没有“全球”产品。每家商店都有自己的产品(或者可能有几家商店会有相同的真实产品,但它们会被认为是不同的,因为它们不相关)。正如 OP 所说,它是一个在线商店门户,里面有不同且可能不相关的在线商店,因此即使真实产品相同,产品之间也没有关系。
      【解决方案5】:

      您应该在问题和产品之间建立多对多的关系:

      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 等)

      【讨论】:

      • 我认为这里不需要多对多的关系。此外,这些表是一对多的,因此它可能是非规范化的主题。
      • 只是一个注释;如果您感到困惑,“问题答案”将是 product_questions 表中的一列
      • @narcisradu m2m 在这种情况下显然是必需的;商店可以有很多产品 - 一个产品可以在很多商店:一个问题涉及很多产品 - 一个产品可以有很多问题。
      • @DRL 正如我在之前的评论中所说,如果店主不同,那么我们不是在谈论同一种产品。请跳出框框思考,而不仅仅是从数据库规范化的角度。
      • @narcisradu 我已经回复了你之前的评论
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-25
      • 2021-12-31
      • 1970-01-01
      相关资源
      最近更新 更多