添加额外的字段以防止需要联接

  • 本文关键字:字段 添加 mysql sql
  • 更新时间 :
  • 英文 :


考虑到模式设计,为了防止必须进行联接,添加我原本不需要的额外表字段是否合适?例:

products_table
| id | name | seller_id
users_table
| id | username |
reviews_table
| id | product_id | seller_id |

对于评论表,我可以使用产品表上的联接来获取卖家的用户 ID。如果我将其排除在评论表之外,则必须使用联接来获取它。通常有些表需要多个联接来获取某些信息,而我可以让我的应用程序将冗余数据添加到表中。就模式设计而言,哪个更正确?

你似乎过于关心JOIN的性能。 通过适当的索引,性能通常不是问题。 事实上,在某些情况下,JOIN更快 - 因为数据在两个表中比一遍又一遍地存储字段更紧凑(不过,这更适用于字符串而不是整数(。

如果要有多个表,请使用JOIN访问"查找"信息。 在某些情况下,您可能希望对信息进行非规范化。 但总的来说,你不会。 过早的优化是许多糟糕设计的根源。

假设您添加了一个列reviews.seller_id并用值填充它,然后几周后您发现这些值并不总是与products_table中的卖家相同。

换句话说,以下查询应始终返回计数 0,但如果有一天它返回计数 6怎么办?

SELECT COUNT(*)
FROM products_table AS p
JOIN reviews_table AS r USING (product_id)
WHERE p.seller_id <> r.seller_id

这意味着一个表有一些更新,但另一个表没有更新。它们没有更新以保持seller_id同步。

这是怎么发生的?哪个表已更新,哪个表仍具有原始seller_id?哪一个是正确的?更新是故意的吗?

您开始研究 6 个案例中的每一个,验证谁是正确的卖家,并更新数据以使它们匹配。

然后下周,不匹配的卖家数量为 1477。您的代码中必须有一个错误,该错误允许更新一个表而不更新另一个表以匹配。现在你有一个更大的数据清理项目,以及一个错误搜索来找出这是如何发生的。

你还有多少次对其他列做过同样的事情——将它们复制到相关表中以避免连接?那些创建不匹配数据的人是否也在创建?您将如何检查它们?您需要每晚检查它们吗?它们能被纠正吗?

这是您在使用非规范化时遇到的麻烦,换句话说,冗余存储列以避免联接、避免聚合或避免昂贵的计算,以加快某些查询的速度。

事实上,你不会避免这些操作,你只是将这些操作的工作转移到更早的时间。

可以使其无缝运行,但对于编码人员来说,开发和测试完美的代码并修复后续代码错误和不可避免的数据清理工作要做更多的工作。

这取决于每个具体情况。纯粹就架构设计而言,不应有任何冗余列(请参阅数据库规范化(。但是,在实际情况下,有时拥有冗余数据是有意义的;例如,当遇到性能问题时,可以牺牲一些内存以使 SELECT 查询更快。

今天添加冗余列会让你明天诅咒。如果您正确处理数据库中的键,性能不会对您造成不利影响。

最新更新