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é lenext_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.