[英]Calculating average rating on a post
I have the following entity: 我有以下实体:
post_id | post_title | post_body
-------------------------------------
1 | First post | Hello, world!
and would like to register ratings on the post, like so: 并希望在帖子上注册评分,例如:
rating_id | rating_user_id | rating_post_id | rating_rating
1 | 23 | 1 | 3.5
My main concern/question is, how I should retrieve the average rating for a post. 我主要关心的问题是如何获取帖子的平均评分。 I know I can do this by using an SQL query like so:
我知道我可以这样使用SQL查询来做到这一点:
SELECT AVG(rating_rating) FROM post_ratings WHERE rating_post_id = 2;
but I would have to call this query everytime I'd do $post->getAverageRating()
- is this a big performance issue? 但是我每次执行
$post->getAverageRating()
都必须调用此查询-这是一个很大的性能问题吗? (keeping in mind that there could be thousands of ratings per post) (请注意,每个帖子可能会有数千个评分)
An alternative would be to store the average rating in a new column in the posts
table and have a cron job calculate the average or something? 一种替代方法是将平均评分存储在
posts
表的新列中,并让cron作业计算平均值或其他内容?
What is the best way of going about this? 最好的方法是什么?
As for comparing performance- It depends on 至于比较性能-这取决于
This is an issue of efficiency 这是效率问题
If and which these ratings will stack to a large amount, it would be preferable to save the calculated average I would add 2 columns to the posts table, average_rating, total_ratings 如果这些评级会与之叠加,那么最好保存计算出的平均值,我会在posts表中添加2列,average_rating,total_ratings
ALTER TABLE posts ADD COLUMN average_rating DECIMAL (9,2);
ALTER TABLE posts ADD COLUMN total_ratings UNSIGNED (9) DEFAULT 0;
And populate them whenever a new rating is added, so you won't need a cron job Notice the order of the queries to calculate the average 并在添加新评分时填充它们,因此您不需要进行cron作业请注意查询的顺序以计算平均值
The MySQL + PHP code should be something like: 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);
This way you can update the posts table immediately without any cron job 这样,您无需任何cron作业即可立即更新posts表
Database calls are expensive especially when you have to average every time. 数据库调用非常昂贵,尤其是在每次必须求平均值时。
You have the following options that are more optimal compared to your current solution. 与当前的解决方案相比,您拥有以下最佳选择。
Have a column that calculates and stores the average rating of a post when the rating has been made like mentioned by the @Guy L 有一列计算和存储帖子平均评分的列,例如@Guy L提到的那样
Implementing a Cache with TTL(Time To Live) 用TTL实现生存时间
example: 例:
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
}
Hope it helps. 希望能帮助到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.