计算一个职位的平均评分

hkmswyz6  于 2021-06-20  发布在  Mysql
关注(0)|答案(3)|浏览(387)

我拥有以下实体:

post_id | post_title | post_body
-------------------------------------
1       | First post | Hello, world!

并希望在帖子上注册收视率,比如:

rating_id | rating_user_id | rating_post_id | rating_rating
1         | 23             | 1              | 3.5

我主要关心的问题是,我应该如何检索一个职位的平均评分。我知道我可以使用如下sql查询:

SELECT AVG(rating_rating) FROM post_ratings WHERE rating_post_id = 2;

但每次我都得打电话问这个问题 $post->getAverageRating() -这是一个大的性能问题吗(请记住,每个帖子可能有数千个收视率)
另一种方法是将平均评级存储在 posts 表,让cron作业计算平均值还是什么?
最好的办法是什么?

jtoj6r0c

jtoj6r0c1#

至于性能比较,则取决于
收视率是多么的静态。如果你希望现有的文章有新的收视率,我会去计算他们的飞行无论如何。
多少职位,你会需要相对于整体职位的评级。如果你有数以百万计的职位,需要平均评级只有几千,这是有意义的,做他们分开也。

7rtdyuoh

7rtdyuoh2#

这是一个效率问题
如果和这些评分将叠加到一个大的数额,它将是可取的保存计算出的平均我会添加2列到职位表,平均评分,总评分

ALTER TABLE posts ADD COLUMN average_rating DECIMAL (9,2);
ALTER TABLE posts ADD COLUMN total_ratings UNSIGNED (9) DEFAULT 0;

并在添加新评级时填充它们,这样就不需要cron作业了,请注意计算平均值的查询顺序
mysql+php代码应该类似于:

$query = "UPDATE posts SET total_ratings  = total_ratings + " . $rating_rating . " WHERE post_id = " . $post_id;
    $db->query($query);
    $query = "UPDATE posts SET average_rating = average_rating * (total_ratings -1 / total_ratings) + " . $rating_rating ." / total_ratings WHERE post_id = " . $post_id;
$db->query($query);

这样您就可以立即更新posts表,而无需任何cron作业

fdx2calv

fdx2calv3#

数据库调用是昂贵的,尤其是当您必须平均每次。
与当前解决方案相比,您有以下更为优化的选项。
有一个列,计算和存储一个职位的平均评级时,评级已经由@guy l提到
用ttl(生存时间)实现缓存
例子:

public function getAverageRating() {
     $post_id = 'post' . $this->id;
     if(Cache::has($post_id))
         return Cache::get($post_id);
     $rating = //fetch rating from DB
     Cache::set($post_id, $rating, 120); //ratings will be in the cahce for 120secs
     return $rating
}

希望有帮助。

相关问题