Database
 sql >> Database >  >> RDS >> Database

Modello di database per un sistema di messaggistica

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 il next_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.