2

假设我有三个规范化表,一个用于线程,一个用于注释,一个用于连接两者。

我想显示线程中的评论数量,这涉及到查找属于某个线程的每条评论。

显然,我不想每次显示页面时都执行此查询,因此我需要将评论数缓存到一个线程。我的两个选择(如我所见)是:

  1. 在线程表中添加 number_comments 行,并在添加/删除评论时更新它。

  2. 将值缓存在内存中,方法是告诉 mysql 缓存它或使用 APC / memchached 之类的东西

每个的优点/缺点是什么?

我认为第一个很简单,性能稍差,但是您有冗余,并且存储比内存便宜很多,尽管它确实用“动态”、不断变化的值弄乱了数据库(另请注意,我会需要为评论保存“upvotes”,所以这个问题适用于多个“动态”值)。

第二个是更好的性能,但它引入了一项新技术,你必须配合它来缓存事物的数量。

这个项目的用户数量相对较少,但我想知道哪个比访问量大的网站更可取(例如,facebook 如何存储评论数量[我猜是数据库和内存中的])。

4

2 回答 2

1

请记住 Donald Knuth 的这句话:

过早的优化是万恶之源。

我认为在这种情况下,缓存或“数据库非规范化”是一个完全有效的选择,但当“正常”方法不再适用时,最好考虑这种选择。

您说您“显然”不想运行额外的查询来获取每个页面视图的评论计数,但实际上并不是那么明显。如果您的数据库配置正确,您应该已经thread_id在评论表中的字段上有一个索引(或者您碰巧调用该字段的任何内容)。运行基于索引字段的查询,特别是当查询仅返回生成的COUNT()字段而不是大量线程列表时,实际上并没有太多开销。我认为只运行该查询并完成它会更容易。

也就是说,当性能需要时,对数据库进行非规范化是有价值的。在这种情况下,我会comments_count在线程表中添加一个字段,每当从表中添加或删除新记录时,该字段就会递增。您需要记住在您的INSERTDELETE查询周围添加额外的代码,并且可能还添加到UPDATE查询中,这取决于您的comments表是否跟踪活动/已删除状态。

同样,在大多数情况下,这是一个过早的优化。您需要问自己的问题是,“这个站点是否如此繁忙/负载如此之重,以至于管理计算字段所增加的复杂性比仅运行快速COUNT()查询成本更低?” 如果是这样,那么一定要选择非规范化路线,但它可能不应该是您选择的第一个选择。

于 2013-01-18T02:54:38.540 回答
0

我认为添加 number_comments 字段不是要走的路。一方面,保持最新是一件痛苦的事情,并且需要额外的代码。它还为您的数据库增加了冗余。

这给我们留下了两个选择。您可以在页面顶部执行查询,获取每个 id 的计数(这应该在一个查询中是可能的 - 而不是每个线程一个)。这很简单,不应该太慢。

如果您确定性能是/将是一个问题并且这是瓶颈,那么 APC 和 Memcache 都是不错的选择。虽然这确实添加了一项新技术,但在 PHP 中设置它非常简单,这意味着将来缓存其他项目更简单。

于 2013-01-18T02:00:43.717 回答