Le persone amano comunicare. Scherziamo spesso sul fatto che qualsiasi sistema software si evolve sempre in un sistema di messaggistica. Questo articolo spiegherà i requisiti di sistema e l'approccio passo dopo passo per progettare un modello di dati per un sistema di messaggistica.
Requisiti in breve
La funzionalità principale di un sistema di messaggistica in un'applicazione è inviare notifiche/messaggi a un utente o a un insieme di utenti. Il nostro sistema permette anche di inviare messaggi a un gruppo di utenti. I gruppi di utenti possono ovviamente essere formati su alcuni parametri come i privilegi di accesso, la posizione geografica degli utenti, ecc.
Questo sistema consente ai ricevitori di rispondere ai messaggi. Tiene anche traccia di chi ha letto il messaggio e chi no.
Inoltre, il sistema dispone di un promemoria integrato meccanismo che consente a un mittente di creare un promemoria e quindi di inviare un promemoria a tutti i destinatari di conseguenza.
Entità e relazioni
In questo modello di dati, user
e message
sono le principali entità per memorizzare i dettagli di utenti e messaggi.
Colonne nell'user
table sarebbero attributi relativi all'utente come first_name
, last_name
, ecc.
Alcune colonne autoesplicative nel message
la tabella sarebbe subject
, message_body
, create_date
e expiry_date
. Aggiungo anche una colonna di chiave esterna chiamata creator_id
in questa tabella che fa riferimento all'id
colonna di user
tavolo. Come suggerisce il nome, significa l'id del creatore di un messaggio. Poiché ci sarebbe sempre un creatore per un messaggio, mantengo questa colonna solo nella tabella dei messaggi. Ti starai chiedendo perché c'è una expiry_date
colonna nella tabella. Ho aggiunto questa colonna per gestire i promemoria su un messaggio. Spiegherò di più su questa colonna più avanti in questo articolo.
La tabella più importante in questo modello di dati è message_recipient
. Direi che l'intero modello di dati ruota solo attorno a questa tabella. Uno degli obiettivi principali alla base della creazione di questa tabella è mantenere la mappatura tra i messaggi ei relativi destinatari. Quindi il recipient_id
la colonna in questa tabella indica gli ID dei destinatari e questa colonna si riferisce alla colonna ID di user
tabella.
Quando un messaggio viene inviato a un destinatario, in questa tabella verrà inserito un record con l'ID del destinatario nel recipient_id
colonna.
Ora ti starai chiedendo quale sia il recipient_group_id
colonna significa in questa tabella. Qui, dovrei prima spiegare come questo modello può essere esteso all'esigenza di inviare messaggi a più destinatari contemporaneamente.
Invio di messaggi a un gruppo
Ho bisogno di un'altra tabella, ovvero group
, per conservare i dettagli del gruppo. Poiché esiste una relazione molti-a-molti tra l'user
e group
tabelle, ovvero un utente può far parte di più di un gruppo, creerò un'altra tabella chiamata user_group
.
Ad esempio, se si forma un gruppo con 25 utenti, ci sarebbero 25 record, uno per ogni utente, nel user_group
tabella.
Torniamo al message_recipient
tavolo. Aggiungo un riferimento alla chiave primaria del user_group
tabella nel message_recipient
tavolo. Lo chiamo recipient_group_id
. Questa colonna conterrà il valore del gruppo utenti per il quale viene inviato il messaggio.
Ora, ogni volta che un messaggio viene inviato a un gruppo, più record verranno inseriti nel message_recipient
tabella in base al numero di utenti nel gruppo e al recipient_group_id
verrà registrato di conseguenza su tutti quei record.
Permettetemi di illustrarlo ulteriormente con un esempio. Supponiamo che un messaggio venga inviato a un gruppo di 10 persone. In questo caso, un totale di 10 record, uno per ogni recipient_group_id
del gruppo, verrà inserito nel message_recipient
tabella.
Tieni presente che se il messaggio viene inviato a un utente, non a un gruppo, allora il recipient_group_id
la colonna rimane vuota. In questo caso, il diretto user_id
verrà registrato sotto il recipient_id
colonna.
Aggiungerò un'altra colonna chiamata is_read
nella tabella per tenere un flag contro un utente del messaggio che indica se il messaggio viene letto o meno dall'utente.
Chiave univoca message_recipient
tabella – Dovrebbe esserci una chiave univoca composita nelle colonne message_id
, recipient_id
e recipient_group_id
, per garantire che esista un solo record per una combinazione univoca di queste colonne.
Conservo is_active
colonna in tutte le tabelle, eccetto le tabelle message e message_recipient, al fine di abilitare una "cancellazione graduale" dei record. Dato che ho aggiunto una expiry_date
colonna nella tabella dei messaggi, un is_active
la colonna non è necessaria. Inoltre, questa colonna non è necessaria in message_recipient
tabella perché un messaggio non può essere ripristinato direttamente una volta inviato. Tuttavia è possibile renderlo inattivo aggiornando la expiry_date
per il messaggio a una data nel passato.
Risposta a un messaggio
Supponiamo ora che il sistema consenta agli utenti di rispondere ai messaggi ricevuti. Estendo la stessa tabella message
per soddisfare questo requisito invece di creare una nuova tabella per le risposte. Aggiungerò una colonna chiamata parent_message_id
per stabilire una relazione gerarchica tra i messaggi. Inserirò un nuovo record per il messaggio di risposta e aggiornerò il parent_message_id
colonna per i messaggi di risposta. Questo modello supporta n-livello di relazione gerarchica, ovvero la risposta al messaggio di risposta può anche essere tracciata attraverso questo modello.
Dashboard per visualizzare la "% di lettura" di ogni messaggio
Il is_read
flag viene registrato su ogni record utente del messaggio. Il valore di questo flag rimane ZERO finché il messaggio non viene letto dall'utente. Verrà aggiornato a ONE non appena il messaggio viene letto dall'utente. In base al valore della colonna, è possibile determinare la "% di lettura" per un messaggio inviato a un gruppo.
Consentitemi di scrivere un esempio SQL per recuperare un rapporto del genere:
SELECT msg.subject, sent_to, msg.create_date, (summ / countt) * 100 AS Read_Per FROM (SELECT msg.subject, grp.name as sent_to, msg.create_date, SUM (is_read) AS summ, COUNT (is_read) AS countt FROM message_recipient msgrec, message msg, user_group ug, group grp WHERE msgrec.message_id = msg.id AND msgrec.recipient_group_id = ug.id AND ug.GROUP_ID = grp.id AND msgrec.recipient_group_id IS NOT NULL GROUP BY msg.subject, grp.name, msg.create_date UNION SELECT msg.subject, u.first_name || ' ' || u.last_name as sent_to, msg.create_date, SUM (is_read) AS summ, COUNT (is_read) AS countt FROM message_recipient msgrec, MESSAGE msg, user u WHERE msgrec.message_id = msg.id AND msgrec.recipient_id = u.id AND msgrec.recipient_group_id IS NULL GROUP BY msg.subject, name, msg.create_date);
Soggetto | Inviato a | Inviato | Leggi% |
---|---|---|---|
Consegna del progetto prevista per martedì | Team di consegna del progetto | 13/09/2015 08:15 | 42% |
Ci vediamo lunedì | Giovanni D | 9/10/2015 13:30 | 100% |
Sincronizza l'ambiente di sviluppo con la produzione | Team DBA | 9/9/2015 09:11 | 80% |
Chiudere gli NCR di audit | Team NSS | 9/9/2015 17:50 | 45% |
Meccanismo promemoria
Per una funzionalità di promemoria, aggiungerò le seguenti colonne nella tabella dei messaggi:
Is_reminder
– Questa colonna indica se è necessario o meno un promemoria per il messaggio.Reminder_frequency_id
– Questa colonna indica la frequenza del promemoria. Dovrebbe essere su base giornaliera o settimanale?Next_remind_date
– Questa colonna contiene la data in cui è necessario inviare il promemoria successivo. Il promemoria verrà inviato ilnext_remind_date
per gli utenti per i quali il flag 'is_read' è ancora ZERO. Un nuovo valore per questa colonna verrà calcolato ogni volta che viene inviato un promemoria.Expiry_date
– Questa colonna è la data limite in cui i promemoria non verranno più inviati agli utenti.
Calcolo del next_remind_date
sarebbe il seguente:supponiamo che un messaggio venga inviato agli utenti il 14/9, lunedì con il 5/10 come data di scadenza. Il messaggio viene inviato con una frequenza settimanale di promemoria. In questo caso, i promemoria verranno inviati agli utenti il 21/9 e il 28/9 per rispondere via e-mail e un'ultima volta il 5/10 per invitarli a rispondere nelle prossime 24 ore.
Modello di dati finali
Conclusione
Uno dei migliori utilizzi di questo sistema di messaggistica è inviare notifiche agli utenti che sono rimasti inattivi nel sistema per molto tempo. Queste notifiche possono essere inviate con un meccanismo di promemoria abilitato e le notifiche verranno inviate agli utenti finché gli utenti non rispondono alla notifica. Gli utenti verranno disattivati alla data di scadenza e dopo la data di scadenza se non riceveranno risposta alle notifiche da parte loro.
Intendevo costruire un modello di dati per un sistema di messaggistica completamente funzionale, che può essere inserito in una varietà di sistemi per inviare messaggi/notifiche. Sentiti libero di condividere le tue opinioni/input/commenti sull'articolo.