我正在使用php/mysql构建一个网站,那里会有帖子和评论。
帖子需要显示他们的评论数量。我在Posts表中有count_comments
列,每次创建或删除评论时都会更新它。
最近有人建议我,用这种方式去规范化是个坏主意,我应该使用缓存。
我的看法是:你做的是正确的。原因如下:
将字段count_comments视为而非是数据模型的部分-这很容易证明,您可以删除此字段的所有内容,重新创建它很简单。
相反,将其视为缓存,其存储空间仅与帖子位于同一位置-非常智能,因为无论何时您都可以免费查询帖子
我不认为这是一个糟糕的方法。
我认识到的一件事是,当代码库通过更严格的方法扩展时,很容易引入副作用。好的部分是,在某个时候,数据库中的行数将不得不被计算或跟踪,实际上没有办法摆脱这种情况。
我不会反对这种做法。还有其他获得评论数的解决方案。看看哪个最快?SELECT SQL_CALC_FOUND_ROWS FROM `table`或SELECT COUNT(*)
该解决方案在选择时速度较慢,但需要较少的代码来跟踪注释计数。
我要说的是,您的方法避免了LIMIT DE优化,这是一个优点。
这是一个几乎从不需要的优化,原因有两个:
1) 适当的索引将使简单计数变得非常快确保您的comments.post_id
列具有索引。
2) 当您需要缓存此值时,您将需要缓存更多的值如果你的网站有太多的帖子、评论、用户和流量,以至于你需要缓存评论总数,那么你几乎肯定需要对大部分数据/输出使用缓存策略(将构建的页面保存到静态、memcache等)。毫无疑问,这些策略将包含你的评论总数,使表字段方法变得毫无意义。
我不知道"缓存"是什么意思,我会对我必须提供的其他答案感兴趣:
从数据库中删除多余的信息很重要,而且,以一种"相信者的方式"(意味着我没有真正测试它,它只是推测性的),我认为从数据库中使用SUM()函数是更好的方法。假设你所有的评论都有一个post_id,那么你所需要的就是:
SELECT SUM(id) FROM comments WHERE id = {post_id_variation_here}
这样,您就减少了1个恒定的CRUD,只是为了读取有多少注释并提高性能。
除非你的应用程序每秒没有数百或数千次点击,否则使用这样的SQL语句没有错:
select posts_field1, ..., (select count(*) from comments where comments_parent = posts_id) as commentNumber from posts
无论如何,您都可以缓存页面的html输出。相比之下根本不需要进行数据库查询。
Maby您可以将post和comment表相互连接,并使用mysql函数计算mysql中的注释行数:mysql_num_rows。像这样:
过账表
postid*
postcontent
注释表
commentid
postid*
comment
然后计算mysql中的注释,如:
$link = mysql_connect("localhost", "mysql_user", "mysql_password");
mysql_select_db("database", $link);
$result = mysql_query("SELECT * FROM commenttable WHERE postid = '1'", $link);
$num_rows = mysql_num_rows($result);