聊天表设计

具体表结构

CREATE TABLE `chat_user` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
 `username` varchar(64) DEFAULT NULL COMMENT '用户名',
 `password` varchar(64) DEFAULT NULL COMMENT '用户密码',
 `created_at` int(11) DEFAULT '0' COMMENT '创建时间',
 PRIMARY KEY (`id`),
 UNIQUE KEY `chat_user_username_IDX` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

CREATE TABLE `chat_user_friend` (
  `friend_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `user_id_a` int(11) NOT NULL DEFAULT '0' COMMENT '用户a的id',
  `user_id_b` int(11) NOT NULL DEFAULT '0' COMMENT '用户b的id',
  `status` tinyint(3) unsigned DEFAULT '0' COMMENT '关系状态 1:a主动删除b, 2:b主动删除a, 4:ab已相互删除, 8:a主动拉黑b, 16:a主动拉黑b, 32:ab已相互拉黑',
  `user_a_last_ack_seq` char(18) DEFAULT NULL COMMENT '用户a的客户端最后获得的消息id',
  `user_b_last_ack_seq` char(18) DEFAULT NULL COMMENT '用户b的客户端最后获得的消息id',
  PRIMARY KEY (`friend_id`),
  UNIQUE KEY `chat_user_friend_user_id_ab_IDX` (`user_id_a`,`user_id_b`) USING BTREE,
  KEY `chat_user_friend_user_id_b_IDX` (`user_id_b`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='好友关系表';

CREATE TABLE `chat_friend_record` (
 `record_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
 `friend_id` int(11) NOT NULL DEFAULT '0' COMMENT '好友关系表id',
 `sender` int(11) NOT NULL DEFAULT '0' COMMENT '发送方',
 `receiver` int(11) NOT NULL DEFAULT '0' COMMENT '接受方',
 `seq` char(18) DEFAULT NULL COMMENT '序列号',
 `content` text COMMENT '消息内容',
 `created_at` int(11) DEFAULT '0' COMMENT '创建时间',
 PRIMARY KEY (`record_id`),
 KEY `chat_friend_record_friend_id_IDX` (`friend_id`),
 UNIQUE KEY `chat_friend_record_seq_IDX` (`seq`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='好友单聊天记录表';

CREATE TABLE `chat_room` (
 `room_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
 `room_name` char(64) DEFAULT NULL COMMENT '群名字',
 `user_id` int(11) NOT NULL DEFAULT '0' COMMENT '群主id',
 `status` tinyint(3) DEFAULT '0' COMMENT '是否解散 0:正常 1:已解散',
 `created_at` int(11) DEFAULT '0' COMMENT '创建时间',
 PRIMARY KEY (`room_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='群表';

CREATE TABLE `chat_room_member` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
 `room_id` int(11) NOT NULL DEFAULT '0' COMMENT '群id',
 `user_id` int(11) NOT NULL DEFAULT '0' COMMENT '用户id',
 `status` tinyint(1) DEFAULT '0' COMMENT '在本群的状态 0:正常 1:已禁言 2:已踢出',
 `created_at` int(11) DEFAULT '0' COMMENT '创建时间',
 `last_ack_seq` char(18) DEFAULT NULL COMMENT '群成员的客户端最后获得的群消息id',
 PRIMARY KEY (`id`),
 UNIQUE KEY `chat_room_member_room_user_id_IDX` (`room_id`,`user_id`),
 KEY `chat_room_member_user_id_IDX` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='群成员表';

CREATE TABLE `chat_room_record` (
 `record_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
 `room_id` int(11) NOT NULL DEFAULT '0' COMMENT '群表id',
 `sender` int(11) NOT NULL DEFAULT '0' COMMENT '发送方',
 `seq` char(18) DEFAULT NULL COMMENT '序列号',
 `content` text COMMENT '消息内容',
 `created_at` int(11) DEFAULT '0' COMMENT '创建时间',
 PRIMARY KEY (`record_id`),
 UNIQUE KEY `chat_room_record_room_id_IDX` (`room_id`),
 UNIQUE KEY `chat_room_record_seq_IDX` (`seq`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='群聊天记录表';

拉取我没主动删除的好友的sql示例

(SELECT * from chat_user_friend force index(chat_user_friend_user_id_ab_IDX) where user_id_a = 1 and status & 4 != 4 and status & 1 = 0) UNION ALL (SELECT * from chat_user_friend force index(chat_user_friend_user_id_b_IDX) where user_id_b = 1 and status & 4 != 4 and status & 2 = 0)

收发消息流程

用户发消息流程:是否好友或群友,写入数据库,发送给在线人,客户端收到消息,发送ack消息给服务端,改写last_ack_seq字段
刚登录用户收取消息流程:根据last_ack_seq,去对应的群聊表、单聊查找大于last_ack_seq的数据返回给客户端,客户端收到消息,发送ack消息给服务端,改写last_ack_seq字段

参考文章

群聊比单聊,凭什么复杂这么多?

本作品采用《CC 协议》,转载必须注明作者和本文链接
梦想星辰大海
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!