MySQL网站评论系统

时间:2013-03-18 19:06:34

标签: php mysql

我需要帮助查询涉及使用以下两个表设置的审阅系统。

reviews
-------
id  date    user_id item_id rating  review
1   02-2012 40      456     3       'I like it'
2   03-2012 22      342     1       'I don't like it'
3   04-2012 45      548     0       'I hate it'
reviews_thumbs
--------------
review_id   user_id like
1           22      1
1           45      -1
2           40      -1
3           22      1

“reviews_thumbs”表用于跟踪评论的upvotes和downvotes,因此评论可以按质量进行评级。在'like'列中,1表示upvote,-1表示downvote。 (评论表中的rating列是星系,不相关。)

加载评论时,我需要以这样一种方式加入reviews_thumbs表,以便我知道以下详细信息(对于每个单独的评论,它们都会被返回):

1.  The total number of upvotes
2.  The total number of downvotes
3.  Whether the current active user has upvoted or downvoted the review

我使用以下查询完成了此操作,而这个查询并不适合我:

SELECT `reviews`.*,
COUNT(upVoteTable.`user_id`) AS upVotes,
COUNT(downVoteTable.`user_id`) AS downVotes,
COUNT(userUpTable.`user_id`) AS userUp,
COUNT(userDownTable.`user_id`) as userDown

FROM `reviews`

LEFT JOIN `reviews_thumbs` AS upVoteTable
ON upVoteTable.`review_id` = `reviews`.`id`
AND upVoteTable.`like` = 1

LEFT JOIN `reviews_thumbs` AS downVoteTable
ON downVoteTable.`review_id` = `reviews`.`id`
AND downVoteTable.`like` = -1

LEFT JOIN `reviews_thumbs` AS userUpTable
ON userUpTable.`review_id` = `reviews`.`id`
AND userUpTable.`like` = 1
AND userUpTable.`user_id` = :userid

LEFT JOIN `reviews_thumbs` AS userDownTable
ON userDownTable.`review_id` = `reviews`.`id`
AND userDownTable.`like` = -1
AND userDownTable.`user_id` = :userid

WHERE `item_id`=:itemid

GROUP BY `reviews`.`id`

ORDER BY `date` DESC

(并绑定适当的:userid和:itemid。)

因此,此查询完美运行并完成了我需要它。但这是很多加入,我几乎是肯定的,必须有一个更好的方法来做到这一点,但我似乎无法搞清楚。

有人可以指点我如何以更清洁的方式实现这个目标吗?

我尝试过的事情:

我尝试过做一个GROUP_CONCAT,列出一个包含所有用户id和喜欢的字符串,然后运行一个正则表达式来查找用户的id以查看他们是否已经对评论进行了投票,但这也感觉到了真的不干净。

提前感谢您提供的任何帮助。

2 个答案:

答案 0 :(得分:1)

您可以将reviews_thumbs修改为更像这样:

reviews_thumbs
--------------
review_id   user_id upvote downvote
1           22      1      0
1           45      0      1
2           40      0      1
3           22      1      0

这可以有效地存储重复的信息,但是当你有一个好的目的时,这没关系。你真的有两件事你想知道,这给你一个2列的快速总和(以及对这些结果的快速减法),以准确得到你想要的东西。这可以减少你将reviews_thumbs表查询为2x,一次查询总数,一次查询用户特定操作。

答案 1 :(得分:0)

不确定这是否会提高您的查询效果,但您可以尝试在子选择中进行计数

SELECT `reviews`.*,
(SELECT count(*) FROM reviews_thumbs t WHERE t.review_id =reviews.id AND t.like = 1) AS upVotes
...
FROM reviews
...