站内信在非企业站的网站基本都有,因为网站本身就有建议和投诉等设计,那么就需要站内信设计
简介
根据网络上的文章做参考、区分一下特点:
- 点到点:一对一发送的站内信,比如用户
A
发给用户B
的消息,或者系统发给用户A的通知。type=private
- 点到多:一对多发送的站内信,接收对象较少,而且接收对象无特殊共性。可以当做私信。
type=private
- 点到面:一对多发送的站内信,接收对象较多,而且接收对象同属于某用户组之类的共同属性。
type=group
- 点到全部:一对多发送的站内信,接收对象为全部用户。通常为系统通知。
type=global
数据表设计
如果用户量小的情况设计可以随意
id | sender_id | receiver_id | type | send_time | content | status |
---|---|---|---|---|---|---|
消息id | 发送者 | 接收者 | 消息类型 | 发送时间 | 消息正文 | 消息状态(未读/已读/删除) |
不管一对一的私信还是一堆多的群发,没给一个用户发消息就插入一条数据简单粗暴(可以作为一对一比较合适)。
但是如果考虑到一对多的消息比较多的时候,消息的content字段其实是冗余的,可以将这张表拆成两份
数据表拆分设计
message
表
content_id | receiver_id | status |
---|---|---|
关联内容 | 接收者 | 消息状态(未读/已读/删除) |
message_content
表
id | sender_id | type | send_time | content | title |
---|---|---|---|---|---|
消息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';
用户量大的全局通知设计
如果用户量大,那么阅读多的用户记录在插入数据其实也不那么好!
- 全局和私信可以分为两个通知,平台、私信
- 全局通知可以用,redis的setBit位处理,用户的id做位序列