Mọi người thích giao tiếp. Chúng tôi thường nói đùa rằng bất kỳ hệ thống phần mềm nào cũng luôn phát triển thành hệ thống nhắn tin. Bài viết này sẽ giải thích các yêu cầu hệ thống và cách tiếp cận từng bước để thiết kế mô hình dữ liệu cho hệ thống nhắn tin.
Yêu cầu trong Nutshell
Chức năng cốt lõi của hệ thống nhắn tin trong ứng dụng là gửi thông báo / tin nhắn cho một người dùng hoặc một nhóm người dùng. Hệ thống của chúng tôi cũng cho phép một người gửi tin nhắn đến một nhóm người dùng. Nhóm người dùng rõ ràng có thể được hình thành dựa trên một số thông số như đặc quyền truy cập, vị trí địa lý của người dùng, v.v.
Hệ thống này cho phép người nhận phản hồi cho các tin nhắn. Nó cũng theo dõi ai đã đọc tin nhắn và ai chưa đọc.
Ngoài ra, hệ thống có lời nhắc được tích hợp sẵn cơ chế cho phép người gửi tạo lời nhắc, sau đó gửi lời nhắc tới tất cả người nhận.
Thực thể và Mối quan hệ
Trong mô hình dữ liệu này, user
và message
là các thực thể chính để lưu trữ thông tin chi tiết của người dùng và tin nhắn.
Các cột trong user
bảng sẽ là các thuộc tính liên quan đến người dùng như first_name
, last_name
, v.v.
Một số cột tự giải thích trong message
bảng sẽ là subject
, message_body
, create_date
và expiry_date
. Tôi cũng thêm một cột khóa ngoại có tên là creator_id
trong bảng này đề cập đến id
cột user
bàn. Như tên gọi của nó, nó biểu thị id của người tạo ra một tin nhắn. Vì sẽ luôn có một người tạo cho một tin nhắn, tôi chỉ giữ cột này trong bảng tin nhắn. Bạn có thể thắc mắc tại sao lại có expiry_date
cột trong bảng. Tôi đã thêm cột này để quản lý lời nhắc trên một tin nhắn. Tôi sẽ giải thích thêm về cột này ở phần sau của bài viết này.
Bảng quan trọng nhất trong mô hình dữ liệu này là message_recipient
. Tôi có thể nói rằng toàn bộ mô hình dữ liệu chỉ xoay quanh bảng này. Một trong những mục tiêu chính đằng sau việc tạo bảng này là giữ ánh xạ giữa các tin nhắn và người nhận của chúng. Do đó, recipient_id
trong bảng này biểu thị id của người nhận và cột này đề cập đến cột id của user
bảng.
Khi một tin nhắn được gửi đến một người nhận, một bản ghi sẽ được chèn vào bảng này với id của người nhận trong recipient_id
cột.
Bây giờ bạn có thể tự hỏi recipient_group_id
là gì cột biểu thị trong bảng này. Ở đây, trước tiên tôi nên giải thích cách mô hình này có thể được mở rộng cho yêu cầu gửi tin nhắn đến nhiều người nhận cùng một lúc.
Gửi tin nhắn cho một nhóm
Tôi cần một bảng khác, đó là group
, để nắm thông tin chi tiết về nhóm. Vì có mối quan hệ nhiều-nhiều giữa user
và group
bảng, tức là người dùng có thể là một phần của nhiều nhóm, tôi sẽ tạo một bảng khác có tên user_group
.
Ví dụ:nếu một nhóm được thành lập với 25 người dùng, sẽ có 25 bản ghi, mỗi bản ghi cho mỗi người dùng, trong user_group
bảng.
Hãy quay lại message_recipient
bàn. Tôi thêm một tham chiếu đến khóa chính của user_group
vào message_recipient
bàn. Tôi đặt tên nó là recipient_group_id
. Cột này sẽ chứa giá trị của nhóm người dùng mà tin nhắn được gửi.
Giờ đây, bất cứ khi nào một tin nhắn được gửi đến một nhóm, nhiều bản ghi sẽ được chèn vào message_recipient
bảng dựa trên số lượng người dùng trong nhóm và recipient_group_id
sẽ được ghi lại tương ứng với tất cả các bản ghi đó.
Hãy để tôi minh họa nó thêm bằng một ví dụ. Giả sử một tin nhắn được gửi đến một nhóm 10 người. Trong trường hợp này, có tổng cộng 10 bản ghi, một bản ghi cho mỗi recipient_group_id
của nhóm, sẽ được chèn vào message_recipient
bảng.
Xin lưu ý rằng nếu tin nhắn được gửi đến người dùng, không phải một nhóm, thì recipient_group_id
cột vẫn trống. Trong trường hợp này, user_id
trực tiếp sẽ được ghi lại dưới recipient_id
cột.
Tôi sẽ thêm một cột nữa có tên là is_read
vào bảng để giữ một lá cờ chống lại người dùng tin nhắn cho biết liệu người dùng có đọc tin nhắn hay không.
Khóa duy nhất trong message_recipient
bảng - Phải có một khóa duy nhất tổng hợp trên các cột message_id
, recipient_id
và recipient_group_id
, để đảm bảo rằng chỉ có một bản ghi tồn tại cho sự kết hợp duy nhất của các cột này.
Tôi giữ is_active
trong tất cả các bảng, ngoại trừ bảng message và message_recipient, để cho phép 'xóa mềm' các bản ghi. Vì tôi đã thêm expiry_date
trong bảng thông báo, một is_active
cột không cần thiết. Hơn nữa, cột này không cần thiết trong message_recipient
bảng bởi vì một tin nhắn không thể được hoàn nguyên trực tiếp sau khi nó được gửi đi. Tuy nhiên, người ta có thể làm cho nó không hoạt động bằng cách cập nhật expiry_date
cho tin nhắn cho một ngày trong quá khứ.
Trả lời tin nhắn
Bây giờ, giả sử hệ thống cho phép người dùng trả lời các tin nhắn đã nhận. Tôi mở rộng cùng một bảng message
để đáp ứng yêu cầu này thay vì tạo một bảng mới cho các câu trả lời. Tôi sẽ thêm một cột có tên là parent_message_id
để thiết lập mối quan hệ thứ bậc giữa các thông điệp. Tôi sẽ chèn một bản ghi mới cho tin nhắn trả lời và cập nhật parent_message_id
cột cho tin nhắn trả lời. Mô hình này hỗ trợ cấp n của mối quan hệ phân cấp, tức là trả lời trên tin nhắn trả lời cũng có thể được theo dõi thông qua mô hình này.
Trang tổng quan để xem 'Đã đọc%' của mỗi tin nhắn
is_read
cờ được ghi vào mỗi bản ghi người dùng tin nhắn. Giá trị của cờ này vẫn là KHÔNG cho đến khi người dùng đọc được thông báo. Nó sẽ được cập nhật lên ONE ngay sau khi người dùng đọc được tin nhắn. Dựa trên giá trị cột, người ta có thể xác định "read%" cho một thư được gửi đến một nhóm.
Hãy để tôi viết một SQL mẫu để tìm nạp một báo cáo như vậy:
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);
Chủ đề | Đã gửi tới | Đã gửi | Đọc% |
---|---|---|---|
Thời hạn giao dự án vào Thứ Ba | Nhóm phân phối dự án | 13/09/2015 08:15 | 42% |
Gặp tôi vào Thứ Hai | John D | 10/09/2015 13:30 | 100% |
Đồng bộ hóa môi trường nhà phát triển với sản xuất | Nhóm DBA | 9/9/2015 09:11 | 80% |
Kết thúc NCR của cuộc kiểm toán | NSS-nhóm | 9/9/2015 17:50 | 45% |
Cơ chế nhắc nhở
Để có chức năng nhắc nhở, tôi sẽ thêm các cột sau vào bảng thông báo:
-
Is_reminder
- Cột này gắn cờ cho biết tin nhắn có cần lời nhắc hay không. -
Reminder_frequency_id
- Cột này biểu thị tần suất của lời nhắc. Nó nên được thực hiện hàng ngày hay hàng tuần? -
Next_remind_date
- Cột này chứa ngày cần gửi lời nhắc tiếp theo. Lời nhắc sẽ được gửi vàonext_remind_date
cho những người dùng mà cờ 'is_read' vẫn là KHÔNG. Giá trị mới cho cột này sẽ được tính mỗi khi có lời nhắc. -
Expiry_date
- Cột này là ngày giới hạn khi lời nhắc sẽ không còn được gửi đến người dùng nữa.
Tính toán của next_remind_date
sẽ như sau - Giả sử một tin nhắn được gửi đến người dùng vào ngày 14/9, thứ Hai, ngày 10/5 là ngày hết hạn của tin nhắn đó. Tin nhắn được gửi với tần suất nhắc nhở hàng tuần. Trong trường hợp này, người dùng sẽ gửi lời nhắc vào ngày 21/9 và 28/9 để trả lời họ qua email và lần cuối cùng vào ngày 10/5 để thúc giục họ trả lời trong 24 giờ tới.
Mô hình dữ liệu cuối cùng
Kết luận
Một trong những cách sử dụng tốt nhất của hệ thống nhắn tin này là gửi thông báo đến những người dùng đã không hoạt động trong hệ thống trong một thời gian dài. Những thông báo này có thể được gửi khi đã bật cơ chế nhắc nhở và thông báo sẽ được gửi đến người dùng cho đến khi người dùng phản hồi lại thông báo. Người dùng sẽ bị hủy kích hoạt vào và sau ngày hết hạn nếu không nhận được phản hồi về thông báo từ họ.
Tôi dự định xây dựng một mô hình dữ liệu cho một hệ thống nhắn tin đầy đủ chức năng, có thể phù hợp với nhiều hệ thống khác nhau để gửi tin nhắn / thông báo. Vui lòng chia sẻ quan điểm / đầu vào / nhận xét của bạn về bài viết.