Acuna
@Acuna
Заполнил свой профиль

Как реализовать ленту новостей для социальной сети?

Всем привет! Пробую реализовать свою небольшую соц. сеть (для себя, ну и просто тренировка).

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

Что у меня есть из таблиц:

comments - непосредственно все записи друзей и групп.
users - данные всех юзеров и групп (решил юзеров и группы писать в одну таблицу, чтобы джойнить меньше).
friends - данные друзей (кто кого добавил). Соответственно выводим записи только моих друзей.
groups_members - данные групп (кто в какой группе состоит).

В комментах есть колонка user_id - это id юзера, оставившего эту запись, и post_id - это id юзера, для кого была оставлена эта запись, или id группы, если запись была сделана на стене группы.

Вот все это сджойнить и не получается, то выводится одна запись, то сразу все вперемешку...
Так что помощь бы не помешала.

Заранее благодарен.
  • Вопрос задан
  • 4272 просмотра
Решения вопроса 2
Tyranron
@Tyranron
Ну, join'ить это дело можно (подозреваю что там ещё и union'ом прийдётся заливать), но так обычно не делают, потому что это решение потом невозможно будет отмасштабировать. Запрос тяжелый, кеширование поможет плохо, так как активность большая и кеш часто сбрасываться будет и база будет дергаться не многим меньше, ну и если базу надо распилить на 2 и больше серверов, то останемся лапу сосать с join'ами.

Для начала можно сделать так - для конкретного `user_id` (владелец новостной ленты):
1) Первым запросом стягиваем айди всех друзей
2) Вторым запросом стягиваем айди всех групп, в которых состоит
3) Третьим запросом стягиваем из comments все записи WHERE `user_id` IN (группы + друзья) ORDER BY/LIMIT по вкусу.

Преимущества:
Меньшая нагрузка на базу, она будет делать меньше дорогостоящих операций с временными таблицами. По индексам быстрее будет отдавать результат.
Первые 2 запроса можно спокойно закешировать, так как добавляются/удаляются друзья гораздо реже, чем сами посты. Потому по сути сводится всё к одному запросу на сами посты без join'ов.

Минусы:
Больше кода на обработку 3х запросов. Чуть более длительное выполнения скрипта, что, в принципе, не будет ощущаться пользователем, и вообще будет не справедливо, если первые 2 запроса кешировать.

Но если стоит задача масштабироваться, то и такого подхода к делу недостаточно. Там уже надо будет скорее всего жертвовать лишним местом, чтобы сократить расходы на собирание размазанных данных по всем серверам баз, например, вести отдельную таблицу ленты новостей для каждого пользователя, которая будет агрегировать все необходимые айдишники.
UPD: ...как и указал @jarvis
Ответ написан
jarvis
@jarvis
Я делал через очередь сообщений, то есть сообщение человека или группы добавляется в ленты каждого его подписчика(многократно)

Все пока одна таблица(пока одна, потом придется увеличить в процессе масштабирования) и такой запрос на получение ленты пользователя с user_id: select * from 'feeds_table' where user_id=id пользователя...., а сама таблица feeds содержит такие поля как user_id( пользователь, которому принадлежит лента, author_id - id автора(кто оставил запись, без разницы группа или пользователь), post (сама запись и вложения). Таким образом запись многократно дублируется, но зато позволяет быстро и в один простой запрос получать ленту.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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