Хочу хранить подписки пользователей на разделы сайта (категории новостей) в отдельном множестве, точнее двух:
первое множество 1 user_id => array( cat_id ) - для того, чтобы знать все подписки пользователя
второе множество 1 cat_id => array( user_id ) - для того, чтобы знать всех подписанных пользователей на категорию
Правильное ли это решение?
Второй вопрос вытекающий из первого:
Необходимо пользователю показывать количество обновлений с момента его просмотра этой категории, т.е. показать ему +3 новые новости с момента его отсутствия. Только тут не могу решить задачу, и понять как ее решить. В случае с комментариями к новости, там можно сравнивать по дате (пользователь подписался на новость/статью/вопрос и мы запомнили дату его последнего просмотра, потом когда написали новые комментарии, просто сравнили сколько добавилось новых комментариев с момента его просмотра, и когда пользователь зайдет в статью, то обновляем дату и все комментарии становятся прочитанными - тут все просто).
Но как это сделать с постами, я не понимаю. Опишу суть непонимания:
В раздел добавили +5 новых статей, напротив категории можно указать +5. Но вот пользователь зашел в категорию и у него в ней 5 статей помечены как новые, он посмотрел одну, должно быть теперь +4, потом еще одну и ему показывает +3, и т.д. тут одним обновлением даты, как с комментариями, не пройдет. Тут видимо необходимо хранить ид всех новых статей в отдельном множестве для пользователя.
Подскажите, пожалуйста, как решить этот вопрос?
Как сферическая задача в вакууме нет, не правильное, т.к. данные дублируются два раза. Потенциально в схеме заложена неконсистентноость данных (например, в первом множестве есть определенная cat_id, в самом множестве cat_id такого user_id). На практике бывает по разному.
Как я уже говорил в теме "Как устроен трекер на Хабре" смысл абсолютно тот же. Только в роле поста у нас идет лента новостей (а в роде комментариев
Но вот пользователь зашел в категорию и у него в ней 5 статей помечены как новые, он посмотрел одну, должно быть теперь +4
Нет, должно быть 0. +4 означало бы, что пользователь должен смотреть все посты чего понятное дело не требуется.
@alekciy решение , где нужно сделать 0, аналогичное как и с комментариями, тут все просто и можно (нужно) хранить все в бд. Но когда необходимо запоминать, что новое, а что просмотренное, мне не понятно. отписал в комментарии ниже пример.
@alekciy с циферкой показывающей +4 к статьям/комментариям сравнивая даты понятно. Но как тогда уведомлять пользователя по почте о новых статьях? При каждой новой статье отправляется письмо (тем, кто подписался по почте) и необходимо этот момент зафиксировать, при новой статье еще раз отправить, и опять сохранить, что отправили. Фиксировать придется все новые статьи, а не только сравнение дат. Потом пользователь зашел на сайт и удалять эти ид статей из базы/редиса. Тут уже возникают другие задачи, которые необходимо решать. Одна из них: 20 000 пользователей подписались на один и тот же раздел по почте. В день добавляют 10 статей - итого 200 тысяч емайлов. Очередь большая, есть вероятность того, что пользователь зайдет на сайт в то время, пока очередь еще только будет отсылаться. То есть посмотрит статью раньше, чем отправится уведомление.
@dim4ik так же элементарно через дату последней рассылки новостей для данного юзера. Пользователя же правильно уведомлять каждых Х часов (дней/недель/мецев/лет), а не на каждую новость, т.е. правильный вариант это дайджест. И ни каких проблем с очередью, т.к. письмо должно уходить по факту.
Желающие мониторить добавление новостей в реальном времени используют RSS.
И редис для данной зачади совершенно не требуется.
@alekciy Пользователя же правильно уведомлять каждых Х часов (дней/недель/мецев/лет), а не на каждую новость Может я чего неправильно понял, но я сейчас на уведомление об этом комменте на тостер перешел.
@alekciy Тостер мне отправил два комментария с интервалом 3 минуты по этому вопросу. И присылает по каждому ответу, так как каждый ответ очень важен. На то и подписываются в трекер, а не в ежедневную рассылку.
@alekciy разницу не уловил, так как тостер шлет уведомления о новых вопросах, подписавшимся по тегу ( представим, что человек подписался на новые объявления о продаже на сайте, чтобы не упустить предложение, ну или на раздел сайта с уроками, так как уроки выходят редко, те же статьи). Сути это не меняет, так как функционал один и тот же. Если вы можете помочь - прошу помогите, а беЗсмысленные вопросы про улавливание сути, прошу оставьте другим авторам вопросов.
И да. Не нужно смешивать алгоритм решения задачи, и реализация данного алгоритма. Поскольку имеем проблему с алгоритмом, то решать задачу реализации еще рано и рассуждать о Redis нет смысла. Более того, я не вижу смысла делать это на уровне Redis когда есть РСУБД в рамки которых это все прекрасно ложиться.
@alekciy Все верно только в случае, когда не нужно смотреть все посты. Если необходимо смотреть все посты (как на утубе, однокласниках и прочих соц сетях) то необходимо где-то хранить ид новых постов, а не просто дату.
В моем проекте необходимо учитывать новые авторские мп3, и если прослушали ее, тогда помечать как прослушанная, остальные новые. Это как пример не ваккумной задачи.
@dim4ik Все укладывает в банальную схему связи многое-ко-многим. 3 таблицы: таблица с пользователями user (id_user, name ....), таблица с треками track (id_track, name ...), таблица отмечающая какой юзер какой трек слушал user_track_link(id_user, id_track). Элементарный SELECT...LEFT JOIN даст все исчерпывающую информацию. Redis тут абсолютно не нужен и даже вреден.
@alekciy Сейчас на сайте 50 000 зарегистрированных пользователей, 3000 авторских мп3.
100 тысяч пользователей будет через 3-4 месяца.
каждый легко прослушает 100 композиций.
100 000 пользователей Х 100 композиций = 10 000 000 записей в таблице прослушек. А если за полгода пользователь прослушает 1000 композиций?
Получается 100 000 000 в таблице? Вот почему я хотел использовать тут Redis. (либо разбивать такую таблицу с 1 по 50 тысяч пользоватлей одна таблица, с 50 000 до 100 000 другая)
@dim4ik чем тут поможет Redis? Что, в нем не нужно будет хранить эти 100 000 000 записей? С каких пор для РСУБД 100Мзаписей стало много, а для in-memory базы нормально?
Если это вопрос использования Redis потому что это клево и модно и круто написать что вот заюзал его в своем проекте, то обсуждать правильный алгоритм под указанную задачу бессмысленно тогда.