Как правильно спроектировать БД для френдленты?

Добрый день!

Подскажите как лучше на сайте организовать ленту новостей пользователя.
В ленте необходимо показывать следующие события:
— добавление в друзья
— создание записей друзьями (посты, вопросы)
— комментарий моей записи
— ответ на мой комментарий
— комментарий записей, добавленных в избранное

Варианты:
1. Создать таблицу UserEvent с полями:
— id_user — идентификатор пользователя, для которого выводить событие
— actionType — тип действия
— id_rec — ссылка на запись-источник события
— createDate — дата события
— id_author — автор события
В эту таблицу писать все события для каждого пользователя. Т.е. создал юзер пост, для каждого друга создалась запись в этой таблице. Выборку по таблице осуществлять с фильтром по полю id_user.

Минусы:
— нагрузка при создании (для каждого друга создавать записи в UserEvent. если будет 2000 друзей, то при каждом создании поста создавать 2000 записей в UserEvent?)
— быстрый рост размера БД
Плюс:
— простая выборка, более быстрая
2. Создать таблицу UserEvent с полями:
— actionType — тип действия
— id_rec — ссылка на запись-источник события
— createDate — дата события
— id_author — автор события

В таблице создавать одну запись на одно событие. Выборку осуществлять по двум таблицам UserEvent + таблица с данными о друзьях и данными об избранных постах и вопросах.

Минусы:
— более сложная выборка
Плюс:
— БД относительно не быстро растет
— нет нагрузки при создании записи ( не нужно создавать для каждого юзера запись в таблице UserEvent)

Посоветуйте, как оптимальнее с точки зрения производительности? Может есть какой-нибудь еще вариант?
  • Вопрос задан
  • 2894 просмотра
Пригласить эксперта
Ответы на вопрос 3
@balloon
Мы делали опираясь на второй вариант, при этом id друзей кэшировали (т.е. в итоге был простой запрос вида select * from feed where author_id in (1,2,3). И всё было просто до следующих требований:
1. Нужно было выводить только те записи друга, которые создали после добавления друга (от этого в последствии отказались из-за чрезмерного оверхеда и сомнительной выгоды)
2. Если кто то из твоих друзей откомментил пост — то он должен был поднятся наверх (упростли до требования поднимать вверх сообщение если хоть кто то его откомментил. Как результат просто ввели еще одно поле с датой апдейта и сортировали по нему)
3. Приватность для записей, которые ссылаются на другую запись. Вроде Твой дружище лайкнул пост своего друга, который не твой друг. В этом случае если оригинальный пост доступен только для друзей(а вы с ним не друзья), то его не нужно было показывать. (В данном случае автором оставлася всегда оригинальный автор, а сообщение помечалось как ссылка и юзера, который его ретвитил мы записывали в отдельное поле).

Были и специфичные требования:
1. Юзера можно было поставить игнор на N дней. В течении этого времени его сообщения должны были игнорирваться.
2. Пост можно было пометить как избранный, и он постоянно висел в топе (нужно было для мониторинга)

P.S. кстати в первом варианте выгоднее создать 2 таблицы. Одна — с сообщениями. Вторая EventId,UserId.
Ответ написан
@bdmalex
NoSQL — как вариант, почему не рассматриваете?
Ответ написан
@egorinsk
Написать демона на Си/Ява/.NET с точки зрения производительности выгоднее, чем мучать БД.
Ответ написан
Ваш ответ на вопрос

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

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