Do not store a record of each rating unless you absolutely need them specifically. An example of such a case could be a psychological experiment that tends to analyze specific properties of the raters themselves. So, yeah! You'd have to be just as crazy to store each rate in a separate record.
Now, coming to the solution, add two more columns to your product table: AverageRating
and RateCount
.
What would you store in them? Well, suppose you have an already-calculated average of the two numbers: 2 and 3, which is 2.5; having a new rate of 10, you'll multiply the average (2.5) by the rate count (2 in this case). Now, you have 5. Add this result to the new rate value (10) and divide the result by 3.
Let's cover all the above in a simple formula,
(AverageRating * RateCount + NewRateValue) / (RateCount + 1)
So (2.5 * 2 + 10) / (2 + 1) = 5
.
Calculate the average on the server-side (not in your database) and store the average in the AverageRating
column and the rate count in the RateCount
column.
Simple, right?!
Edit
This solution doesn't require storing each rating separately as long as no review, edit or delete operations are involved. Yet, for such cases; let's assume that you've got a review with a rating of 3 that the owning user would like to modify to 4. Then, the formula to recalculate the average rating would be like this,
(AverageRating * RateCount - OldRateValue + NewRateValue) / RateCount
References
https://math.stackexchange.com/a/106314