Comprendre un système de notification

15

J'ai cherché à construire un système de notification sur SE et ailleurs et je me suis retrouvé attiré par la solution qui est la réponse acceptée ici: /programming/9735578/building-a-notification-system qui utilise cette structure:

╔═════════════╗      ╔═══════════════════╗      ╔════════════════════╗
notification       notification_object      notification_change 
╟─────────────╢      ╟───────────────────╢      ╟────────────────────╢
ID           ║—1:n—→║ID                 ║—1:n—→║ID                  
userID             notificationID           notificationObjectID
╚═════════════╝      object                   verb                
                     ╚═══════════════════╝      actor               
                                                ╚════════════════════╝

Une notification concerne quelque chose (objet = événement, amitié ..) en cours de modification (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.

J'ai d'abord pensé que j'avais compris cette approche, mais quand j'ai commencé à me préparer à la mettre en œuvre, j'ai réalisé que je ne la comprenais pas particulièrement bien. Les derniers commentaires sur la réponse sont des questions d'autres utilisateurs qui ont également eu du mal à comprendre la solution.

Je ne sais pas si c'est le modèle que je vais suivre, mais étant donné le nombre de votes positifs qu'il a, je suis sûr que cela me serait utile de le comprendre , et j'aimerais certainement en savoir plus. J'espère que cela sera également utile à ceux qui ont eu du mal à saisir cette solution (d'ailleurs, je n'ai pas assez de points Internet pour laisser un commentaire sur cette réponse en direction de cette question, n'importe qui d'autre, s'il vous plaît!)

Des questions

Si je comprends bien, notificationObjectID est un pointage de clé étrangère à la notification_object table, et notificationID est une clé étrangère pointant vers la notification table. Il semble que l' objet devrait être une clé étrangère faisant référence à l'ID de l'entrée de base de données à propos de laquelle la notification concerne (par exemple, un événement ou une publication spécifique), mais n'avons-nous pas alors besoin d'un autre champ pour indiquer à quelle table cet ID appartient?

L'auteur a écrit

notification_object.object identifie le type de changement, comme une chaîne "amitié" La référence réelle à l'objet modifié avec ses données supplémentaires dont je parle se trouve dans notification_change.notificationObjectID

ce qui ne semble pas avoir de sens pour moi. L'objet est une chaîne (enum?) Et notificationObjectID est une clé étrangère faisant référence à l'objet sur lequel porte la notification. Alors, comment les tables du milieu et de droite sont-elles connectées?

Il semble que le tableau du milieu spécifie de quel objet (ou type d'objet) la notification concerne, par exemple un événement ou une publication. Nous pouvons alors avoir de nombreuses entrées dans notification_change qui pointent vers le même type d'objet, ce qui nous permet de regrouper les notifications (comme "25 utilisateurs postés sur le mur de X) - d'où la relation 1: n entre les tables du milieu et de droite.

Mais pourquoi existe-t-il une relation 1: n entre les tables gauche et centrale? Allons-nous donner à "25 utilisateurs postés sur le mur de Sam" et "Mary a mis à jour son événement" Friday Picnic "le même ID de notification? Si toutes les notifications pour le même utilisateur ont le même ID de notification, pourquoi avons-nous même besoin du tableau sur le la gauche?

Une question de performance - disons que John publie un commentaire sur l'événement de pique-nique de Mary. Il semble que nous devions effectuer une recherche pour voir si un objet notification_object existe déjà pour Mary's Picnic avant de créer l' entrée notification_change . Cela aura-t-il un impact négatif sur les performances ou s'agit-il d'un problème? Poursuivant les questions du paragraphe précédent, comment saurions-nous à quelle entrée de notification pointer l'objet notification_object ?

user45623
la source

Réponses:

8

Merci pour ces questions approfondies et désolé pour toute confusion - commenter 1 an après la réponse initiale est difficile et maintenant 3 ans après ... les pensées initiales s'estompent et me confondent aussi, mais j'ai peur d'éditer le truc du trou parce que je ne travaille pas sur le stockage des notifications sur le backend en ce moment et je ne sais pas si je fais de bons jugements sans application pratique

Je pense qu'au moment de la rédaction:

  • Oui et non, notificationID était une clé étrangère, notificationObjectID ne l'était pas. Vous avez besoin d'un autre champ FK pour lier les tables ensemble. Je reproche à mon expérience mongo de ne pas être aussi clair à ce sujet :(
  • Oui et non, notification_object.object est vague car vous pouvez l'avoir comme une chaîne ou quelque chose de complexe (JSON ou FK). Dans mon cas, ce n'était qu'un nom.

Tout dépend donc de l'apparence de vos notifications. Pour un cas simple, vous voulez simplement lier la notification entière à une URL, comme une page d'amis - c'est pourquoi avoir un objet (entityType) comme chaîne est utile - vous lui liez des URL.

La notification "vous avez ajouté 3 demandes d'amis " peut être enregistrée différemment.

Si vous souhaitez les afficher une à la fois, vous aurez 3 notifications, 3 objets de notification (friend_request) et 3 entrées dans notification_change qui lient un utilisateur ami spécifique.

Si vous souhaitez afficher une notification - vous aurez 1 notification, 1 / plusieurs objets et 3 / plus d'actions. Donc, dans ce cas complexe, comme «vous avez 3 demandes d'amis de l'utilisateur A, de l'utilisateur B, de l'utilisateur C» - vous utilisez notificationObjectIDs pour chaque utilisateur et avez plusieurs liens dans votre texte de notification.

Devriez-vous utiliser 1 ou 3 objets friend_request? Ça dépend de

  1. Quel est l'objet et quelle est l'action. «L'article est-il aimé / commenté»? Ou est-ce «j'aime / commentaire ajouté» et la hiérarchie des objets n'est liée que pendant l'affichage? Voici Facebook distinguant les «commentaires de photos» des «mentions d'utilisateurs» qui semblent sémantiquement très proches - vous avez la même photo, le même acteur mais des notifications différentes qui auraient pu être fusionnées

entrez la description de l'image ici

  1. Pouvez-vous supprimer une notification ou avez-vous besoin d'un historique? Donc, si j'envoie une demande d'ami, puis l'annule ou commente puis supprime un article, comme et contrairement à quelque chose - devrait-il afficher cet historique (comme une autre action) à l'utilisateur final sous la forme de deux actions différentes? Probablement pas. De plus, il est techniquement plus complexe - vous devez rechercher s'il existe un objet notification_object existant, y ajouter un nouveau notification_change (sinon - ajouter un nouvel objet) de sorte que plus tard, je devrais rechercher dans notification_change pour le supprimer. Au lieu de cela, je voudrais simplement ajouter un autre notification_object à la même notification et le supprimer s'il est parti avec des actions supprimées en cascade.

D'un autre côté, il pourrait y avoir des cas où il pourrait être utile d'avoir un regroupement d'actions où rien ne serait effacé de l'historique.

Je pense que c'est pourquoi au moment de la rédaction, une relation 1: n entre les tableaux gauche et central a été établie - afin que vous puissiez regrouper les notifications non seulement par les acteurs sur la même entité (tableaux du milieu à droite) mais également par plusieurs objets / entités.

Mais bien sûr, vous pouvez simplifier l'intégralité du cas et optimiser le stockage en inversant la relation gauche-milieu à n: 1, de sorte que des notifications par utilisateur soient générées pour un événement.

Pour que ça ressemble plus à ça ..

╔═════════════╗      ╔═══════════════════╗      ╔════════════════════╗
notification       notification_object      notification_change 
╟─────────────╢      ╟───────────────────╢      ╟────────────────────╢
ID           ║←—n:1—║ID                 ║—1:n—→║ID                  
noteObjFK          entityType               noteObjFK           
viewerUserID       entityID                 actionOnEntity      
╚═════════════╝      ╚═══════════════════╝      actorUserID         
                                                ╚════════════════════╝

J'espère que cela a aidé

Artjom Kurapov
la source
Très bien, merci pour cette réponse complète. Je vais le parcourir et vous faire savoir si j'ai d'autres questions, mais je pense que cela explique très bien les choses.
user45623