随便想到,群聊天的数据库简单设计

2020-03-20 13:35:55

参考地址 随便想到,群聊天的数据库简单设计


简单来讲,就是记录最后的阅读id,这样通过数据库查询。

顺便说一下,群记录可以这样。

个人都个人的,就是每次发送给对方信息,就往未读信息表里面插入一条数据,当然这个数据之插入messageid,每次客户端收到长连接请求,就去拉去这个表里面的所有未读记录。客户端根据内容进行读取。

通过查询,发现微信只保留未读信息为两天。这样的话,数据量不多的话,完全群聊信息,完全也可以这么做。

其次,我觉得我们如果用户量不大的话,完全可以保留更多的天数。

为了更加保障信息不丢失,我们可以添加历史信息的功能。

1,聊天消息设计


突然想了想,如果一个群聊天数据库到底应该咋设计。
从最简单的思路慢慢开始。简单到大家都能明白。

2,就一个表


最简单的方式,先完成功能。开发比较着急嘛,一个表数据存放方便。
数据库表结构如下。

 CREATE TABLE `msg` (  `id` bigint(20) NOT NULL AUTO_INCREMENT,  `gid` bigint(20) DEFAULT NULL,  `from_uid` bigint(20) DEFAULT NULL,  `to_uid` bigint(20) DEFAULT NULL,  `content` text DEFAULT NULL,  `is_read` tinyint(1) DEFAULT '0',  `create_time` datetime DEFAULT NULL,  `update_time` datetime DEFAULT NULL,  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

一个群的聊天记录,一个消息发给多个人,每个人都收到一个相同的消息。
一般是不会这样设计的吧。这个数据 比较冗余啊。而且一个群下面人越多。
消息的重复数量越多。m*n条数据冗余啊

3,简化下


拆分成消息内容和流水表。

 CREATE TABLE `msg` (  `id` bigint(20) NOT NULL AUTO_INCREMENT,  `content` text DEFAULT NULL,  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 CREATE TABLE `msg_log` (  `id` bigint(20) NOT NULL AUTO_INCREMENT,  `gid` bigint(20) DEFAULT NULL,  `msg_id` bigint(20) DEFAULT NULL,  `from_uid` bigint(20) DEFAULT NULL,  `to_uid` bigint(20) DEFAULT NULL,  `is_read` tinyint(1) DEFAULT '0',  `create_time` datetime DEFAULT NULL,  `update_time` datetime DEFAULT NULL,  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

这样会好一点,将消息内容存储成一个表,然后每个人都只有一个流水表。
但是这样也有一个问题,只是节省了内容字段。没有节省流水。
还是 m*n 条消息记录呢

4,增加配置表


拆分成两个表,一个是消息的流水表,一个是每个人的配置表。
记录每个群下面的这个用户的最后读取的消息last_msg_id,然后在计算消息未读数据。
这样优化之后数据将减少好多,数量是 m+n条数据。不在是成倍增长了。

 CREATE TABLE `msg` (  `id` bigint(20) NOT NULL AUTO_INCREMENT,  `gid` bigint(20) DEFAULT NULL,  `content` text DEFAULT NULL,  `create_time` datetime DEFAULT NULL,  `update_time` datetime DEFAULT NULL,  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 CREATE TABLE `msg_config` (  `id` bigint(20) NOT NULL AUTO_INCREMENT,  `gid` bigint(20) DEFAULT NULL,  `last_msg_id` bigint(20) DEFAULT NULL,  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

但是这个是个局限只限于群聊天,因为这个只是知道你这个群的未读消息数量。
所以直接进行connt查询就行。

4,总结


总结,一个群消息的数据设计简单的进行了几次演化。
最后的方案比较好,只有通过配置读取最新的msg_id,然后再计算出用户未读数量。
基本上一个消息都是顺序读取的,一个流水,可以认为用户也是顺着读的。
这样就可以把消息的未读数据用last_msg_id 进行计算。
感觉上qq上面的群消息应该也是这样设计的吧。这样设计才最节省资源。


  • 2019-01-24 16:11:39

    数据库去除重复记录

    如何删除数据库中重复的记录 一般情况下,数据库去重复有以下那么三种方法:

  • 2019-01-26 10:12:40

    一行代码让webview不加载图片

    最近项目中需要控制列表页和详情页图片资源的显示,列表页比较好做,详情页是用WebView来展示的,不太好控制图片资源的加载。在Google上找到了两个解决办法,跟大家分享一下!

  • 2019-01-29 14:33:07

    child_process中spawn和exec方法的使用

    child_process是nw.exe的一个内置模块,通过它可以实现创建多线程,并可实现主线程和子线程之间的通信。child_process模块中主要使用有两个方法spawn和exec,这两个方法都可以用来创建子线程。除了spawn和exec外,child_process模块还有execFile,fork,spawnSync,execFileSync,execSync,它们都是基于spawn的不同封装。 --------------------- 作者:黄泽平 来源:CSDN 原文:https://blog.csdn.net/zeping891103/article/details/52230175 版权声明:本文为博主原创文章,转载请附上博文链接!

  • 2019-01-29 14:50:51

    Node.js 编写跨平台 spawn 语句

    Node.js 是跨平台的,也就是说它能运行在 Windows、OSX 和 Linux 平台上。很多 Node.js 开发者都是在 OSX 上做开发的,然后再将代码部署到 Linux 服务器上。由于 OSX 和 Linux 都是基于 Unix 的,因此两者共性很多。Windows 也是 Node.js 官方支持的平台,只要你通过正确的方式写代码,就能在各个平台上毫无压力的跑起来。