2012-03-16 74 views
0

比方说,我有一个表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 

是的,我会重复数据,但不是这种方法更有效吗?还是不推荐出于某种原因?

+0

THREAD_ID在表中是唯一的吗?如果没有,那么你的方法不在2NF。 – danihp 2012-03-16 21:03:29

回答

0

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

+0

@IcedD​​ante说:这是一个选项,但它取决于你必须进行多少行。我最近做了并且从table1中计数(id),其中a = 1'在超过4000万行的表上并且是即时的,所以它不应该是个问题。 另外:存储过程使数据库查询更快。 – ydd1987 2012-03-16 21:09:22

+0

我认为这是一个很好的标准,只存储数据库本身无法计算的内容 – federicot 2012-03-17 08:50:21

0

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

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

0

保持计数列,虽然不是100%正常化,但会导致更快的页面加载时间,特别是当您的响应表开始变得非常大时。如果您的响应表包含文本列,我怀疑它的确如此,但计数速度会比如果您有小尺寸的行(整数,变量等)慢得多。

如果您决定走这条路线,我会建议在响应表上使用触发器来更新相应线程行的计数。这样你就不必在代码中管理它。

+0

'COUNT(*)'能够使用索引,因此文本列不会影响计数性能。 – 2012-03-16 21:18:46

0

存储计数是一个坏主意,因为其他答案已经给出了所有原因。而不是运行单独的查询来算,你可以简单的左加入响应表的答复 -

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

使用左侧计数JOIN会非常快,因为它可以使用应该已经存在外键索引。