sql >> Database >  >> RDS >> Database

Databasemodel voor een berichtensysteem

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


  1. Gebruik ik JDBC Connection Pooling?

  2. Krijg het aantal dagen in een maand in PostgreSQL

  3. lopende balans berekenen in oracle-query

  4. bouw dynamische SQL-query's met psycopg2 python-bibliotheek en gebruik goede conversietools