[英]Calculating average rating on a post
我有以下實體:
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作業計算平均值或其他內容?
最好的方法是什么?
至於比較性能-這取決於
這是效率問題
如果這些評級會與之疊加,那么最好保存計算出的平均值,我會在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;
並在添加新評分時填充它們,因此您不需要進行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);
這樣,您無需任何cron作業即可立即更新posts表
數據庫調用非常昂貴,尤其是在每次必須求平均值時。
與當前的解決方案相比,您擁有以下最佳選擇。
有一列計算和存儲帖子平均評分的列,例如@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
}
希望能幫助到你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.