重复数据以提高效率

时间:2012-03-16 20:57:55

标签: mysql database database-design

假设我有一个表thread和一个表response,我将线程和响应存储在用户在论坛中提交的线程中。

我正在计算给定线程的响应:

SELECT COUNT(id)
FROM response
WHERE container_id = THREAD_ID

但是,在线程表中只有另一个字段(number_of_responses或类似的东西)更好,每次响应时都加1吗?然后查询变成这样的东西:

SELECT number_of_responses
FROM thread
WHERE id = THREAD_ID
LIMIT 1

是的,我正在重复数据,但这种方法效率不高吗?或者出于某种原因不建议使用它?

4 个答案:

答案 0 :(得分:0)

我想这部分取决于你如何使用数据。但我知道我使用的很多论坛都列出了所有主题标题的回复数量,所以如果你要在线程列表和搜索结果中显示这些信息,那么这是一个很好的选择。

如果您只在线程打开时显示它,那么您也可以避免冗余。

答案 1 :(得分:0)

我认为您不应该使用number_of_responses,因为它是生成的数据。您应该只在数据库中保存数据库无法自己计算的内容。 当您遇到慢速表时,您应该添加索引或以其他方式优化表。

答案 2 :(得分:0)

保持计数列,而不是100%标准化,将导致更快的页面加载时间,尤其是当响应表开始变得非常大时。如果您的响应表包含文本列,我怀疑它确实如此,那么计数会比您有小行(整数,变量等)行的速度慢得多。

如果您决定采用这种方式,我建议在响应表上使用触发器来更新相应线程行的计数。这样您就不必在代码中对其进行管理。

答案 3 :(得分:0)

存储计数对于其他答案中已经给出的所有原因都是一个坏主意。而不是运行单独的查询来计算响应,您可以简单地将连接添加到响应表 -

SELECT t.*, COUNT(*) 
FROM thread t
LEFT JOIN response r
    ON t.id = r.container_id
GROUP BY t.id

在LEFT JOIN上使用count会非常​​快,因为它可以使用外键应该存在的索引。