2013-03-18 68 views
3

我需要一个查询涉及到与以下两个表设置的审查系统的帮助。网站的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表,以便我知道以下详细信息(对于每个单独的评论):

 
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 

(并绑定适宜:

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

我曾尝试使用下面的查询,这是不符合我的权利坐在完成了这个用户名和:为itemid)

所以这个查询完美工作,并完成我需要它。但是,这是一个很大的加入,我几乎肯定有一个更好的方式来做到这一点,但我似乎无法找出任何结果。

难道有人请指出我在正确的方向如何以更清洁的方式完成此?

我试了一下:

我试着做一个GROUP_CONCAT,列出一个包含所有用户ID和喜欢一个字符串,并且然后运行一个正则表达式查找用户的ID来看看如果他们已经对评论投了赞成票,但这也感觉真的不干净。

非常感谢您提供任何帮助。

+0

不要在大型​​网站上使用'JOIN's。当你有两台以上的服务器时,它会导致你重写很多代码。 – TheJSB 2013-03-18 19:14:34

+3

可以考虑使用-1(downvote)和+1(upvote)的整数投票列来计算上下选票,可以很容易地用'SUM'来获得总分。顺便说一句,当要求对现有查询进行改进时,如果您可以举一个SQLFiddle示例,那么它确实很有帮助 - 您可以在那里设置模式和数据,这样做可能会让人们倾向于改进它。 – halfer 2013-03-18 22:17:16

+0

@halfer这是一个好主意的投票,谢谢你。至于小提琴,我认为这不重要,因为这只是一个关于最佳做法的开放式问题。这些左连接实际上并不认为是最佳实践解决方案,他们觉得过度杀伤,我只是在寻找指导,而不是为别人写我的代码。谢谢! – Leng 2013-03-18 22:59:54

回答

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件事情你想知道,这给你一个快速总结2列(和对这些结果快速减法),以准确得到你要找的东西。这会使您将queries_thumbs表查询为2x,一次为总数,一次为用户特定操作。

+0

这是一个优雅,辉煌的解决方案,使我的系统性能翻了一番。非常感谢您花时间帮助我! :) – Leng 2013-04-16 21:06:04

+2

不客气,只是付出了堆栈溢出多年来给我的所有帮助。 – invertedSpear 2013-04-16 21:16:23

0

不知道是否能够提高你的查询性能,但你可以尝试做计数的子选择

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

谢谢你的回应,西蒙。不幸的是,你是正确的,这个子查询风格不会提高性能,因为'reviews_thumbs'仍然需要被查询4次。 – Leng 2013-03-25 22:20:34