老师分表方案的会话表 t_chat_relation_78 是user_id取余为78的 假设两个用户相互关注 a b,a往t_chat_relation_78 写了一条记录,b往t_chat_relation_88写了一条记录,一共在2张表上插入2条数据,看老师课程的意思是,两条记录 指向一个session_id。也就是t_chat_relation的字段为 id userid session_id, 其中session_id的字段值相同。对于私聊场景 a 发送给b, 会把发送人userid,接受人userid,session_id带上,这时候我能正常去对应的 t_chat_relation表中更新数据。那如果是群聊场景,怎么做呢?不可能在发送消息时把接受人的id带上的,因为有多个发送对象,也就是说我在真正去发送消息的时候,需要去查这个会话下的user_id,其实还是去查 t_chat_relation,因为这张表的路由片键是user_id,所以这时候只能全表去扫,压力会大。这块群聊,老师是又维护一张分表去做吗?一张 session_user的分表,记录session_id,user_id,这里的session_id指的是t_chat_relation的session_id字段,维护的是session和user的关系。只不过此时的维护的路由片键是session_id,这样就能避免查询所有的表。对于群聊私聊的表结构的关联关系,及路由片键有些难以抽象。我还是觉得,把私聊当成群聊去做好,用户会话关联表,会话表。会话下用户表。消息表。表结构一致,清晰。维护方便。
1. 整体表结构设计(私聊=群聊统一方案)
1)用户会话表:user_session
作用:查“我有哪些会话,以及当前已读数”
user_id bigint # bigint # 会话ID
read_num int 用户ID(分片键)
session_id
created_at datetime
updated_at datetime
- 分片键:user_id
2)会话基础表:session
作用:会话本身信息以及记录外层消息,消息总数(群名、公告、类型等)
session_id bigint # 会话ID(分片键)
type tinyint # 1=私聊 2=群聊
total_num bigint 会话消息总数
outer_text varchar 外层展示数据
owner_id bigint
created_at datetime
- 分片键:session_id
3)会话成员表:session_user
作用:这个会话里有哪些人
session_id bigint # 会话ID(分片键)
user_id bigint # 用户ID
join_time datetime
quit_time datetime
is_deleted tinyint
- 分片键:session_id
- 私聊:固定 2 条记录(A→session,B→session)
- 群聊:N 条记录
这张表就是发消息时,通过 sessionId 查所有接收人的来源。
4)消息表:message
作用:存具体消息
msg_id bigint
session_id bigint # 分片键
sender_id bigint
content text
type tinyint
send_time datetime
- 分片键:session_id
- 同一个会话的所有消息落在同一片。1. 前端发送
sender_id + session_id + content
2. 后端:- 根据 session_id 去 session_user 表查出所有在群成员 user_id 列表
- 排除自己,得到接收人列表
- 写入 message 表(按 session_id 分片)
- 更新 会话表的总条数
3. 接收方:- 打开 APP → 查自己 user_session 得到所有会话
- 点进某个会话 → 按 session_id 拉 message 表 整个聊天发消息过程,只写一张message 以及更新会话的消息总数。未读消息红点数量由后台计算拼接在消息里一起发送。用户从会话列表进入聊天页面或者离开,将用户会话表的已读数量设置为session的总条数。
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星