前语

最近在自己写一个IM即时通讯的一个体系,相似为一个社区的姿态,昨日进行了对数据库规划的的重构,在重构的过程中,遇到了未读音讯规划的这个问题,之前一点功课都没做的时分,作者的主意就十分的单纯,每次有一个音讯发过来就在缓存中添加未读数,当时没有想到一个用户有多个群聊,并且每个群聊还会出现重复记载的问题,所以就这次重构之前,作者是阅读过一些大佬的文章,还有几经问询之下有了这次的规划探究

声明:本篇文章是作者自己的构思历程,有好的主意欢迎提出,遇到过错也欢迎对作者提出斧正意见,最后转载请声明出处

第一次规划测验:为每个主频道添加一个用户的最后脱离时刻

  1. 体系主体规划 首要作者规划的这个体系是对相似于Discord这种交际应用的一种主意上的复现,主体是每个用户都能够参加和创建一个主频道,主频道下有只有一级是子频道,没有子子频道

  2. 初度测验 首要关于将未读音讯数计入缓存这个如果频道数多了之后就很不现实,所以采纳一种比较通用的办法便是,通过头和尾的时刻戳来锁定未读音讯的时刻戳

    作者初度是为主体频道添加了一个用户最后的脱离时刻,想的是每次用户登录进来这个频道后,用登录的时刻戳减去前次脱离的时刻戳,上了个厕所回来之后发现这种主意很不现实,仅仅对大频道进行一次脱离时刻戳记载,各个子频道,作者又怎么知道用户是什么时分进去,什么时分脱离,明显这个主意有点不太管用了

第2次规划测验:新建表记载子频道的最后脱离时刻

作者确实也百度了很多也问了AI,相较于上一次的异想天开,这次给出的办法正常许多,新树立一个表

IM系统中群聊未读消息的设计思路

如上图所示,不论是以用户为主体还是以频道为主体来记载这个最后的活跃时刻戳,数据量都是十分大的,就比如有十个用户和十个频道,当这十个用户悉数参加这十个频道后,就需要为这个表去添加 100 行数据来保护,可想而知这个增量还是挺大的,一个主频道或许不止区区十个子频道

到这儿,经过我的百度和各种思考,我发现单从数据库的层面想来让这个问题得到很好的处理的话有点不太现实,所以我发动了最后一个办法,去各个群里问询大佬们的主意

终究的规划:抛弃数据库的规划

当我抛出问题后有一个大佬很快给出一个思路为什么不能够记载在客户端呢,我登时茅塞顿开,相比于记载于服务端,数据库承受的压力是相当大的,简简单单的时刻戳如果去记载在客户端不仅对每个用户的压力很小,并且每个用户参加的频道数也或许不太多,大多数都在 50 个以下,这样不仅速度能够得到提高,并且还省去了服务端的业务压力,只用关怀对音讯的寄存就好

所以终究在前端对音讯未读业务规划为 json 存储于 localStorage 中进行持久化处理

IM系统中群聊未读消息的设计思路

总结

这次的规划思路的历程让人给我最大的感触便是,有一些关于用户个人的业务,不方便进行大规模的存储和核算的时分,是否能够将压力分摊到个人的身上,一起一起规划前后端的时分,多想想前端精干一些什么,压力不要悉数给到后端,前后端别离嘛,不仅仅是要做到高内聚低耦合,还要想着怎么高雅的去实践这一理论,那么今天的分析就到这,感谢您能看到这儿,下次我们再聊,Bye~