哪个更好的数据库设计?

问题描述:

给定一个像*这样的网站,创建num_comments列来存储提交的评论数量,然后在做出评论时更新它,或者只是使用COUNT函数查询行数,会更好吗?看起来后者更具可读性和优雅性,但前者效率更高。 SO认为什么?哪个更好的数据库设计?

+1

如果SO需要连接表以显示注释计数,则它不会存在。但是,担心当你的网站每天被数百万的综合浏览量击中时会发生什么,我们只是说,不成熟 - 所以在你自己的项目中,使用“COUNT”。 – Jon 2011-03-17 21:01:01

+5

不要过早优化。保持数据库规范化,直到你需要对它们进行非规范化。 – Quentin 2011-03-17 21:02:51

+1

@Jon:有趣......你能详细说明还是提供链接?我在关系模型之外坚果,但总是准备学习... – 2011-03-17 21:03:58

绝对要使用COUNT。存储评论的数量是一个经典的去规范化,会产生令人头疼的问题。它的检索效率稍高一些,但是插入的代价要高得多:每个新的注释不仅需要插入到注释表中,而且需要在包含注释计数的行上写入锁。

+1

这不是反规范化更多的优化,需要一些触发器 - 几乎不是头疼! – 2011-03-17 22:04:53

+0

@JonBlack - 是的,这是一个优化(尽管如我在答案中所说的那样,“优化”是否值得不那么清楚)。同时,它绝对是一种反规范化。特别是,'num_comments'列违反了第三范式,因为它引入了非关键依赖关系 - 一个不依赖于关键字的值,但在这种情况下,这些关键值最可能来自完全不同的表。至于令人头痛的问题,这个问题不仅仅是写出“一些触发器”,而且随着数据库的发展,必须保持触发器以及其他一切。 – 2017-10-31 01:09:15

前者未规范化,但会产生更好的性能(假设读取次数多于写入次数)。

后者更规范化,但需要更多的资源,因此性能较差。

哪个更好归结为应用需求。

我会建议计数评论记录。虽然其他方法会更快,但它可以提供更清晰的数据库。添加计数列将是一种数据重复,更不用说额外的代码步骤和插入。

如果您希望获得数百万条评论,那么您可能需要选择count列方法。

我同意@Oded。这取决于应用程序的要求,也就是如何与现役的网站,但这里也是我的两分钱

  • 我会尽量避免将不得不由触发器进行写操作,更新以新时评论张贴表被添加。
  • 如果您担心报告数据,那么请勿在事务性系统上执行此操作。创建一个报告数据库并定期更新。

“正确的”设计方法是使用另一个表,加入它并COUNT。这与database normalization教导的一致。

规范化的问题是它不能缩放。皮肤只有很多种方法来处理猫,所以如果你每天有数百万个查询,而且其中很多涉及到表X,那么数据库的性能会低于地面,因为服务器还必须处理并发写入,交易等。

要解决这个问题,一般的做法是sharding。分片具有副作用,表中的行不存储在相同的物理位置,并且主要的后果是您不能再JOIN;你怎么能JOIN对半桌,并收到有意义的结果?显然,尝试JOIN针对表的所有分区并合并结果将比疾病更糟糕。

因此,您会发现,不仅您在实践中使用的替代方案可以实现高性能,而且还有更激进的步骤可供工程师采用。

当然,除非你有性能问题,分片或甚至去规范化只是让你的生活更难以没有实际的好处。

+0

这是如何将标度倾斜到包含num_comments列的? – 2011-03-17 21:37:14