PHP / MySQL Activity (аля facebook) - PullRequest
       12

PHP / MySQL Activity (аля facebook)

3 голосов
/ 06 августа 2009

Это может быть волосатый вопрос, но. Скажи, что у меня есть

Followers:
-user_id
-follower_id

Activities:
-id
-user_id
-activity_type
-node_id

Вытащить активность пользователей довольно легко. Но каков наилучший способ получить активность подписчиков? Подвыбор? Кажется, что это невероятно медленно, поскольку пользователи получают все больше и больше последователей. Любые идеи, чтобы ускорить это?

Кроме того, на более концептуальном уровне. Как работает группировка? Все ли это делается с помощью одного запроса? Или все данные об активности извлекаются, а затем сортируются и группируются на стороне PHP?

Пользователи X, Y и Z выполнили упражнение A Пользователь J выполнил 3 действия B

Ответы [ 3 ]

4 голосов
/ 06 августа 2009

Подвыборы часто медленнее, чем JOIN, но это действительно зависит от того, что именно вы делаете с ними. Чтобы ответить на ваш главный вопрос, я бы получил данные последователей с JOIN:

SELECT * FROM followers f
LEFT JOIN activities a ON f.follower_id=a.user_id
WHERE f.user_id=$followedPerson

Предполагается, что таблица последователей представляет пользователя с user_id, а кто-то, кто следует за ним с follower_id, который, как оказалось, также user_id в таблице пользователей.

Это никогда не будет невероятно медленным, пока у вас есть индекс на followers.user_id. Однако объем данных, который может вернуть такой запрос, может стать больше, чем вы действительно хотите иметь дело. Вам необходимо определить, какие виды активности будет показывать ваше приложение, и попытаться соответствующим образом отфильтровать его, чтобы вы не выполняли огромные запросы все время, а использовали только крошечную часть возвращаемых результатов.

Вытащить данные и сгруппировать их на стороне PHP - это хорошо, но если вы не сможете выбрать их в первую очередь, вам лучше. В этом случае я, вероятно, добавил бы ORDER BY f.follower_id,activity_date DESC, предполагая, что дата существует, и попытался бы придумать еще несколько критериев фильтрации для таблицы действий. Затем я перебрал бы строки в PHP, выводя данные, сгруппированные по последователю.

2 голосов
/ 09 августа 2009

Журнал активности может содержать очень большое количество записей, поскольку в нем обычно содержатся сведения о деятельности текущего пользователя и всех его друзей. Если вы объединяете разные таблицы, и у пользователя есть сотни друзей, это может привести к извлечению большого количества данных.

Одним из подходов является денормализация данных и обработка их как одного большого журнала, в котором все записи, которые должны появиться на странице журнала активности пользователя, будут сохранены в таблице журнала активности для этого пользователя. Например, если у пользователя A есть два друга, пользователь B и пользователь C, когда пользователь A делает что-то, создаются три записи журнала активности:

record 1: "I did this" log for user A
record 2: "My friend did this" log for user B
record 3: "My friend did this" log for user C

Вы получите дубликаты, но это не имеет значения. Это быстро выбрать, поскольку он из одной таблицы и проиндексирован только по идентификатору пользователя. И, скорее всего, вы будете вести таблицу журнала активности (т.е. удалять записи старше 1 месяца).

Таблица журнала активности может выглядеть примерно так:

-id
-user_id  (user who's activity log this is)
-action_user_id  (user who took the action, or null if same as user_id)
-activity_type
-date

Выбрать все последние журналы активности для одного пользователя очень просто:

SELECT * from activity_log WHERE user_id = ? ORDER by date DESC LIMIT 0,50

Чтобы сделать этот подход действительно эффективным, вам нужно иметь достаточно информации в единой таблице журнала активности, чтобы не требовалось никаких дальнейших выборов. Например, вы можете хранить необработанное сообщение журнала, а не создавать его на лету.

0 голосов
/ 06 августа 2009

Я не знаю, правильно ли я понял, что вам нужно, но Я бы попробовал этот выбор, если я прав, вы должны получить всю активность для всех последователей #USERID#

SELECT a.* FROM Activities AS a 
INNER JOIN Followers AS f1 
ON a.user_id = f1.follower_id
WHERE f1.user_id = #USERID# 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...