Database
 sql >> Baza danych >  >> RDS >> Database

Model bazy danych dla systemu komunikacyjnego

Ludzie uwielbiają się komunikować. Często żartujemy, że każdy system oprogramowania zawsze ewoluuje w system przesyłania wiadomości. W tym artykule wyjaśniono wymagania systemowe i krok po kroku podejście do projektowania modelu danych dla systemu przesyłania wiadomości.

Wymagania w skrócie

Podstawową funkcją systemu przesyłania wiadomości w aplikacji jest wysyłanie powiadomień/wiadomości do użytkownika lub zbioru użytkowników. Nasz system umożliwia również wysyłanie wiadomości do grupy użytkowników. Grupy użytkowników można oczywiście tworzyć na podstawie niektórych parametrów, takich jak uprawnienia dostępu, położenie geograficzne użytkowników itp.

Ten system umożliwia odbiorcom odpowiedź do wiadomości. Śledzi również, kto przeczytał wiadomość, a kto nie.

Ponadto system ma wbudowane przypomnienie mechanizm, który pozwala nadawcy stworzyć przypomnienie, a następnie odpowiednio wysłać przypomnienie do wszystkich odbiorców.

Podmioty i relacje

W tym modelu danych user i message są głównymi podmiotami przechowującymi dane użytkowników i wiadomości.

Kolumny w user tabela byłaby atrybutami związanymi z użytkownikiem, takimi jak first_name , last_name itp.

Niektóre oczywiste kolumny w message tabela byłaby subject , message_body , create_date i expiry_date . Dodaję również kolumnę klucza obcego o nazwie creator_id w tej tabeli, która odwołuje się do id kolumna user stół. Jak sama nazwa wskazuje, oznacza id twórcy wiadomości. Ponieważ dla wiadomości zawsze będzie jeden twórca, zachowuję tę kolumnę tylko w tabeli wiadomości. Być może zastanawiasz się, dlaczego istnieje expiry_date kolumna w tabeli. Dodałem tę kolumnę, aby zarządzać przypomnieniami w wiadomościach. Więcej na temat tej kolumny wyjaśnię w dalszej części tego artykułu.

Najważniejszą tabelą w tym modelu danych jest message_recipient . Powiedziałbym, że cały model danych kręci się tylko wokół tej tabeli. Jednym z głównych celów tworzenia tej tabeli jest odwzorowanie wiadomości i ich odbiorców. Zatem recipient_id kolumna w tej tabeli oznacza identyfikatory odbiorców, a ta kolumna odnosi się do kolumny identyfikatora user tabela.

Gdy wiadomość zostanie wysłana do jednego odbiorcy, do tej tabeli zostanie wstawiony jeden rekord z identyfikatorem odbiorcy w recipient_id kolumna.

Teraz możesz się zastanawiać, jaki jest recipient_group_id kolumna oznacza w tej tabeli. W tym miejscu powinienem najpierw wyjaśnić, w jaki sposób ten model można rozszerzyć o wymóg wysyłania wiadomości do wielu odbiorców jednocześnie.

Wysyłanie wiadomości do grupy

Potrzebuję innej tabeli, a mianowicie group , aby przechowywać szczegóły grupy. Ponieważ istnieje relacja wiele-do-wielu między user i group tabele, czyli użytkownik może należeć do więcej niż jednej grupy, utworzę kolejną tabelę o nazwie user_group .

Na przykład, jeśli grupa jest utworzona z 25 użytkownikami, w user_group tabela.

Wróćmy do message_recipient stół. Dodaję odwołanie do klucza podstawowego user_group tabeli do message_recipient stół. Nazywam go recipient_group_id . Ta kolumna będzie zawierać wartość grupy użytkowników, dla której wiadomość jest wysłana.

Teraz za każdym razem, gdy wiadomość jest wysyłana do grupy, wiele rekordów zostanie wstawionych do message_recipient tabela na podstawie liczby użytkowników w grupie i recipient_group_id zostaną odpowiednio zarejestrowane we wszystkich tych rekordach.

Pozwólcie, że zilustruję to dalej przykładem. Załóżmy, że wiadomość została wysłana do grupy 10 osób. W tym przypadku łącznie 10 rekordów, po jednym dla każdego recipient_group_id grupy, zostanie wstawiony do message_recipient tabela.

Pamiętaj, że jeśli wiadomość jest wysyłana do użytkownika, a nie do grupy, to recipient_group_id kolumna pozostaje pusta. W tym przypadku bezpośredni user_id zostanie zarejestrowany pod recipient_id kolumna.

Dodam jeszcze jedną kolumnę o nazwie is_read do tabeli, aby umieścić flagę przy użytkowniku wiadomości, która wskazuje, czy wiadomość jest czytana przez użytkownika.

Unikalny klucz message_recipient tabela – powinien znajdować się unikalny klucz złożony w kolumnach message_id , recipient_id i recipient_group_id , aby zapewnić, że istnieje tylko jeden rekord dla unikalnej kombinacji tych kolumn.

Zachowuję is_active kolumnę we wszystkich tabelach z wyjątkiem message i message_recipient, aby umożliwić „miękkie usuwanie” rekordów. Ponieważ dodałem expiry_date kolumna w tabeli wiadomości, is_active kolumna nie jest potrzebna. Co więcej, ta kolumna nie jest potrzebna w message_recipient tabeli, ponieważ wiadomości nie można cofnąć bezpośrednio po jej wysłaniu. Można go jednak dezaktywować, aktualizując expiry_date dla wiadomości z datą z przeszłości.

Odpowiadanie na wiadomość

Załóżmy teraz, że system pozwala użytkownikom odpowiadać na otrzymane wiadomości. Rozszerzam tę samą tabelę message aby spełnić ten wymóg, zamiast tworzyć nową tabelę odpowiedzi. Dodam jedną kolumnę o nazwie parent_message_id aby ustanowić hierarchiczną relację między wiadomościami. Wstawię nowy rekord do wiadomości zwrotnej i zaktualizuję parent_message_id kolumna na wiadomości zwrotne. Model ten obsługuje n-poziomową relację hierarchiczną, tj. odpowiedź na wiadomość zwrotną może być również śledzona za pomocą tego modelu.

Panel do przeglądania „odczytu %” każdej wiadomości

is_read flaga jest rejestrowana dla każdego rekordu użytkownika wiadomości. Wartość tej flagi pozostaje ZERO, dopóki wiadomość nie zostanie odczytana przez użytkownika. Zostanie zaktualizowany do JEDNEGO, gdy tylko wiadomość zostanie przeczytana przez użytkownika. Na podstawie wartości kolumny można określić „% odczytu” wiadomości wysyłanej do grupy.

Napiszę przykładowy kod SQL, aby pobrać taki raport:

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


Temat Wysłano do Wysłane Czytaj %
Dostarczenie projektu we wtorek Zespół realizujący projekt 13.09.2015 08:15 42%
Spotkajmy się w poniedziałek Jan D 10.09.2015 13:30 100%
Zsynchronizuj środowisko deweloperskie z produkcją zespół DBA 09.09.2015 09:11 80%
Zamykanie NCR audytu Zespół NSS 09.09.2015 17:50 45%

Mechanizm przypominania

Dla przypomnienia dodam następujące kolumny w tabeli wiadomości:

  • Is_reminder – Ta kolumna wskazuje, czy dla wiadomości wymagane jest przypomnienie.
  • Reminder_frequency_id – Ta kolumna oznacza częstotliwość przypominania. Czy powinno to odbywać się codziennie czy co tydzień?
  • Next_remind_date – W tej kolumnie znajduje się data, kiedy należy wysłać następne przypomnienie. Przypomnienie zostanie wysłane next_remind_date dla użytkowników, dla których flaga „is_read” wynosi jeszcze ZERO. Nowa wartość dla tej kolumny zostanie obliczona za każdym razem, gdy zostanie wysłane przypomnienie.
  • Expiry_date – Ta kolumna to data graniczna, kiedy przypomnienia nie będą już wysyłane do użytkowników.

Obliczanie next_remind_date wyglądałoby następująco – Załóżmy, że jedna wiadomość zostanie wysłana do użytkowników 14 września w poniedziałek z datą wygaśnięcia 10/5. Wiadomość jest wysyłana z tygodniową częstotliwością przypomnień. W takim przypadku przypomnienia zostaną wysłane do użytkowników 21 września i 28 września, aby odpowiedzieć na nie e-mailem, a ostatni raz 5 października, aby zachęcić ich do odpowiedzi w ciągu najbliższych 24 godzin.

Końcowy model danych



Wniosek

Jednym z najlepszych zastosowań tego systemu przesyłania wiadomości jest wysyłanie powiadomień do użytkowników, którzy byli nieaktywni w systemie przez długi czas. Powiadomienia te mogą być wysyłane z włączonym mechanizmem przypominania, a powiadomienia będą wysyłane do użytkowników, dopóki użytkownicy nie odpowiedzą na powiadomienie. Użytkownicy zostaną dezaktywowani w dniu i po dacie wygaśnięcia, jeśli nie otrzymają od nich odpowiedzi na powiadomienia.

Zamierzałem zbudować model danych dla w pełni funkcjonalnego systemu przesyłania wiadomości, który można dopasować do różnych systemów do wysyłania wiadomości/powiadomień. Zapraszam do dzielenia się swoimi poglądami/wkładami/komentarzami do artykułu.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Relacyjne vs nierelacyjne bazy danych – część 2

  2. Twój ostateczny przewodnik po SQL Join:INNER JOIN – część 1

  3. Zabawa z kompresją (kolumnową) na bardzo dużym stole – część 3

  4. Estymacja liczności dla wielu predykatów

  5. Dlaczego optymalizator nie wykorzystuje wiedzy o puli buforów