2013-03-18 67 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