点到点的消息传送:数据库
点到面的消息传送网络
对于用户很是少的状况,没有必要深刻的考虑数据库的优化,采用简单的表设计:架构
如表message优化
列名 | 字段 |
---|---|
sendId | 发送者id |
recId | 接受者id |
message | 站内信内容 |
status | 查看 |
create_date | 发送日期 |
点对点的信息发送,只须要在表中插入一条数据,记录双方的ID以及信息便可。查看本身是否有信息也很简单:表中recId字段值等于本身的ID且status为0(未读)的信息就是本身须要查看的信息设计
店对面的操做和点对点的信息发送一致。索引
若是按照少许用户的设计思路来处理中量用户的状况,会出现什么问题?假设用户数量10000,管理员要向全部用户发送系统通知。那么,上述的表就须要一次操做插入10000条数据,这并没什么,但里面的message就必须重复10000次,这意味着,100个汉字的消息,一次消息发送,就会占用2M的空间,多发几回,这张表就冗余到不能接受了。table
那为何不用recId=0来表明向全部人发送,这样不就能够解决message重复10000次的问题了。固然能够这样作,但必须引入另外一张表,否则,就无法记录哪个用户读过系统消息,哪个用户没有读过。效率
所以,表设计以下:基础
表messagedate
列名 | 字段 |
---|---|
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
列名 | 字段 |
---|---|
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表中插入一条数据,代表本身已经阅读了。这样就即解决没发知道那个用户是否已经阅读的问题,也解决了须要在百万表中查找修改状态的问题。固然也会引入其余问题,好比说:
固然,还能够在其余当面对站内信作一些优化操做,好比说:
上述的站内信只是在单应用系统下的一个很初步的设计,能够这样说,哪怕是按照大量用户来设计单应用系统的站内信,也会出现这这那那的瓶颈,不只是数据库的,还有网络的,IO操做的等;所以,对于基础单应用系统的站内信设计,只推荐使用中量用户的设计,大量用户的设计是一个很是复杂的架构,并非再分一个表就能解决的。
总结一下