Mensen houden van communiceren. We maken vaak grapjes dat elk softwaresysteem altijd evolueert naar een berichtensysteem. In dit artikel worden de systeemvereisten uitgelegd en wordt stap voor stap uitgelegd hoe u een gegevensmodel voor een berichtensysteem kunt ontwerpen.
Vereisten in een notendop
De kernfunctionaliteit van een berichtensysteem in een applicatie is om meldingen/berichten te verzenden aan een gebruiker of een groep gebruikers. Ons systeem maakt het ook mogelijk om berichten naar een gebruikersgroep te sturen. Gebruikersgroepen kunnen uiteraard worden gevormd op basis van bepaalde parameters, zoals toegangsrechten, geografische locatie van gebruikers, enz.
Met dit systeem kunnen ontvangers reageren naar de berichten. Het houdt ook bij wie het bericht heeft gelezen en wie niet.
Bovendien heeft het systeem een ingebouwde herinnering mechanisme waarmee een afzender een herinnering kan maken en dienovereenkomstig een herinnering naar alle ontvangers stuurt.
Entiteiten en relaties
In dit gegevensmodel, user
en message
zijn de belangrijkste entiteiten om de gegevens van gebruikers en berichten op te slaan.
Kolommen in de user
tabel zou gebruikersgerelateerde attributen zijn zoals first_name
, last_name
, enz.
Enkele voor zichzelf sprekende kolommen in het message
tabel zou zijn subject
, message_body
, create_date
en expiry_date
. Ik voeg ook een externe sleutelkolom toe met de naam creator_id
in deze tabel die verwijst naar de id
kolom van user
tafel. Zoals de naam al doet vermoeden, betekent het de id van de maker van een bericht. Aangezien er altijd één maker voor een bericht zou zijn, bewaar ik deze kolom alleen in de berichtentabel. Je vraagt je misschien af waarom er een expiry_date
. is kolom in de tabel. Ik heb deze kolom toegevoegd om herinneringen voor een bericht te beheren. Ik zal verderop in dit artikel meer over deze column uitleggen.
De belangrijkste tabel in dit gegevensmodel is message_recipient
. Ik zou zeggen dat het hele datamodel alleen om deze tabel draait. Een van de belangrijkste doelstellingen achter het maken van deze tabel is om de toewijzing tussen berichten en hun ontvangers vast te houden. Dus de recipient_id
kolom in deze tabel geeft de ID's van de ontvangers aan, en deze kolom verwijst naar de ID-kolom van user
tafel.
Wanneer een bericht naar één ontvanger wordt verzonden, wordt één record in deze tabel ingevoegd met het ID van de ontvanger in de recipient_id
kolom.
Nu vraag je je misschien af wat de recipient_group_id
kolom betekent in deze tabel. Hier moet ik eerst uitleggen hoe dit model kan worden uitgebreid tot een vereiste om berichten naar meerdere ontvangers tegelijk te verzenden.
Bericht verzenden naar een groep
Ik heb een andere tabel nodig, namelijk group
, om groepsdetails vast te houden. Aangezien er een veel-op-veel-relatie is tussen de user
en group
tabellen, d.w.z. een gebruiker kan deel uitmaken van meer dan één groep, ik zal een andere tabel maken met de naam user_group
.
Als er bijvoorbeeld een groep wordt gevormd met 25 gebruikers, zouden er 25 records zijn, één voor elke gebruiker, in de user_group
tafel.
Laten we teruggaan naar de message_recipient
tafel. Ik voeg een verwijzing toe naar de primaire sleutel van de user_group
tabel in de message_recipient
tafel. Ik noem het recipient_group_id
. Deze kolom bevat de waarde van de gebruikersgroep waarvoor het bericht is verzonden.
Wanneer nu een bericht naar een groep wordt verzonden, worden meerdere records ingevoegd in de message_recipient
tabel op basis van het aantal gebruikers in de groep en de recipient_group_id
wordt overeenkomstig al die records geregistreerd.
Laat ik het verder illustreren met een voorbeeld. Stel, er wordt een bericht gestuurd naar een groep van 10 personen. In dit geval in totaal 10 records, één voor elke recipient_group_id
van de groep, wordt ingevoegd in de message_recipient
tafel.
Houd er rekening mee dat als het bericht wordt verzonden naar een gebruiker, niet naar een groep, de recipient_group_id
kolom blijft leeg. In dit geval is de directe user_id
wordt gelogd onder de recipient_id
kolom.
Ik zal nog een kolom toevoegen met de naam is_read
in de tabel om een vlag tegen een berichtgebruiker te houden die aangeeft of het bericht al dan niet door de gebruiker wordt gelezen.
Unieke sleutel in message_recipient
tabel – Er moet een samengestelde unieke sleutel zijn in de kolommen message_id
, recipient_id
en recipient_group_id
, om ervoor te zorgen dat er slechts één record bestaat voor een unieke combinatie van deze kolommen.
Ik bewaar de is_active
kolom in alle tabellen, behalve de tabellen message en message_recipient, om een 'soft delete' van records mogelijk te maken. Sinds ik een expiry_date
heb toegevoegd kolom in de berichtentabel, een is_active
kolom is niet nodig. Bovendien is deze kolom niet nodig in de message_recipient
tabel omdat een bericht niet direct kan worden teruggedraaid nadat het is verzonden. Men kan het echter inactief maken door de expiry_date
. bij te werken voor het bericht naar een datum in het verleden.
Een bericht beantwoorden
Stel nu dat het systeem gebruikers in staat stelt te reageren op ontvangen berichten. Ik verleng dezelfde tabel message
om aan deze eis te voldoen in plaats van een nieuwe tabel voor antwoorden te maken. Ik zal een kolom toevoegen met de naam parent_message_id
om een hiërarchische relatie tussen berichten tot stand te brengen. Ik zal een nieuw record voor het antwoordbericht invoegen en de parent_message_id
. bijwerken kolom voor antwoordberichten. Dit model ondersteunt hiërarchische relaties op n-niveau, d.w.z. het antwoord op een antwoordbericht kan ook via dit model worden gevolgd.
Dashboard om 'gelezen %' van elk bericht te bekijken
De is_read
vlag wordt vastgelegd tegen elk bericht-gebruiker record. De waarde voor deze vlag blijft NUL totdat het bericht door de gebruiker is gelezen. Het wordt bijgewerkt naar EEN zodra het bericht door de gebruiker is gelezen. Op basis van de kolomwaarde kan men 'lees %' bepalen voor een bericht dat naar een groep wordt gestuurd.
Laat me een voorbeeld-SQL schrijven om zo'n rapport op te halen:
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);
Onderwerp | Verzonden naar | Verzonden | Lees % |
---|---|---|---|
Oplevering project op dinsdag | Team projectoplevering | 13-09-2015 08:15 | 42% |
Ontmoet me op maandag | John D | 9/10/2015 13:30 | 100% |
Ontwikkelomgeving synchroniseren met productie | DBA-team | 9/9/2015 09:11 | 80% |
NCR's van controle afsluiten | NSS-team | 9/9/2015 17:50 | 45% |
Herinneringsmechanisme
Voor een herinneringsfunctie zal ik de volgende kolommen in de berichtentabel toevoegen:
Is_reminder
– Deze kolom geeft aan of een herinnering al dan niet vereist is voor het bericht.Reminder_frequency_id
– Deze kolom geeft de frequentie van de herinnering aan. Moet het dagelijks of wekelijks zijn?Next_remind_date
– Deze kolom bevat de datum waarop de volgende herinnering moet worden verzonden. De herinnering wordt verzonden op denext_remind_date
voor de gebruikers voor wie de vlag 'is_read' nog steeds NUL is. Elke keer dat een herinnering wordt verzonden, wordt een nieuwe waarde voor deze kolom berekend.Expiry_date
– Deze kolom is de sluitingsdatum wanneer er geen herinneringen meer naar gebruikers worden verzonden.
Berekening van de next_remind_date
zou als volgt zijn - Stel dat er één bericht naar gebruikers wordt verzonden op 14-9, maandag met 10/5 als vervaldatum. Het bericht wordt verstuurd met een wekelijkse frequentie van herinneringen. In dit geval worden gebruikers op 21-9 en 28-9 een herinnering gestuurd om ze per e-mail te beantwoorden, en een laatste keer op 5-10 om hen aan te sporen binnen 24 uur te reageren.
Definitief gegevensmodel
Conclusie
Een van de beste toepassingen van dit berichtensysteem is om meldingen te sturen naar gebruikers die lange tijd inactief zijn geweest in het systeem. Deze meldingen kunnen worden verzonden met een herinneringsmechanisme ingeschakeld, en meldingen worden naar gebruikers verzonden totdat gebruikers op de melding reageren. Gebruikers worden op en na de vervaldatum gedeactiveerd als er geen reactie op de meldingen van hen wordt ontvangen.
Ik was van plan een datamodel te bouwen voor een volledig functioneel berichtensysteem, dat in verschillende systemen kan worden ingepast om berichten/meldingen te verzenden. Voel je vrij om je mening/input/opmerkingen over het artikel te delen.