@neronru

Как правильно организовать ленту постов?

Здравствуйте, очень нужен ваш совет в плане правильной организации БД/хранилища для ленты постов. Суть заключается в следующем: нужно вывести все лайкнутые статьи,всех на кого ты подписан, но при этом нужно группировать, так, что позиция статьи зависит от первого лайка....Сейчас на примере попытаюсь это показать.
Есть у нас пользователи A,B,C. A подписан на B и на C. Пусть пользователи B и C лайкнули одну статью. (Сначала B потом C). Так вот в ленте позиция этой статьи должна быть по первому лайку, то есть по времени лайка B.
Сначала были сделаны две таблицы в MySQL:
  1. user_relationships(idUser INT(11), idSub INT(11))
  2. post_likes (id INT(11), idPost INT (11), idUser INT(11), size INT(11), date DATETIME)

Первая это отношение между пользователями, вторая лайки...И выбирали вот таким вот запросом:
SELECT  min(id) as id, idPost, posts_likes.idUser 
FROM `post_likes`,`users_relationships` WHERE 
    post_likes.idUser=users_relationships.idSub AND
     users_relationships.idUser=$user_id AND post_likes.size >= 0 
GROUP BY idPost ORDER BY id DESC

Но с заполнением таблицы post_likes время запроса стало резко увеличиваться, я посмотрел explain, и стало понятно, что запрос не может использовать индексы...Посмотрев документацию мускула, я понял, что это происходит из-за того что группировка и сортировка производятся по разным полям. Может быть вы подскажите, как это можно преодолеть?
Так же возникла идея генерировать ленту в Redis, ну и вообще полностью перенести эти две таблички туда. Но тут так же проблема с генерацией ленты...Структура в Redis'е такая: для каждого пользователя хранятся все его лайкнутые статьи. Для того чтобы сгенерировать ленту, мы просто используем zunionstore для каждого на кого подписан пользователь, и потом сохраняем ленту для пользователя. Но тут возникает проблема с удалением статей, если пользователь отписался(уж очень много обходить), и с большим количеством перерасходывания памяти.(Частично генерировать не получится, так как может быть такая ситуация: пользователь B лайкнул давным давно статью, а пользователь C только что, и может получится так, что пост появится два раза...)
Очень прошу помочь, как все таки сделать правильнее. Заранее спасибо.
  • Вопрос задан
  • 318 просмотров
Пригласить эксперта
Ответы на вопрос 1
1) не могу понять зачем вам id и size в таблице post_likes. Для регистрации факта и времени лайка достаточно этого: (idPost, idUser, date) с ключом (idPost, idUser).
2) почему ORDER BY id а не по дате?
3) сделайте нормальные нужные вам индексы, включающие поля по которым вы фильтруете и сортируете (с указанием порядка сортировки).

Под большой нагрузкой с такой задачей лучше графовую базу пробовать (когда много связей, как у вас с подписчиками).
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы