站内信在非企业站的网站基本都有,因为网站本身就有建议和投诉等设计,那么就需要站内信设计

简介

根据网络上的文章做参考、区分一下特点:

  1. 点到点:一对一发送的站内信,比如用户A发给用户B的消息,或者系统发给用户A的通知。type=private
  2. 点到多:一对多发送的站内信,接收对象较少,而且接收对象无特殊共性。可以当做私信。type=private
  3. 点到面:一对多发送的站内信,接收对象较多,而且接收对象同属于某用户组之类的共同属性。type=group
  4. 点到全部:一对多发送的站内信,接收对象为全部用户。通常为系统通知。type=global

数据表设计

如果用户量小的情况设计可以随意

idsender_idreceiver_idtypesend_timecontentstatus
消息id发送者接收者消息类型发送时间消息正文消息状态(未读/已读/删除)


不管一对一的私信还是一堆多的群发,没给一个用户发消息就插入一条数据简单粗暴(可以作为一对一比较合适)。
但是如果考虑到一对多的消息比较多的时候,消息的content字段其实是冗余的,可以将这张表拆成两份

数据表拆分设计

message

content_idreceiver_idstatus
关联内容接收者消息状态(未读/已读/删除)

message_content

idsender_idtypesend_timecontenttitle
消息id发送者消息类型发送时间消息内容消息标题

这样拆分后,对于一对一的私信,需要在message表与message_content表各插入一条数据。

对于一对多的消息,在message_content表只需要插入一条数据,大大节省了消息数据的存储空间,不过仍需对对应的用户在mssage表插入一条数据。

对于全部用户,那么可以换个思路,message_content中只需要插入一条数据(type=global, sender_id=0),但message表中进行不插入(及读取后插入数据,未有的数据为未读)这种形式来减轻message插入量。前端页面可以分业务逻辑一个是私信通知和全局通知,区分页面查询。

如果是百万或者十万级用户这种其实都难以忍受

要查询用户id为1的未读广播消息:

select id from message_content where type='global' and id not in
(select content_id from message where receiver_id=1);

全局通知的站内信查询出用户id为1已读或者未读的信息

select * from message_content c left join message m on
c.id=m.content_id and receiver_id=1 where type='global';

用户量大的全局通知设计

如果用户量大,那么阅读多的用户记录在插入数据其实也不那么好!

  1. 全局和私信可以分为两个通知,平台、私信
  2. 全局通知可以用,redis的setBit位处理,用户的id做位序列
Last modification:December 3, 2022
如果觉得我的文章对你有用,请随意赞赏