Как моделировать рейтинги продуктов в базе данных?

Каков наилучший подход к хранению рейтингов продуктов в базе данных? Я имею в виду следующие два (упрощенные и предполагающие MySQL db) сценарии:

Создайте два столбца в таблице продуктов, чтобы сохранить количество и сумму всех голосов соответственно. Используйте столбцы, чтобы получить среднее значение во время выполнения или с помощью запроса.

Этот подход означает, что мне нужно только получить доступ к одной таблице, упрощая вещи.

Нормализовать данные, создав дополнительную таблицу для хранения оценок.

Это изолирует данные рейтингов в отдельной таблице, оставляя таблицу продуктов для предоставления данных о доступных продуктах. Хотя для этого потребуется соединение или отдельный запрос для оценок.

Какой подход лучше, нормирован или денормализован?

Ответы

Ответ 1

Рекомендуется использовать другую таблицу для оценок, чтобы поддерживать динамику. Не беспокойтесь о сотнях (или тысячах или десятках тысяч) записей, что все арахисы для баз данных.

Предложение:

таблица продукты
- id
- название
- etc

таблица products_ratings
- id
- productId
- оценка
- дата (при необходимости)
- ip (при необходимости, например, для предотвращения двойного рейтинга)
- etc

Получить все оценки для продукта 1234:

SELECT pr.rating
FROM products_ratings pr
INNER JOIN products p
  ON pr.productId = p.id
  AND p.id = 1234

Средний рейтинг продукта 1234:

SELECT AVG(pr.rating) AS rating_average -- or ROUND(AVG(pr.rating))
FROM products_ratings pr
INNER JOIN products p
  ON pr.productId = p.id
  AND p.id = 1234";

И так же легко получить список продуктов вместе со своим средним рейтингом:

SELECT
  p.id, p.name, p.etc,
  AVG(pr.rating) AS rating_average
FROM products p
INNER JOIN products_ratings pr
  ON pr.productId = p.id
WHERE p.id > 10 AND p.id < 20 -- or whatever

Ответ 2

Я знаю, что мой ответ - это не то, о чем вы действительно просите, но вы, возможно, захотите, чтобы это облегчало то, что новые продукты с вашей системой почти никогда не могут превзойти старые продукты. Скажите, что вы получите продукт с рейтингом 99%. Было бы очень сложно получить новые продукты, если вы сортируете продукты с наивысшим рейтингом.