2009-08-06 8 views
3

Cela peut être une question poilue mais. Dire que j'aiPHP/MySQL Activity (ala facebook)

Followers: 
-user_id 
-follower_id 

Activities: 
-id 
-user_id 
-activity_type 
-node_id 

Extraction d'une activité utilisateur est assez facile. Mais quelle est la meilleure façon d'obtenir une activité de fidèles? Un sous-ensemble? Il semble que c'est incroyablement lent car les utilisateurs obtiennent de plus en plus d'adeptes. Des idées pour accélérer cela?

Aussi, à un niveau plus conceptuel. Comment fonctionne le regroupement. Est-ce que tout est fait avec une seule requête? Ou est-ce que toutes les données d'activité sont tirées dedans et alors classées et groupées du côté de PHP?

Utilisateurs X, Y et Z ont Activité A utilisateur J a 3 de l'activité B

Répondre

4

subselects sont souvent plus lent que JOIN, mais cela dépend vraiment de ce que vous faites exactement avec eux. Pour vous répondre à la question principale, j'obtenir des données de suiveur avec un JOIN:

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

C'est en supposant que la table disciples représente un utilisateur avec user_id, et quelqu'un qui les suit avec un follower_id qui se trouve être un user_id dans la table des utilisateurs aussi.

Il ne sera jamais incroyablement lente tant que vous avez un index sur followers.user_id. Cependant, la quantité de données qu'une telle requête pourrait renvoyer pourrait devenir plus grande que ce que vous voulez vraiment traiter. Vous devez déterminer les types d'activité que votre application va afficher, et essayer de les filtrer en conséquence, afin de ne pas faire de grosses requêtes tout le temps, mais seulement en utilisant une infime fraction des résultats retournés.

Extraire des données et les regrouper Le côté PHP est bien, mais si vous pouvez éviter de le sélectionner en premier lieu, vous êtes mieux lotis. Dans ce cas, j'ajouterais probablement un ORDER BY f.follower_id,activity_date DESC, en supposant qu'une date existe, et j'essayerai de trouver d'autres critères de filtrage pour la table d'activité. Ensuite, je parcourais les lignes en PHP, produisant des données groupées par suiveur.

+0

Je pense que la notion de date est assez cruciale, mais c'est peut-être juste une omission de Josh. – Wookai

0

Je ne sais pas si je comprends bien ce que vous avez besoin, mais je voudrais essayer cette sélection, si je ne me trompe pas, vous devriez obtenir toute activité pour tous les adeptes de #USERID#

SELECT a.* FROM Activities AS a 
INNER JOIN Followers AS f1 
ON a.user_id = f1.follower_id 
WHERE f1.user_id = #USERID# 
2

Un journal d'activité a le potentiel pour un très grand nombre d'enregistrements car il présente généralement un mélange d'activité de l'utilisateur actuel et de tous ses amis. Si vous rejoignez plusieurs tables et qu'un utilisateur a des centaines d'amis, il est possible que beaucoup de données soient retirées. Une approche consiste à dénormaliser les données et à les traiter comme un grand journal dans lequel toutes les entrées qui doivent apparaître sur la page du journal d'activité d'un utilisateur doivent être stockées dans la table du journal des activités pour cet utilisateur. Par exemple, si l'utilisateur A deux amis, l'utilisateur B et C utilisateur, lorsque l'utilisateur A fait quelque chose de trois enregistrements du journal d'activité sont créés:

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 

Vous obtiendrez des doublons, mais cela n'a pas vraiment d'importance. Il est rapide à sélectionner car il provient d'une table et est indexé uniquement sur l'ID utilisateur. Et il est probable que vous conserviez une table de journal d'activité (c'est-à-dire que vous supprimiez les entrées datant de plus d'un mois).

La table de journal d'activité pourrait être quelque chose comme:

-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 

Pour sélectionner tous les journaux d'activité récente pour un seul utilisateur est alors facile:

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

Pour rendre cette approche vous avez vraiment efficace besoin de avoir suffisamment d'informations dans la table de journal d'activité unique pour ne pas avoir besoin d'autres sélections. Par exemple, vous pouvez stocker le message de journal brut, plutôt que de le créer à la volée.

+0

Que se passe-t-il si je viens de vous ajouter en tant qu'ami et que je veux voir vos dernières activités? Devons-nous rétrospectivement ajouter les activités d'un utilisateur à un nouvel adepte? – Wookai

+0

bon point. Dans l'exemple ci-dessus, vous ne verriez pas les dernières activités de l'utilisateur dans votre propre flux d'activités. Vous ne verriez que de nouvelles entrées. Ce que je pense est acceptable. Vous pouvez toujours accéder à la page publique de l'utilisateur pour voir son propre journal d'activité (s'il est public aux autres utilisateurs). – simonrjones

+1

Donc, ce que vous dites, si j'ai 5000 amis/suiveurs et que je fais un post, je devrais créer 5000 entrées dans la base de données pour chaque action que je fais? J'espère que j'ai mal compris votre réponse sinon ce sera une réponse horrible sans irrespect. – JasonDavis