2010-07-14 82 views
2

我已經爲MySQL中的電影構建了評分系統,但是擔心的是,當我的查詢總結所有評分並將其分開時,它可能必須總計數百萬和數百萬條記錄。評分系統查詢

我想到的一個解決方案是基本上緩存memcached中的評級,並且只對那些用處不大的項目進行評級操作。然而即使如此,對於那些沒有被評價很多的電影,如果有人去檢查評級,如果需要計算很多行,查詢可能需要很長時間。

我想到的另一個解決方案是建立一個不斷更新表的臨時表,但是如果電影被評爲很多並且有人試圖訪問它,那麼我相信INNODB會進行行鎖定,所以這個導致僵局或長期的事情?

回答

4

由於評分相當靜態且數據集很大,因此您可以在用戶對影片評分時緩存(反規格化)影片記錄中的數據。你需要記錄兩票和總票數,所以平均數是準確的。您的電影評級是在您需要時動態計算的。這裏的架構:

create table movie as (
movie_id int not null primary key, 
-- your current columns 
vote_count int, 
vote_sum int 
); 

然後使用視圖來助陣

create view movie_view as 
select 
    *, 
    vote_sum/vote_count as vote_average 
from movie; 

假設你有一個表,看起來像這樣:

create table user_movie_vote (
user_id int references user, 
movie_id int references movie, 
vote int 
); 

,你可以使用觸發器來保持投票總數最新爲您:

delimiter ~ 
create trigger movie_vote_trg after insert on user_movie_vote 
for each row 
begin 
    update movie set 
    vote_count = vote_count + 1, 
    vote_sum = vote_sum + new.vote 
    where movie_id = new.movie_id; 
end~ 
delimiter ; 

如果投票可以更新,你將需要:

delimiter ~ 
create trigger movie_vote_trg after update on user_movie_vote 
for each row 
begin 
    update movie set 
    vote_sum = vote_sum + new.vote - old.vote 
    where movie_id = new.movie_id; 
end~ 
delimiter ; 

如果投票可以刪除,你將需要:

delimiter ~ 
create trigger movie_vote_trg after delete on user_movie_vote 
for each row 
begin 
    update movie set 
    vote_sum = vote_sum - old.vote, 
    vote_count = vote_count - 1 
    where movie_id = new.movie_id; 
end~ 
delimiter ; 
+0

這是優秀的,我需要的!謝謝 – 2010-07-17 02:42:11