|
|
|
Проектирование френдленты и рейтингов
|
|||
|---|---|---|---|
|
#18+
Добрый день. Есть сайт с: - пользователями (Users: UID, UserName) - у пользователей есть посты (Posts: PID, UID, Content) - у постов есть комментарии (Comments: CID, PID, UID, CommentContent). - друзья пользователей (Friends: UID, FriendUID) Далее каждый пользователь может оценивать как посты, так и комментарии (обычные +/- ). Так же, пользователь может добавлять других пользователей в друзья. Хочу спросить, какую структуру БД лучше всего создать для следующей задачи: хочется выводить френдленту с информацией, кто из френдов, когда и что делал (написал пост, оценил чужой пост, написал комментарий, оценил комментарий). Типо как новости вконтакте или фейсбуке. + хочется рейтинги постов, юзеров и комментариев вида: "лучший пост дня", "недели". Плюс сохранение истории этих рейтингов. Проблема с пониманием того, какую структуру выбрать. Пока придумалась одна аггрегирующая табличка активности вида: Activity: UID - кто сделал TypeID - что сделал (оценил пост, оценил коммент, добавил пост, добавил коммент, ...) ItemID - ID того, над чем произведено действие (ID поста, ID комментария) ItemOwnerID - UID того, кто является автором поста или комментария. RelatedItemID - ID главного элемента RelatedItemOwnerID - UID автора главного элемента DateOf - дата действия. Rating - рейтинг (NULL - если запись активности не является оценкой) RelatedItemID и RelatedItemOwnerID - это ID главных элементов (см. ниже) Пример: - Вася Пупкин (UID=15), - оценил (TypeID=1) комментарий (CID=10) Феди Иванова (UID=20) - который прокомментировал пост (PID=5) Ивана Семенова (UID=30) - оценкой "5" - 22 февраля 2010 года, тогда запись в эту таблицу активности будет такой: Код: plaintext 1. 2. По такой таблице достаточно просто делать френдленту, ибо есть все UID'ы, и все их действия. Но, насколько такая схема удобна и правильна? И второй вопрос - как считать рейтинги по такой таблице? Допустим раз в сутки я пересчитываю рейтинги каждых постов, юзеров, комментариев. Для примера я хочу посчитать "статью дня" - статью, набравшую наибольшее кол-во голосов за 24 часа с момента её опубликования. Дата опубликования находится как в таблице Posts (CreationDate), так и в таблице Activity со своим TypeID. Никак не могу придумать такой запрос. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.04.2010, 23:04 |
|
||
|
Проектирование френдленты и рейтингов
|
|||
|---|---|---|---|
|
#18+
1. Я бы в Posts добавил 2 столбца : 1) SumRating INT (суммарный рэйитг) 2) NumberOfVotes - INT (общее кол-во голосований) При добалении поста значения полей 0, 0. При голосовании прибавляем к сумме поставленную оценку , увеливаем на 1 кол-во. Так же добавить вычисляемый столбец. AvgRating : SumRating * 1.00 / NumberOfVotes. Желательно вычисляемый, если нет то постоянный столбец. Это избавляет от постоянного расчета среднего рэйтинга. И то что хранится уже предыдущая сумма избавляет, от сканирования и пересчета среднего при добавлениях. По этому столбцу делаете индекс. (Получение наиболее популярных) Итого : быстро и актуальная информация. Аналогично для Comments. Для примера я хочу посчитать "статью дня" - статью, набравшую наибольшее кол-во голосов за 24 часа с момента её опубликования. Да , такие вещи делаются асинхронно. (В наименее загруженное время) Зачем вам таблица Activity ? Попытка запихнуть все что только можно ? Кем создан пост и комментарий хранятся в соответствующих таблицах и этого достаточно . Зачем их дублировать. Для процесса голосования добавляете 2 таблицы для постов и комментариев отдельно . Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.04.2010, 00:33 |
|
||
|
Проектирование френдленты и рейтингов
|
|||
|---|---|---|---|
|
#18+
Леша7771. Я бы в Posts добавил 2 столбца : Аналогично для Comments. Там немного хитрее формула, но да, текущий рейтинг, который обсчитывается раз в сутки для каждого элемента, будет хранится в таблицах Posts, Comments. Что бы можно было легко выводить тот же ТОП делая просто Код: plaintext 1. Да , такие вещи делаются асинхронно. (В наименее загруженное время) Так и будет. Раз в сутки считаться. Зачем вам таблица Activity ? Попытка запихнуть все что только можно ? Кем создан пост и комментарий хранятся в соответствующих таблицах и этого достаточно . Зачем их дублировать. Тогда возникает вопрос - как во френдленте выводить в хронологическом порядке данные из разных таблиц? Т.е. мне надо вывести: кто из моих френдов написал какой-то пост, кто из моих френдов написал какой-то коммент и к чему, кто из моих френдов что-то оценил. Из одной таблицы это было бы легко: Код: plaintext 1. 2. 3. А если эти вещи не хранить в аггрегирующей таблице, то надо будет делать 3 запроса (к таблицам Posts, Comments, Ratings) и далее их еще как-то отсортировать по дате. А с пагинацией там еще тоже головной боли. Или я чего-то не понимаю? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.04.2010, 08:55 |
|
||
|
Проектирование френдленты и рейтингов
|
|||
|---|---|---|---|
|
#18+
Нету в вашей предметной области такой сущности, как фридлента. Есть пост, коментарий, оценка, пользователь. Если задача сделать получение фрилдленты быстро( с пэйджигами и сортировками), то данные нужно дублировать. Не должна из-за этого появлятся непонятная таблица , типа вашей активити. Одна таблица - одна сущность. Представьте вашу систему еще чем- нибудь надо будет расширить : например, добавить более одного голосования или еще что-нибудь. Я бы делал как описал выше. А для фридленты сделал бы доп таблицу : id ,UID ,Date ,ExternalRecordID ,ExternalRecordType Где ExternalRecordID - идентификатор внешней записи (поста, комментария, рэйтинга ...) , ExternalRecordType - тип . Соответственно завести табличку - справочник для типов активности. Индекс по UID + Date сильно поможет делать эту выборку быстро. И алгоритм с пэйджингом видится так : 1) получаете нужную страницу 2) сохраняете во временной таблице индекс в выборке, ExternalRecordID, ,ExternalRecordType 3) И union-ами соединяете выборки с соотв. базовой таблицей . Да, появлятся доп сортировка, но всего лишь для страницы данных. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.04.2010, 11:33 |
|
||
|
|

start [/forum/topic.php?desktop=1&fid=32&tid=1542733]: |
0ms |
get settings: |
6ms |
get forum list: |
15ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
175ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
30ms |
get tp. blocked users: |
1ms |
| others: | 229ms |
| total: | 471ms |

| 0 / 0 |
