Comprensione di un sistema di notifica


15

Ho esaminato come costruire un sistema di notifica su SE e altrove e mi sono trovato attratto dalla soluzione che è la risposta accettata qui: /programming/9735578/building-a-notification-system che utilizza questa struttura:

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

Una notifica riguarda qualcosa (oggetto = evento, amicizia ..) che viene modificato (verbo = aggiunto, richiesto ...) da qualcuno (attore) e segnalato all'utente (soggetto). Ecco una struttura di dati normalizzata (anche se ho usato MongoDB). È necessario informare alcuni utenti delle modifiche. Quindi sono le notifiche per utente ... il che significa che se c'erano 100 utenti coinvolti, si generano 100 notifiche.

All'inizio ho pensato di aver capito questo approccio, ma quando ho iniziato a prepararmi per implementarlo mi sono reso conto che apparentemente non lo capisco particolarmente bene. Gli ultimi commenti sulla risposta sono domande di altri utenti che hanno anche avuto difficoltà a comprendere la soluzione.

Non sono sicuro che questo sia il modello che seguirò, ma dato il numero di voti che ha, sono sicuro che mi gioverebbe a comprenderlo , e sicuramente mi piacerebbe saperne di più. Spero che questo possa essere utile anche agli altri che hanno avuto difficoltà a cogliere questa soluzione (per inciso, non ho abbastanza punti internet per lasciare un commento su quella risposta che indirizza a questa domanda, chiunque altro lo faccia!)

Domande

Se ho capito bene, notificationObjectID è una punta chiave esterna alla notification_object tavolo, e notificationID è una chiave esterna che punta alla notifica di tavolo. Sembra che l' oggetto dovrebbe essere una chiave esterna che si riferisce all'ID della voce del database di cui si riferisce la notifica (ad esempio un evento o post specifico), ma non è necessario un altro campo per indicare a quale tabella appartiene quell'ID?

L'autore ha scritto

notification_object.object identifica il tipo di modifica, come una stringa "amicizia" Il riferimento effettivo all'oggetto modificato con i suoi dati extra di cui parlo è in notification_change.notificationObjectID

che non sembra avere senso per me. L'oggetto è una stringa (enum?) E notificationObjectID è una chiave esterna che fa riferimento all'oggetto di cui si riferisce la notifica? Quindi come sono collegati i tavoli medio e destro?

Sembra che la tabella centrale specifichi su quale oggetto (o tipo di oggetto) si tratti della notifica, ad esempio un evento o un post. Possiamo quindi avere molte voci in notification_change che puntano allo stesso tipo di oggetto, il che ci consente di raggruppare le notifiche (come "25 utenti pubblicati sul muro di X) - da qui la relazione 1: n tra la tabella centrale e quella destra.

Ma perché esiste una relazione 1: n tra la tabella di sinistra e quella centrale? Daremo a "25 utenti pubblicati sulla bacheca di Sam" e "Mary ha aggiornato il suo evento" Venerdì Picnic "lo stesso ID di notifica? Se tutte le notifiche per lo stesso utente hanno lo stesso ID di notifica, perché abbiamo bisogno anche della tabella nella sinistra?

Una domanda sulla performance: dire che John pubblica un commento sull'evento picnic di Mary. Sembra che dovremmo fare una ricerca per vedere se esiste già un oggetto notification_ per Mary's Picnic prima di creare la voce notification_change . Questo avrà un impatto negativo sulle prestazioni o non è un problema? Continuando le domande del paragrafo precedente, come potremmo sapere a quale voce di notifica indirizzare l' oggetto_ notifica ?

Risposte:


8

Grazie per domande così approfondite, e scusa per tutta la confusione: commentare 1 anno dopo la risposta iniziale è difficile e ora 3 anni dopo .. i pensieri iniziali svaniscono e confondono anche me, ma temo di modificare il problema perché non sto lavorando sulla memorizzazione delle notifiche sul back-end in questo momento e non sono sicuro di esprimere giudizi positivi senza un'applicazione pratica

Penso al momento della scrittura:

  • Sì e no, notificationID era una chiave esterna, notificationObjectID no. È necessario un altro campo FK per unire le tabelle. Incolpo la mia esperienza di mongo nel non essere così chiaro al riguardo :(
  • Sì e no, notification_object.object è vago perché puoi averlo come una stringa o qualcosa di complesso (JSON o FK). Nel mio caso era solo un sostantivo.

Quindi tutto dipende dall'aspetto delle tue notifiche. Per un semplice caso, vuoi solo collegare l'intera notifica a qualche URL, come la pagina degli amici - ecco perché avere un oggetto (entityType) come stringa è utile - devi legare gli URL ad esso.

La notifica "hai 3 richieste di amicizia aggiunte" può essere memorizzata in modo diverso.

Se vuoi mostrarli uno alla volta, avrai 3 notifiche, 3 oggetti di notifica (richiesta_amico) e 3 voci in notification_change che rimandano a un utente amico specifico.

Se vuoi mostrare una notifica, avrai 1 notifica, 1 / più oggetti e 3 / più azioni. Quindi, in questo caso complesso, come «hai 3 richieste di amicizia da parte dell'utente A, utente B, utente C», usi gli IDOggetti di notifica per ciascun utente e hai diversi collegamenti nel testo della notifica.

Dovresti usare 1 o 3 oggetti friend_request? Dipende da

  1. Qual è l'oggetto e qual è l'azione. L '«articolo è piaciuto / commentato»? O è «mi piace / commento aggiunto» e la gerarchia degli oggetti viene collegata solo durante la visualizzazione? Ecco Facebook che distingue il «commento fotografico» dal «menzionare l'utente» che semanticamente sembrano essere molto vicini: hai la stessa foto, lo stesso attore ma notifiche diverse che avrebbero potuto essere unite

inserisci qui la descrizione dell'immagine

  1. Puoi rimuovere una notifica o hai bisogno di una cronologia? Quindi, se invio una richiesta di amicizia e poi la annullo, o commento e quindi elimino un articolo, come e quindi diverso da qualcosa - Dovrebbe mostrare questa cronologia (come un'altra azione) all'utente finale come due diverse azioni? Probabilmente no. Inoltre, è tecnicamente più complesso: è necessario cercare se esiste un oggetto notification_it esistente, aggiungere un nuovo notification_change ad esso (in caso contrario - aggiungere un nuovo oggetto) in modo che in seguito dovrei cercare in notification_change per rimuoverlo. Invece, aggiungerei un altro oggetto_ notifica alla stessa notifica e la rimuoverei se fosse andato con le azioni che venivano eliminate a cascata.

D'altra parte, potrebbero esserci casi in cui potrebbe essere utile avere un raggruppamento di azioni in cui nulla viene cancellato dalla storia.

Penso che sia per questo che al momento della stesura della relazione 1: n tra i tavoli di sinistra e quelli centrali siano stati fatti, in modo da poter raggruppare le notifiche non solo dagli attori sulla stessa entità (tabelle di mezzo destra) ma anche da diversi oggetti / entità.

Ma certo, puoi semplificare l'intero caso e ottimizzare l'archiviazione invertendo la relazione centro-sinistra in n: 1, in modo da generare notifiche per utente generate per un evento.

In modo che sembrerebbe più così ...

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

Spero che questo abbia aiutato


Ottimo, grazie per questa risposta approfondita. Lo esaminerò e ti farò sapere se ho altre domande, ma penso che questo spieghi le cose molto bene.
user45623,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.