基本功能
- 点到点的消息传送:
- 用户给用户
- 管理员给用户
- 点到面的消息传送
- 管理员给用户群
少量用户(10-999)
对于用户非常少的情况,没有必要深入的考虑数据库的优化,采用简单的表设计:
如表message
列名 | 字段 |
sendId | 发送者id |
recId | 接受者id |
message | 站内信内容 |
status | 查看 |
create_date | 发送日期 |
点对点的信息发送,只需要在表中插入一条数据,记录双方的ID以及信息即可。查看自己是否有信息也很简单:表中recId字段值等于自己的ID且status为0(未读)的信息就是自己需要查看的信息
店对面的操作和点对点的信息发送一致。
中量用户(1000-99999)
如果按照少量用户的设计思路来处理中量用户的情况,会出现什么问题?假设用户数量10000,管理员要向所有用户发送系统通知。那么,上述的表就需要一次操作插入10000条数据,这并没什么,但里面的message就必须重复10000次,这意味着,100个汉字的消息,一次消息发送,就会占用2M的空间,多发几次,这张表就冗余到不能接受了。
那为什么不用recId=0来代表向所有人发送,这样不就可以解决message重复10000次的问题了。当然可以这样做,但必须引入另一张表,不然,就没法记录哪一个用户读过系统消息,哪一个用户没有读过。
因此,表设计如下:
表message
列名 | 字段 |
sendId | 发送者id |
recId | 接受者id |
messageId | 站内信内容id |
status | 查看 |
create_date | 发送日期 |
表message_text
列名 | 字段 |
messageId | 编号 |
message_content | 内容 |
create_date | 发送日期 |
点对点的信息发送,首先在message_text表中插入一条记录,得到对应的ID,然后在message表中插入一条记录,记录相关发送人,接收人以及信息的ID
点对面的操作和点对点类似,一一对记录好即可
这样设计,每一次的信息发送操作,都只会记录一条信息数据而不会重复。这样能有效解决信息重复记录导致占用大量空间的问题。当然也会这样也不是完美的
大量用户(几十万到上百万)
同样,如果在百万级的情况下,使用中量用户的方案会出现什么问题?
从功能出发,管理员要向所有用户发送站内信,那么,message表中一下子就得涌入百万条数据,这个数据量对于数据库来说,简直可怕!而且,着还意味着,这张表有着百万次潜在的是否已读的修改请求。并且是每个用户在百万条数据中寻找自己的那一条数据进行修改。这个效率是完全不能接受的。
因此,我们可以设计一条规则来优化这个问题:
群发的消息,接收人的ID为0。这样虽然可以避免巨量操作,但是会引入另一个问题:我怎么知道那个用户读了?那个用户没读?
那么,咱们就要将整体结构拆分为三张表:
- message:收发关系表
- message_text:发送消息表
- message_customer:用户消息关系表,加索引
表设计如下:
表message
列名 | 字段 |
sendId | 发送者id |
recId | 接受者id |
messageId | 站内信内容id |
create_date | 发送日期 |
表message_text
列名 | 字段 |
messageId | 编号 |
message_content | 内容 |
create_date | 发送日期 |
表message_customer
列名 | 字段 |
customerId | 用户id |
messageId | 信息id |
status | 阅读状态 |
这样每次点对面的消息发送,首先在message_text表中插入一条数据,得到ID,然后在message记录相应的数据。用户在阅读后,会在message_customer表中插入一条数据,表明自己已经阅读了。这样就即解决没发知道那个用户是否已经阅读的问题,也解决了需要在百万表中查找修改状态的问题。当然也会引入其他问题,比如说:
- 增加了message_customer表的插入操作
- 如果用户想将已读的信息改为未读,怎么办
当然,还可以在其他当面对站内信做一些优化操作,比如说:
- 数百万的用户,肯定有僵尸用户,那么对于那些僵尸用户,咱们就不用发系统消息。
- 分时段的群发,对于实效性不是那么强的信息,可以分时段的向部分用户发送,直至发送完全。也可以在凌晨系统不是那么繁忙的时候操作。
总结
上述的站内信只是在单应用系统下的一个很初步的设计,可以这样说,哪怕是按照大量用户来设计单应用系统的站内信,也会出现这这那那的瓶颈,不仅是数据库的,还有网络的,IO操作的等;因此,对于基础单应用系统的站内信设计,只推荐使用中量用户的设计,大量用户的设计是一个非常复杂的架构,并不是再分一个表就能解决的。
总结一下
- 少量用户:设计简单,但浪费空间,冗余高
- 中量用户:设计较简单,对表的操作压力大
- 大量用户:这不是增加几个表能解决的问题