Как правильно хранить оценки для постов, но быстро сортировать посты по средней оценке?

Есть посты о фильмах. Таких постов очень много. У каждого фильма есть рейтинг от 1 до 10. Понятное дело, если все нормализовать, то все фильмы лежат в одной таблице, все рейтинги в другой. Но встает задача за все время вывести топ 100 фильмов с максимальными средним рейтингом.

На ум приходит два варианта:
1) мы могли бы просто взять все рейтинги, сгруппировать по фильмам, посчитать средние, взять топ сто средних. Но это как будто неэффективно
2) когда происходит добавление очередного рейтинга, помещать его в таблицу, но и тут же пересчитать его, и дописать в специальную колонку с фильмом. Это звучит эффективно для выборки, но как будет дело обстоять с конкурентной записью? Или транзакция будет ставить в очередь при одновременном добавлении двух оценок?

А может есть другие практики?
  • Вопрос задан
  • 645 просмотров
Решения вопроса 1
inoise
@inoise
Solution Architect, AWS Certified, Serverless
Как уже правильно было сказано должно быть:
  • таблица с постами
  • таблица с оценками
  • таблица с рейтингом

Прим. Не обязательно таблица, не обязательно база реляционная - для задачи это не играет никакой роли

Эти 3 сущности напрямую ни через одну логику влиять друг на друга не должны, ибо может привести к довольно печальным последствиям.

Что касается транзакций - там много чего интересного может происходить, включая блокировки, но самое главное что не стоит выносить данную логику на соединение клиента - при увеличении размера базы будет расти и время запроса, а там и другие интересные последствия. Но! Есть решение.

Для того чтобы сделать все красиво существуют Message Brokers (RabbitMQ, Kafka, ... да какой угодно в принципе - выбор зависит от требований к системе).
Архитектура такая:
  1. пользователь оставляет оценку к посту
  2. оценка сохраняется в базе оценок
  3. после сохранения в брокера падает сообщение "у поста 12345 новая оценка" (сама оценка для этого кейса не важна, но ее можно тоже указать)
  4. клиент счастливо идет дальше серфить интернеты, не ожидая обработки всякой логики, которую задумал программист
  5. на той стороне брокера сидит маленький демон и слушает эти события
  6. при появлении события демон моментально пересчитывает рейтинг поста и обновляет его в отдельной таблице
  7. при росте нагрузки на демона ничего страшного не происходит - все сообщения встают в очередь и ждут обработки
  8. ну, если хочется совсем все быстро обрабатывать - запускаем ХХХ этих демонов чтобы пережевывали за раз больше информации


Вот так. Надеюсь вам поможет такой маленький пример их мира энтерпрайз-разработки
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
x67
@x67
Когда речь идет о рейтинге фильма, а не об необходимом уровне погружения графитовых стержней в ядро реактора, можно пренебречь точность и актуальностью. Средний рейтинг хранить вместе с фильмом и пересчитывать его время от времени. Это будет самым быстрым решением аак с точки зрения записи, так и чтения.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы