Database
 sql >> Base de données >  >> RDS >> Database

Modèle de base de données pour un système de messagerie

Les gens aiment communiquer. Nous plaisantons souvent sur le fait que tout système logiciel évolue toujours vers un système de messagerie. Cet article explique la configuration système requise et l'approche étape par étape pour concevoir un modèle de données pour un système de messagerie.

Exigences en bref

La fonctionnalité principale d'un système de messagerie dans une application consiste à envoyer des notifications/messages à un utilisateur ou à un ensemble d'utilisateurs. Notre système permet également d'envoyer des messages à un groupe d'utilisateurs. Les groupes d'utilisateurs peuvent évidemment être formés sur certains paramètres comme les privilèges d'accès, la localisation géographique des utilisateurs, etc.

Ce système permet aux destinataires de répondre aux messages. Il permet également de savoir qui a lu le message et qui ne l'a pas lu.

De plus, le système dispose d'un rappel intégré mécanisme qui permet à un expéditeur de créer un rappel, puis envoie un rappel à tous les destinataires en conséquence.

Entités et relations

Dans ce modèle de données, user et message sont les principales entités pour stocker les détails des utilisateurs et des messages.

Colonnes dans le user table serait des attributs liés à l'utilisateur comme first_name , last_name , etc.

Quelques colonnes explicites dans le message table serait subject , message_body , create_date et expiry_date . J'ajoute également une colonne de clé étrangère appelée creator_id dans ce tableau qui fait référence à l'id colonne de user table. Comme son nom l'indique, il signifie l'identifiant du créateur d'un message. Puisqu'il y aurait toujours un créateur pour un message, je garde cette colonne dans la table des messages uniquement. Vous vous demandez peut-être pourquoi il y a une expiry_date colonne dans le tableau. J'ai ajouté cette colonne pour gérer les rappels sur un message. J'expliquerai plus sur cette colonne plus tard dans cet article.

La table la plus importante de ce modèle de données est message_recipient . Je dirais que tout le modèle de données tourne autour de cette table uniquement. L'un des principaux objectifs de la création de cette table est de conserver le mappage entre les messages et leurs destinataires. Ainsi le recipient_id la colonne de ce tableau indique les identifiants des destinataires, et cette colonne fait référence à la colonne d'identifiant de user tableau.

Lorsqu'un message est envoyé à un destinataire, un enregistrement sera inséré dans cette table avec l'identifiant du destinataire dans le recipient_id colonne.

Maintenant, vous vous demandez peut-être ce que le recipient_group_id colonne signifie dans ce tableau. Ici, je dois d'abord expliquer comment ce modèle peut être étendu à une exigence d'envoi de messages à plusieurs destinataires à la fois.

Envoi d'un message à un groupe

J'ai besoin d'une autre table, à savoir group , pour conserver les détails du groupe. Puisqu'il existe une relation plusieurs à plusieurs entre le user et group tables, c'est-à-dire qu'un utilisateur peut faire partie de plusieurs groupes, je vais créer une autre table appelée user_group .

Par exemple, si un groupe est formé avec 25 utilisateurs, il y aura 25 enregistrements, un pour chaque utilisateur, dans le user_group tableau.

Revenons au message_recipient table. J'ajoute une référence à la clé primaire du user_group table dans le message_recipient table. Je le nomme recipient_group_id . Cette colonne contiendra la valeur du groupe d'utilisateurs pour lequel le message est envoyé.

Désormais, chaque fois qu'un message est envoyé à un groupe, plusieurs enregistrements seront insérés dans le message_recipient table basée sur le nombre d'utilisateurs dans le groupe et le recipient_group_id sera consigné en conséquence dans tous ces enregistrements.

Permettez-moi de l'illustrer davantage avec un exemple. Supposons qu'un message soit envoyé à un groupe de 10 personnes. Dans ce cas, un total de 10 enregistrements, un pour chaque recipient_group_id du groupe, sera inséré dans le message_recipient tableau.

Veuillez noter que si le message est envoyé à un utilisateur, pas à un groupe, alors le recipient_group_id colonne reste vide. Dans ce cas, le user_id direct sera enregistré sous le recipient_id colonne.

Je vais ajouter une autre colonne appelée is_read dans la table pour maintenir un indicateur contre un utilisateur de message qui indique si le message est lu ou non par l'utilisateur.

Clé unique message_recipient table – Il devrait y avoir une clé unique composite sur les colonnes message_id , recipient_id et recipient_group_id , afin de garantir qu'un seul enregistrement existe pour une combinaison unique de ces colonnes.

Je garde le is_active colonne dans toutes les tables, à l'exception des tables message et message_recipient, afin de permettre une "suppression réversible" des enregistrements. Depuis que j'ai ajouté une expiry_date colonne dans la table des messages, un is_active colonne n'est pas nécessaire. De plus, cette colonne n'est pas nécessaire dans le message_recipient car un message ne peut pas être annulé directement une fois envoyé. Cependant on peut le rendre inactif en mettant à jour le expiry_date pour le message à une date dans le passé.

Répondre à un message

Supposons maintenant que le système autorise les utilisateurs à répondre aux messages reçus. J'étends le même tableau message pour répondre à cette exigence au lieu de créer un nouveau tableau pour les réponses. Je vais ajouter une colonne appelée parent_message_id pour établir une relation hiérarchique entre les messages. Je vais insérer un nouvel enregistrement pour le message de réponse et mettre à jour le parent_message_id colonne pour les messages de réponse. Ce modèle prend en charge n niveaux de relation hiérarchique, c'est-à-dire que la réponse sur message de réponse peut également être suivie via ce modèle.

Tableau de bord pour afficher le « % de lecture » ​​de chaque message

Le is_read L'indicateur est consigné pour chaque enregistrement d'utilisateur de message. La valeur de cet indicateur reste ZERO jusqu'à ce que le message soit lu par l'utilisateur. Il sera mis à jour à ONE dès que le message sera lu par l'utilisateur. Sur la base de la valeur de la colonne, on peut déterminer "% lu" pour un message envoyé à un groupe.

Permettez-moi d'écrire un exemple de code SQL pour récupérer un tel rapport :

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);


Sujet Envoyé à Envoyé Lire %
Livraison du projet prévue mardi Équipe de réalisation du projet 13/09/2015 08:15 42 %
Retrouvez-moi lundi Jean D 9/10/2015 13:30 100 %
Synchroniser l'environnement de développement avec la production Équipe DBA 09/09/2015 09:11 80 %
Clôturer les NCR d'audit Équipe NSS 09/09/2015 17:50 45 %

Mécanisme de rappel

Pour une fonctionnalité de rappel, j'ajouterai les colonnes suivantes dans le tableau des messages :

  • Is_reminder – Cette colonne indique si un rappel est requis ou non pour le message.
  • Reminder_frequency_id – Cette colonne indique la fréquence du rappel. Doit-il être quotidien ou hebdomadaire ?
  • Next_remind_date – Cette colonne contient la date à laquelle le prochain rappel doit être envoyé. Le rappel sera envoyé le next_remind_date pour les utilisateurs pour lesquels le drapeau 'is_read' est toujours à ZERO. Une nouvelle valeur pour cette colonne sera calculée chaque fois qu'un rappel est envoyé.
  • Expiry_date – Cette colonne est la date limite à laquelle les rappels ne seront plus envoyés aux utilisateurs.

Calcul de la next_remind_date serait comme suit - Supposons qu'un message soit envoyé aux utilisateurs le 14/09, lundi avec le 05/10 comme date d'expiration. Le message est envoyé avec une fréquence hebdomadaire de rappels. Dans ce cas, des rappels seront envoyés aux utilisateurs le 21/09 et le 28/09 pour leur répondre par e-mail, et une dernière fois le 05/10 pour les inviter à répondre dans les prochaines 24 heures.

Modèle de données final



Conclusion

L'une des meilleures utilisations de ce système de messagerie est d'envoyer des notifications aux utilisateurs qui sont restés longtemps inactifs dans le système. Ces notifications peuvent être envoyées avec un mécanisme de rappel activé, et les notifications seront envoyées aux utilisateurs jusqu'à ce que les utilisateurs répondent à la notification. Les utilisateurs seront désactivés à compter de la date d'expiration si aucune réponse aux notifications n'est reçue de leur part.

J'avais l'intention de construire un modèle de données pour un système de messagerie entièrement fonctionnel, qui peut être intégré à une variété de systèmes pour envoyer des messages/notifications. N'hésitez pas à partager vos points de vue/contributions/commentaires sur l'article.