前言:由于导师在我的毕设项目里加了消息系统(本来想水水就过的..),没办法...来稍微研究研究吧..简单简单...
需求分析
我的毕设是一个博客系统,类似于简书这样的,所以消息系统也类似,在用户的消息里包含了有:喜欢和赞、评论、关注、私信这样的一类东西,这样的一个系统应该包含以下的功能:我没有 关注了 你
三颗 喜欢了你的文章 《Java消息系统简单设计与实现》
心脏 评论了你的文章 《Java消息系统简单设计与实现》当用户评论/关注/点赞时能够通知到被评论/关注/点赞的用户,并生成像如下格式的提示信息(允许取消关注/点赞但不收到通知):
用户之间能够发送/接受私信,不需要像QQ那样建立长连接实现实时通信,但刷新列表能看到新消息,并且界面类似QQ聊天界面一左一右,允许删除私信;
管理员能发送通告,其实就像是用管理员的账号给每一个用户发送私信;
可以查看关注的用户最新发表的文章,得到类似推送的效果;
所有消息当然也要标注好消息已读or未读,登录就能得到消息提醒标识好有多少未读消息,像是QQ消息右上角的小红点那样类似;
OK,大致就是以上的功能,那么问题来了:这要怎么设计啊?
进一步分析
其实可以根据上面的需求分析,把上面的消息大致可以分为公告(Announcement)、提醒(Remind)、私信(Message)三类,我们可以大致抽象出一个 通知(Notify) 模型:发送者接受者信息类型动作类型通知内容是否已读消息创建时间粉丝1号我没有三颗心脏提醒关注粉丝1号 关注了 你是xx:xx:xx
粉丝1号我没有三颗心脏提醒喜欢和赞粉丝1号 喜欢了你的文章 《Java消息系统简单设计与实现》是xx:xx:xx
粉丝1号我没有三颗心脏提醒评论粉丝1号 评论了你的文章 《Java消息系统简单设计与实现》是xx:xx:xx
粉丝2号我没有三颗心脏私信无你收到了来自 粉丝2号 的 1 条私信是xx:xx:xx
上面加了一些数据以便理解,不过话说粉丝1号果然是真爱粉,又关注又喜欢又评论,嘻嘻嘻嘻...
emm.这样的模型能够胜任我们的工作吗?我也不知道..不过根据这个模型能够想出大概的这样的创建通知的逻辑:
似乎看上去也没有什么大问题..不过既然消息内容都可以根据动作类型自动生成的了,加上私信和公告的内容因为长度问题也肯定不保存在这张表里的好,所以我们在设计数据库时干脆把通知内容这条去掉不要,当信息类型是公告或者私信时可以根据这条通知的 id 在相应的表中找到相应的数据就可以了,emm..我觉得可以
顺下去想想其实脑中有了一个大概,这样的模型还容易设计和想到,其实主要的问题还是下面的那些
问题一:单表数据大了怎么办?
如果当用户量上去到一定量的时候,那么这张 通知表 势必会变得巨大,因为不管是我们的公告、提醒还是私信都会在这个通知表上创建一条数据,到时候就会面临查询慢的问题,问题的答案是:我也不知道..
所以我们的规定是:不考虑像简书这样超大用户量,能够应付毕设就好啦..简单设计,嘻嘻嘻..不过也不要太不相信MySQL的性能,还是有一定容纳能力的!
问题二:用户要怎样正确得到自己的未读消息呢?
暴力一点方法是,反正通知表里有用户所有的消息,直接读取完,然后通过是否已读字段就能够找到正确的所有未读消息了,这..这么简单吗?
其实有思考过使用时间或者另建一张保存有最新已读到哪条消息的表,但用户可以选择有一些读有一些不读,这两个似乎都很难达到目的...还是暴力吧
问题三:私信消息该怎么设计?发送者接受者内容发送时间粉丝1号我没有三颗心脏我是你的真爱粉啊!我要给你生猴子!2019年1月7日11:34:23
我没有三颗心脏粉丝1号已阅...下一个...2019年1月7日11:34:53
就像 QQ消息 一样嘛,包含一个内容、时间、发送者和接受者,然后前端直接根据时间或者 id 排序生成一左一右的消息对话框,不过比较特殊的一点就是私信是一个双向交流的过程,在一个对话框中我可能既是接受者也是发送者,这也无所谓嘛,稍微分析分析场景:读取私信列表时:按照接受者和发送者一起查询的原则,也就是查询接受者是自己和发送者是自己的数据,然后根据时间和已读未读来建立私信列表;
读取私信时:这时已经有了明确的接受者和发送者,那就查询所有 发送者是对方接受者是自己 Or 发送者是自己接受者是对方 的数据,然后在前端拼凑出一左一右的聊天框;
发送私信时:先查询之前是否有记录,然后同上建立聊天框,点击发送之后把发送方设为自己接收方设为私信对象,然后在通知表中新建一条未读数据通知私信对象有私信来了;
这完全能满足要求,只不过感觉查询多了些..
数据库设计
简单弄了弄弄..看着挺难受的,不过能简单实现功能,并且为了演示,这里是做了一张user_follow表,表示用户之间的关联关系,点赞和评论与这个类似,就不多弄了..下面给一下建表语句吧:
user表:CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `username` varchar(50) NOT NULL COMMENT '用户姓名',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
user_follow表:CREATE TABLE `user_follow` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `uid` bigint(20) NOT NULL COMMENT '用户ID', `follow_uid` bigint(20) NOT