Folk elsker at kommunikere. Vi spøger ofte med, at ethvert softwaresystem altid udvikler sig til et meddelelsessystem. Denne artikel vil forklare systemkravene og trin for trin tilgang til at designe en datamodel til et meddelelsessystem.
Krav i nøddeskal
Kernefunktionaliteten i et meddelelsessystem i en applikation er at sende meddelelser/beskeder til en bruger eller et sæt brugere. Vores system giver også mulighed for at sende beskeder til en brugergruppe. Brugergrupper kan naturligvis dannes på nogle parametre som adgangsrettigheder, geografisk placering af brugere osv.
Dette system gør det muligt for modtagere at reagere til beskederne. Den holder også styr på, hvem der har læst beskeden, og hvem der ikke har.
Derudover har systemet en indbygget påmindelse mekanisme, der tillader en afsender at oprette en påmindelse og derefter sender en påmindelse til alle modtagere i overensstemmelse hermed.
Enheder og relationer
I denne datamodel, user
og message
er de vigtigste enheder til at gemme brugernes og beskeders detaljer.
Kolonner i user
tabel ville være brugerrelaterede attributter som first_name
, last_name
osv.
Nogle selvforklarende kolonner i message
tabel ville være subject
, message_body
, create_date
og expiry_date
. Jeg tilføjer også en fremmednøglekolonne kaldet creator_id
i denne tabel, der henviser til id
kolonne af user
bord. Som navnet antyder, betyder det id'et for skaberen af en meddelelse. Da der altid vil være én skaber til en besked, beholder jeg kun denne kolonne i beskedtabellen. Du undrer dig måske over, hvorfor der er en expiry_date
kolonne i tabellen. Jeg har tilføjet denne kolonne for at administrere påmindelser på en besked. Jeg vil forklare mere om denne kolonne senere i denne artikel.
Den vigtigste tabel i denne datamodel er message_recipient
. Jeg vil sige, at hele datamodellen kun drejer sig om denne tabel. Et af hovedformålene bag oprettelsen af denne tabel er at holde kortlægningen mellem meddelelser og deres modtagere. Således recipient_id
kolonne i denne tabel angiver modtagernes id'er, og denne kolonne henviser til id-kolonnen for user
tabel.
Når en besked sendes til én modtager, indsættes én post i denne tabel med modtagerens id i recipient_id
kolonne.
Nu undrer du dig måske over, hvad recipient_group_id
er kolonne betyder i denne tabel. Her skal jeg først forklare, hvordan denne model kan udvides til et krav om at sende beskeder til flere modtagere på én gang.
Sender besked til en gruppe
Jeg har brug for en anden tabel, nemlig group
, for at opbevare gruppeoplysninger. Da der er et mange-til-mange forhold mellem user
og group
tabeller, dvs. en bruger kan være en del af mere end én gruppe, vil jeg oprette en anden tabel kaldet user_group
.
For eksempel, hvis en gruppe dannes med 25 brugere, vil der være 25 poster, én for hver bruger, i user_group
tabel.
Lad os vende tilbage til message_recipient
bord. Jeg tilføjer en reference til den primære nøgle i user_group
tabellen i message_recipient
bord. Jeg navngiver den recipient_group_id
. Denne kolonne vil indeholde værdien af den brugergruppe, som beskeden er sendt til.
Nu når en besked sendes til en gruppe, vil flere poster blive indsat i message_recipient
tabel baseret på antallet af brugere i gruppen og recipient_group_id
vil blive logget i overensstemmelse hermed mod alle disse poster.
Lad mig illustrere det yderligere med et eksempel. Antag, at en besked sendes til en gruppe på 10 personer. I dette tilfælde i alt 10 poster, én for hver recipient_group_id
af gruppen, vil blive indsat i message_recipient
tabel.
Bemærk venligst, at hvis beskeden sendes til en bruger, ikke en gruppe, så er recipient_group_id
kolonne forbliver tom. I dette tilfælde er den direkte user_id
vil blive logget under recipient_id
kolonne.
Jeg vil tilføje en kolonne mere kaldet is_read
ind i tabellen for at holde et flag mod en meddelelsesbruger, der angiver, om meddelelsen er læst af brugeren eller ej.
Unik nøgle ind message_recipient
tabel – Der skal være en sammensat unik nøgle i kolonnerne message_id
, recipient_id
og recipient_group_id
, for at sikre, at der kun findes én post for en unik kombination af disse kolonner.
Jeg beholder is_active
kolonne i alle tabeller, undtagen meddelelses- og message_recipient-tabellerne, for at aktivere en 'blød sletning' af poster. Siden jeg har tilføjet en expiry_date
kolonne i meddelelsestabellen, en is_active
kolonne er ikke nødvendig. Desuden er denne kolonne ikke nødvendig i message_recipient
tabel, fordi en meddelelse ikke kan tilbageføres direkte, når den først er sendt. Man kan dog gøre det inaktivt ved at opdatere expiry_date
for beskeden til en dato i fortiden.
Svar på en besked
Antag nu, at systemet tillader brugere at svare på modtagne beskeder. Jeg udvider den samme tabel message
for at imødekomme dette krav i stedet for at oprette en ny tabel til svar. Jeg tilføjer en kolonne kaldet parent_message_id
at etablere et hierarkisk forhold mellem meddelelser. Jeg vil indsætte en ny registrering for svarbesked og opdatere parent_message_id
kolonne for svarbeskeder. Denne model understøtter n-niveau af hierarkisk relation, dvs. svar på svarmeddelelse kan også spores gennem denne model.
Dashboard for at se "Læs %" af hver besked
is_read
flag logges mod hver meddelelsesbrugerpost. Værdien for dette flag forbliver NUL, indtil meddelelsen læses af brugeren. Den vil blive opdateret til ONE, så snart beskeden er læst af brugeren. Baseret på kolonneværdien kan man bestemme 'læst %' for en besked, der sendes til en gruppe.
Lad mig skrive et eksempel på SQL for at hente sådan en 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);
Emne | Sendt til | Sendt | Læs % |
---|---|---|---|
Projektlevering på tirsdag | Projektleveringsteam | 9/13/2015 08:15 | 42 % |
Mød mig på mandag | John D | 9/10/2015 13:30 | 100 % |
Synkroniser udviklermiljø med produktion | DBA-hold | 9/9/2015 09:11 | 80 % |
Afslutning af NCR'er for revision | NSS-team | 9/9/2015 17:50 | 45 % |
Mindemekanisme
For en påmindelsesfunktionalitet vil jeg tilføje følgende kolonner i meddelelsestabellen:
Is_reminder
– Denne kolonne markerer, om der kræves en påmindelse for beskeden.Reminder_frequency_id
– Denne kolonne angiver hyppigheden af påmindelsen. Skal det være på daglig basis eller ugentlig basis?Next_remind_date
– Denne kolonne indeholder datoen for, hvornår den næste rykker skal sendes. Påmindelsen sendes pånext_remind_date
for de brugere, for hvem flaget "er_læst" stadig er NUL. En ny værdi for denne kolonne vil blive beregnet, hver gang der sendes en påmindelse.Expiry_date
– Denne kolonne er skæringsdatoen, når påmindelser ikke længere vil blive sendt til brugere.
Beregning af next_remind_date
ville være som følger – Antag, at der sendes én besked til brugere den 14/9, mandag med 10/5 som udløbsdato for den. Beskeden sendes med en ugentlig frekvens af påmindelser. I dette tilfælde vil der blive sendt påmindelser til brugerne den 21/9 og 28/9 om at svare på dem på e-mail, og en sidste gang den 10/5 for at opfordre dem til at svare inden for de næste 24 timer.
Endelig datamodel
Konklusion
En af de bedste anvendelser af dette meddelelsessystem er at sende meddelelser til brugere, der har været inaktive i systemet i lang tid. Disse meddelelser kan sendes med en påmindelsesmekanisme aktiveret, og meddelelser vil blive sendt til brugerne, indtil brugerne svarer på meddelelsen. Brugere vil blive deaktiveret på og efter udløbsdatoen, hvis der ikke modtages svar på meddelelserne fra dem.
Jeg havde til hensigt at bygge en datamodel for et fuldt funktionelt meddelelsessystem, som kan passes ind i en række forskellige systemer til at sende meddelelser/meddelelser. Del gerne dine synspunkter/ inputs/ kommentarer til artiklen.