Grundlegendes zu einem Benachrichtigungssystem

14

Ich habe mir überlegt, wie ein Benachrichtigungssystem auf SE und anderswo erstellt werden kann, und bin zu der Lösung gelangt, die hier als Antwort akzeptiert wird: /programming/9735578/building-a-notification-system using diese Struktur:

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

Bei einer Benachrichtigung wird etwas (Objekt = Ereignis, Freundschaft ..) von jemandem (Schauspieler) geändert (Verb = hinzugefügt, angefordert ..) und dem Benutzer (Betreff) gemeldet. Hier ist eine normalisierte Datenstruktur (obwohl ich MongoDB verwendet habe). Sie müssen bestimmte Benutzer über Änderungen informieren. Es handelt sich also um benutzerbezogene Benachrichtigungen. Wenn also 100 Benutzer beteiligt sind, werden 100 Benachrichtigungen generiert.

Ich dachte zuerst, dass ich diesen Ansatz verstehe, aber als ich anfing, ihn umzusetzen, stellte ich fest, dass ich ihn anscheinend nicht besonders gut verstehe. Bei den letzten Kommentaren zur Antwort handelt es sich um Fragen anderer Benutzer, die ebenfalls Probleme mit dem Verständnis der Lösung hatten.

Ich bin mir nicht sicher, ob dies das Modell ist, dem ich am Ende folgen werde, aber angesichts der Anzahl der positiven Stimmen bin ich sicher, dass es mir helfen würde, es zu verstehen , und ich würde auf jeden Fall gerne mehr erfahren. Ich hoffe, dass dies auch für andere von Nutzen ist, die Probleme haben, diese Lösung zu finden. (Übrigens, ich habe nicht genug Internetpunkte, um einen Kommentar zu dieser Antwort zu hinterlassen, die auf diese Frage verweist.

Fragen

Wenn ich es richtig verstehe, ist notificationObjectID ein Fremdschlüssel, der auf die notification_object- Tabelle verweist , und notificationID ist ein Fremdschlüssel, der auf die notification- Tabelle verweist . Es scheint, als sollte object ein Fremdschlüssel sein, der auf die ID des Datenbankeintrags verweist, um den es in der Benachrichtigung geht (z. B. ein bestimmtes Ereignis oder einen bestimmten Beitrag). Brauchen wir dann kein anderes Feld, um anzugeben, zu welcher Tabelle diese ID gehört?

Der Autor schrieb

notification_object.object identifiziert den Änderungstyp wie eine Zeichenfolge "friendship". Der tatsächliche Verweis auf das geänderte Objekt mit den zusätzlichen Daten, über die ich spreche, befindet sich in notification_change.notificationObjectID

das scheint mir nicht sinnvoll zu sein. Objekt ist eine Zeichenfolge (enum?) Und notificationObjectID ist ein Fremdschlüssel, der auf das Objekt verweist, um das es sich bei der Benachrichtigung handelt. Wie sind dann die mittleren und rechten Tische überhaupt verbunden?

Anscheinend gibt die mittlere Tabelle an, um welches Objekt (oder um welchen Objekttyp) es sich bei der Benachrichtigung handelt, z. B. um ein Ereignis oder einen Beitrag. In notification_change können dann viele Einträge auf denselben Objekttyp verweisen, sodass wir Benachrichtigungen bündeln können (z. B. "25 Benutzer an der Wand von X") - daher die 1: n-Beziehung zwischen der mittleren und der rechten Tabelle.

Aber warum besteht eine 1: n-Beziehung zwischen der linken und der mittleren Tabelle? Werden wir "25 Benutzern, die auf Sams Pinnwand gepostet wurden" und "Mary hat ihr Ereignis" Friday Picnic "mit derselben Benachrichtigungs-ID aktualisiert? Wenn alle Benachrichtigungen für denselben Benutzer dieselbe Benachrichtigungs-ID haben, warum benötigen wir dann überhaupt die Tabelle auf der links?

Eine Performance-Frage - sagen wir, John schreibt einen Kommentar zu Marys Picknick-Event. Es scheint, als müssten wir eine Suche durchführen, um festzustellen, ob für Mary's Picnic bereits ein notification_object vorhanden ist, bevor wir den notification_change- Eintrag erstellt haben. Wird sich dies negativ auf die Leistung auswirken oder ist dies kein Problem? Fortsetzung der Fragen aus dem vorherigen Absatz, woher wissen wir, auf welchen Benachrichtigungseintrag das notification_object zeigen soll?

user45623
quelle

Antworten:

8

Vielen Dank für solch gründliche Fragen und Entschuldigung für all die Verwirrung - 1 Jahr nach der ersten Antwort zu kommentieren ist schwer und jetzt 3 Jahre nach .. Erste Gedanken verblassen und verwirren mich auch, aber ich fürchte, das ganze Ding zu bearbeiten, weil ich nicht arbeite über das Speichern von Benachrichtigungen im Backend und nicht sicher, ob ich ohne praktische Anwendung gute Urteile fälle

Ich denke zum Zeitpunkt des Schreibens:

  • Ja und nein, notificationID war ein Fremdschlüssel, notificationObjectID nicht. Sie benötigen ein weiteres FK-Feld, um Tabellen zusammenzufügen. Ich beschuldige meine Mongo-Erfahrung, nicht so klar darüber zu sein :(
  • Ja und nein, notification_object.object ist vage, weil Sie es nur als Zeichenfolge oder als etwas Komplexes (JSON oder FK) haben können. In meinem Fall war es nur ein Nomen.

Es hängt also davon ab, wie Ihre Benachrichtigungen aussehen. Im einfachen Fall möchten Sie lediglich die gesamte Benachrichtigung mit einer bestimmten URL verknüpfen, z. B. einer Freundeseite. Deshalb ist es hilfreich, das Objekt (entityType) als Zeichenfolge zu haben. Sie binden URLs an diese URL.

Benachrichtigung "Sie haben 3 Freundschaftsanfragen hinzugefügt" kann anders gespeichert werden.

Wenn Sie sie einzeln anzeigen möchten, haben Sie 3 Benachrichtigungen, 3 Benachrichtigungsobjekte (friend_request) und 3 Einträge in notification_change, die auf einen bestimmten Freundbenutzer verweisen.

Wenn Sie eine Benachrichtigung anzeigen möchten, haben Sie 1 Benachrichtigung, 1 / mehr Objekte und 3 / mehr Aktionen. In diesem komplexen Fall, wie „Sie haben 3 Freundschaftsanfragen von Benutzer A, Benutzer B, Benutzer C“, verwenden Sie notificationObjectIDs für jeden Benutzer und haben mehrere Links in Ihrem Benachrichtigungstext.

Sollten Sie 1 oder 3 friend_request-Objekte verwenden? Es hängt davon ab

  1. Was ist das Objekt und was ist die Handlung. Wird «Artikel gemocht / kommentiert»? Oder ist es "like / comment added" und die Objekthierarchie wird nur während der Anzeige verknüpft? Hier ist Facebook, das "Kommentieren von Fotos" von "Erwähnen von Benutzern" unterscheidet, die semantisch sehr ähnlich zu sein scheinen - Sie haben dasselbe Foto, denselben Schauspieler, aber verschiedene Benachrichtigungen, die zusammengeführt werden könnten

Bildbeschreibung hier eingeben

  1. Können Sie eine Benachrichtigung entfernen oder benötigen Sie eine Historie? Wenn ich also eine Freundschaftsanfrage sende und sie dann storniere oder einen Artikel kommentiere und dann lösche, der etwas gefällt und dann nicht gefällt - sollte er dem Endbenutzer diesen Verlauf (als weitere Aktion) als zwei verschiedene Aktionen anzeigen? Wahrscheinlich nicht. Darüber hinaus ist es technisch komplexer - Sie müssen suchen, ob ein Benachrichtigungsobjekt vorhanden ist, und eine neue Benachrichtigungsänderung hinzufügen (falls nicht, fügen Sie ein neues Objekt hinzu), damit ich später die Benachrichtigungsänderung durchsuchen muss, um sie zu entfernen. Stattdessen füge ich einfach ein weiteres notification_object zu derselben Benachrichtigung hinzu und entferne es, wenn die Aktionen nicht mehr kaskadenartig gelöscht werden.

Andererseits kann es Fälle geben, in denen es nützlich sein kann, Aktionen zu gruppieren, bei denen nichts aus dem Verlauf gelöscht wird.

Ich denke, aus diesem Grund wurde zum Zeitpunkt des Schreibens eine 1: n-Beziehung zwischen der linken und der mittleren Tabelle hergestellt, sodass Sie Benachrichtigungen nicht nur nach Akteuren derselben Entität (mittlere rechte Tabelle), sondern auch nach mehreren Objekten / Entitäten gruppieren können.

Sie können jedoch den gesamten Fall vereinfachen und die Speicherung optimieren, indem Sie die Links-Mitte-Beziehung auf n: 1 umkehren, sodass für ein Ereignis Benachrichtigungen pro Benutzer generiert werden.

Damit es so aussieht ..

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

Hoffe das hat geholfen

Artjom Kurapov
quelle
Toll, danke für diese gründliche Antwort. Ich werde es durchgehen und Sie wissen lassen, wenn ich weitere Fragen habe, aber ich denke, das erklärt die Dinge sehr gut.
user45623