Je suis au début de la construction d'un système de notification de style Facebook pour notre page (type de jeu social) et je recherche maintenant quelle serait la meilleure façon de concevoir un tel système. Je ne suis pas intéressé par la façon de pousser les notifications à l'utilisateur ou quoi que ce soit du genre (pour l'instant même). Je recherche comment construire le système sur le serveur (comment stocker les notifications, où les stocker, comment les récupérer, etc.).
Donc ... certaines exigences que nous avons:
- aux heures de pointe, nous avons environ 1k utilisateurs connectés simultanément (et beaucoup plus d'invités, mais ils n'ont pas d'importance ici car ils n'auront pas de notifications) qui généreront de nombreux événements
- il y aura différents types de notifications (l'utilisateur A vous a ajouté comme ami, l'utilisateur B a commenté votre profil, l'utilisateur C a aimé votre image, l'utilisateur D vous a battu sur le jeu X, ...)
- la plupart des événements généreront 1 notification pour 1 utilisateur (l'utilisateur X a aimé votre image), mais il y aura des cas où un événement générera de nombreuses notifications (c'est l'anniversaire de l'utilisateur Y par exemple)
- les notifications devraient être regroupées; si, par exemple, quatre utilisateurs différents aiment une image, le propriétaire de cette image devrait recevoir une notification indiquant que quatre utilisateurs ont aimé l'image et non quatre notifications distinctes (tout comme FB)
OK, donc ce que je pensais, c'est que je devrais créer une sorte de file d'attente où je stockerais les événements lorsqu'ils se produisent. Ensuite, j'aurais un travail d'arrière-plan ( gearman ?) Qui examinerait cette file d'attente et générerait des notifications en fonction de ces événements. Ce travail stocke ensuite les notifications dans la base de données pour chaque utilisateur (donc si un événement affecte 10 utilisateurs, il y aura 10 notifications distinctes). Ensuite, lorsque l'utilisateur ouvrait une page avec la liste des notifications, je lisais toutes ces notifications pour lui (nous pensons à limiter cela à 100 dernières notifications) et les regroupais, puis les afficherais enfin.
Choses qui me préoccupent avec cette approche:
- complexe comme l'enfer :)
- est la base de données le meilleur stockage ici (nous utilisons MySQL) ou devrais-je utiliser autre chose (redis semble également être un bon choix)
- que dois-je stocker comme notification? ID utilisateur, ID utilisateur qui a initié l'événement, type d'événement (afin que je puisse les regrouper et afficher le texte approprié) mais ensuite je ne sais pas comment stocker les données réelles de la notification (par exemple, URL et titre de l'image qui a été aimé). Dois-je simplement "cuire" cette information lorsque je génère la notification, ou dois-je stocker l'ID de l'enregistrement (image, profil, ...) affecté et extraire les informations de la base de données lors de l'affichage de la notification.
- les performances devraient être correctes ici, même si je dois traiter 100 notifications à la volée lors de l'affichage de la page des notifications
- problème de performance possible à chaque demande car je devrais afficher le nombre de notifications non lues à l'utilisateur (ce qui pourrait être un problème en soi puisque je regrouperais les notifications). Cela pourrait être évité si je générais la vue des notifications (où elles sont regroupées) en arrière-plan et non à la volée
Alors, que pensez-vous de ma solution proposée et de mes préoccupations? Veuillez commenter si vous pensez que je devrais mentionner autre chose qui serait pertinent ici.
Oh, nous utilisons PHP pour notre page, mais cela ne devrait pas être un facteur important ici, je pense.
la source
Réponses:
Une notification concerne quelque chose (objet = événement, amitié ..) modifié (verbe = ajouté, demandé ..) par quelqu'un (acteur) et signalé à l'utilisateur (sujet). Voici une structure de données normalisée (bien que j'aie utilisé MongoDB). Vous devez informer certains utilisateurs des modifications. Il s'agit donc de notifications par utilisateur ... ce qui signifie que s'il y avait 100 utilisateurs impliqués, vous générez 100 notifications.
(Ajoutez des champs horaires là où vous le souhaitez)
Il s'agit essentiellement de regrouper les modifications par objet, de sorte que vous puissiez dire "Vous avez 3 demandes d'ami". Et le regroupement par acteur est utile, de sorte que vous puissiez dire "L'utilisateur James Bond a fait des changements dans votre lit". Cela permet également de traduire et de compter les notifications à votre guise.
Mais, étant donné que l'objet n'est qu'un ID, vous devez obtenir toutes les informations supplémentaires sur l'objet que vous souhaitez avec des appels séparés, à moins que l'objet ne change réellement et que vous souhaitiez afficher cet historique (par exemple, "l'utilisateur a changé le titre de l'événement en ... ")
Étant donné que les notifications sont proches du temps réel pour les utilisateurs du site, je les lierais au client nodejs + websockets avec php poussant la mise à jour vers nodejs pour tous les écouteurs à mesure que le changement est ajouté.
la source
is_notification_read
dans lenotification
tableau et le marquer de manière appropriée si c'est le casunread
,read
oudeleted
.C'est vraiment une question abstraite, donc je suppose que nous allons simplement devoir en discuter au lieu de souligner ce que vous devriez ou ne devriez pas faire.
Voici ce que je pense de vos préoccupations:
Oui, un système de notification est complexe, mais pas comme l'enfer. Vous pouvez avoir de nombreuses approches différentes sur la modélisation et la mise en œuvre de tels systèmes, et ils peuvent avoir un niveau de complexité moyen à élevé;
Pesonally, j'essaye toujours de faire des choses basées sur des bases de données. Pourquoi? Parce que je peux garantir un contrôle total de tout ce qui se passe - mais ce n'est que moi, vous pouvez avoir le contrôle sans une approche basée sur une base de données; croyez-moi, vous voudrez contrôler cette affaire;
Permettez-moi de vous donner un exemple concret, afin que vous puissiez partir de quelque part. Au cours de la dernière année, j'ai modélisé et implémenté un système de notification dans une sorte de réseau social (pas comme Facebook, bien sûr). La façon dont j'y stockais les notifications? J'avais une
notifications
table, où j'ai gardé legenerator_user_id
(l'ID de l'utilisateur qui génère la notification), letarget_user_id
(genre d'évident, n'est-ce pas?), Lenotification_type_id
(qui faisait référence à une table différente avec des types de notification), et tout les éléments nécessaires dont nous avons besoin pour remplir nos tables (horodatages, indicateurs, etc.). Manotification_types
table avait une relation avec unenotification_templates
table, qui stockait des modèles spécifiques pour chaque type de notification. Par exemple, j'avais unPOST_REPLY
type, qui avait un type de modèle{USER} HAS REPLIED ONE OF YOUR #POSTS
. De là, je viens de traiter le{}
comme variable et#
comme lien de référence;Oui, les performances doivent et doivent être correctes. Lorsque vous pensez aux notifications, vous pensez au serveur qui se déplace de la tête aux pieds. Soit si vous allez le faire avec des requêtes ajax ou autre, vous allez devoir vous soucier des performances. Mais je pense que c'est une deuxième préoccupation;
Ce modèle que j'ai conçu n'est bien sûr pas le seul que vous puissiez suivre, ni le meilleur également. J'espère que ma réponse, au moins, vous suivra dans la bonne direction.
la source
Cela semble une bonne réponse plutôt que d'avoir 2 collections. Vous pouvez interroger par nom d'utilisateur, objet et isRead pour obtenir de nouveaux événements (comme 3 demandes d'amis en attente, 4 questions posées, etc.)
Faites-moi savoir s'il y a un problème avec ce schéma.
la source
Personnellement, je ne comprends pas très bien le diagramme de la réponse acceptée, donc je vais joindre un diagramme de base de données basé sur ce que je pourrais apprendre de la réponse acceptée et d'autres pages.
Les améliorations sont bien reçues.
la source