Лента новостей. Как же сделать правильно?

Темы, не касающиеся фреймворка, но относящиеся к программированию в целом.
Ответить
arlamar
Сообщения: 39
Зарегистрирован: 2013.07.20, 17:38

Лента новостей. Как же сделать правильно?

Сообщение arlamar »

Все привет.

Намечается один проект в котором будет лента аля ВК, фейсбук и тд.
Стал я думать и понял, что не могу придумать архитектуру БД при которой это будет работать при куче пользователей...
Реляционные БД - это куча записей в таблице и джойны(или доп запросы) для лайков и комментов и самого контента на который ссылается запись.
MongoDB и тд - это необходимость обновлять ленту каждого пользователя для которого доступна моя запись при любом действии. А как быть когда у чела 100500 подписчиков, например. Я мало знаю о монго, но читал пару статей в которых описывали как же это плохо как раз в таких случаях.
В общем, попытки найти ответы на мои вопросы порождают у меня еще больше вопросов :)
Может кто-нибудь делать уже подобное? Поделитесь советом, плз)

Проект будет на Yii2.
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Лента новостей. Как же сделать правильно?

Сообщение samdark »

Задачка занятная. Как-то её Бородин рассказывал на конференциях: http://spb-borodin.livejournal.com/. В одном из постов у него есть намёки.
arlamar
Сообщения: 39
Зарегистрирован: 2013.07.20, 17:38

Re: Лента новостей. Как же сделать правильно?

Сообщение arlamar »

Sam Dark, спасибо большое. Познавательно. Появились мысли как устроить всё.
Avgusto
Сообщения: 46
Зарегистрирован: 2013.11.07, 21:09

Re: Лента новостей. Как же сделать правильно?

Сообщение Avgusto »

У меня схожая диллема пока не решена. Например, товары в е-магазине
1 - товар
2 - EAV (entity–attribute–value)
3 - оценки (не просто звёзды, а достоинства, недостатки и комментарий)
4 - обсуждения (или комментарии)
5 - подписка по email на изменение свойств (например, скидка)

или простые статьи с оценками, комментариями и подписчиками - суть та-же

Каждая такая сущность ("доп" свойство) хранится в своей таблице БД.
Просто выводить такой список, еще ладно - любые допы можно "наджойнить".
А вот как это всё фильтровать по разным доп.параметрам: EAV, оценкам, подпискам и т.п.

И, конечно, это всё без 100500 запросов к БД и мега-массивов в памяти, на рендер одной страницы.

Впорос про архитектуру решения: подскажите, куда думать?
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Лента новостей. Как же сделать правильно?

Сообщение samdark »

EAV в реляционной базе — это уже плохо для производительности. По определению.
arlamar
Сообщения: 39
Зарегистрирован: 2013.07.20, 17:38

Re: Лента новостей. Как же сделать правильно?

Сообщение arlamar »

Много читал сегодня, голова уже не соображает, но пришел к следующему:
Вся лента хранится в одной таблице/коллекции - с конкретным видом хранилища еще не определился.
Что-то типа:
id|user_id|model_name|model_id|comments_count|likes_count|created_at
Ну и может еще какие-то поля будут. Комменты и лайки пересчитывать планирую при непосредственном добавлении/удалении. Контент остается в модели.

Еще у документо-ориентированной есть определенные плюсы. Например, хранение всех user_id которые лайкали запись прямо в документе. Атомарные операции очень удобно использовать. Но если предположить, что будет очень много лайков(200к например) то при чтении такого документа будет отожрана куча памяти. Правда и тут есть решение, можно лайки вынести в отдельную коллекцию и читать их только если нужно будет отображать тех кто лайкнул. Так же возможно комментарии войдут в документ, хотя не уверен, так как не понял как потом пейджер делать или подгрузку.
В MySQL мне бы пришлось делать отдельную таблицу, наверное, для лайков. Получается, что при 1кк записей в таблице ленты и по 100 лайков в среднем на запись, мы получаем просто какое-то заоблачное кол-во записей в таблице лайков.
Другого решения ведь нет для MySql?

Пугают еще и отзывы о MongoDB по поводу надежности. Не хотелось бы безвозвратно потерять инфу по всем лайкам и комментариям.
Так же пока не понял как быть с ограничение в 16мб на документ. Так как массив из 200к user_id отжирает 30мб+ памяти, то есть документ должен весить столько же?

1кк записей и 200к лайков для одной записи очень оптимистично, конечно, но хочется сразу сделать правильно так как проект очень даже интересный и, скорее всего, жить будет :)

Кто что думает?

ps. Сильно не пинайте, опыта работы с большими БД нет, о NoSQL только читал пока.
arlamar
Сообщения: 39
Зарегистрирован: 2013.07.20, 17:38

Re: Лента новостей. Как же сделать правильно?

Сообщение arlamar »

Сегодня задумался на тем как выбирать из ленты записи тех людей, на которых я подписан и, признаться, тупик...
Если на примере мускула то получается вложенный запрос в условии? WHERE user_id IN (SELECT user_id FROM subscribers WHERE subscriber_id = :my_id) ? Будет ли такое работать вообще если в обеих таблицах миллионы записей?
На Монго получается не намного лучше, надо взять массив всех людей на кого я подписан и передать в IN. Но тут я вообще пока не понимаю как он переварит допустим 100к+ айди в запросе...
Гуру СУБД отзовитесь плз)
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Лента новостей. Как же сделать правильно?

Сообщение slavcodev »

Информация для размышлений по "ленты новостей" (для еще большей боли в голове) :)

1) Возможно пригодится систему обмена сообщениями (СОС), например RabbitMQ, можно свою команду простую написать, для крона.

2) Процесс работы:
- При регистрации пользователя Х, создается очередь сообщений Х
- Другие пользователи подписываются на эту очередь (Follow User, Friendship)
- Когда пользователь Х добавляет новость, в очередь сообщений Х попадает сообщение "Пользователь Х добавил новость У", далее другой процесс (СОС) рассылает это сообщение всем подписавшимся
- Для новой новости создается очередь У, на которую подписываются, например все кто добавит коммент, и в эту очередь попадают сообщения для рассылки, когда комменты добавляются
- Если пользователь Х удаляет новость, в очередь Х отправляется соотв. сообщение и СОС удаляет у подписавшися эту запись
Жду Yii 3!
Ответить