2

我在 MySQL 中为电影建立了一个评级系统,但问题是,当我的查询汇总所有评级并对其进行划分时,它可能必须汇总数百万条记录。

我想到的一种解决方案是基本上将评分缓存在 memcached 中,并且只对不经常使用的项目进行评分操作。然而即使那样,对于那些没有被很多评价的电影,如果有人去检查评分,如果它必须计算很多行,查询可能需要很长时间。

我想到的另一个解决方案是构建一个不断更新表的临时表,但是如果电影的评分很高并且有人试图访问它怎么办,我相信 INNODB 确实行锁定,所以这会导致死锁或从长远来看?

4

1 回答 1

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 ;
于 2010-07-15T03:43:45.327 回答