数据库表创建-会话
版本归属
用于 v2 会话基础版。
表清单
conversationsconversation_members
conversations
会话表。单聊和群聊都存在这里,消息能力落地前也先由这张表承载会话基础信息。
conversations 执行 SQL
sql
CREATE TABLE IF NOT EXISTS conversations (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
type ENUM('direct', 'group') NOT NULL,
direct_key VARCHAR(64) NULL,
title VARCHAR(128) NULL,
avatar_url VARCHAR(255) NULL,
owner_id BIGINT NULL,
last_message_id BIGINT NULL,
last_message_at DATETIME NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_conversations_direct_key (direct_key),
KEY idx_conversations_last_message_at (last_message_at),
KEY idx_conversations_owner_id (owner_id)
);字段说明:
id:会话内部 IDtype:会话类型,direct表示单聊,group表示群聊direct_key:单聊唯一键,格式为min_user_id:max_user_id;群聊为空title:群聊名称;单聊可为空,由客户端根据对方用户展示avatar_url:群聊头像;单聊可为空owner_id:群主用户 ID;单聊可为空last_message_id:最后一条消息 ID,v3 消息版本开始维护last_message_at:最后一条消息发送时间,v3 消息版本开始维护created_at:创建时间updated_at:更新时间
索引说明:
uk_conversations_direct_key:保证同一对用户只能有一个单聊会话idx_conversations_last_message_at:用于会话列表按最后消息时间排序idx_conversations_owner_id:用于查询某个用户创建的群聊
业务约束:
- 创建单聊前必须先对两个用户 ID 排序,再生成
direct_key - 创建单聊时如果
direct_key已存在,直接返回已有会话 - 群聊不写
direct_key - v2 阶段
last_message_id和last_message_at可以为空
conversation_members
会话成员表。负责单聊成员、群成员、角色、已读游标和成员状态。
conversation_members 执行 SQL
sql
CREATE TABLE IF NOT EXISTS conversation_members (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
conversation_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
role ENUM('owner', 'admin', 'member') NOT NULL DEFAULT 'member',
joined_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
muted_until DATETIME NULL,
last_read_message_id BIGINT NULL,
last_read_at DATETIME NULL,
status ENUM('active', 'left', 'removed') NOT NULL DEFAULT 'active',
UNIQUE KEY uk_conversation_members_conversation_user (conversation_id, user_id),
KEY idx_conversation_members_user_status (user_id, status),
KEY idx_conversation_members_conversation_status (conversation_id, status)
);字段说明:
id:成员记录 IDconversation_id:会话 IDuser_id:成员用户 IDrole:成员角色,owner群主,admin管理员,member普通成员joined_at:加入时间muted_until:免打扰或禁言截止时间,当前可为空last_read_message_id:会话级已读游标,v3 消息版本开始使用last_read_at:最后已读时间,v3 消息版本开始使用status:成员状态,active正常,left主动退出,removed被移除
索引说明:
uk_conversation_members_conversation_user:保证同一用户在同一会话中只有一条成员记录idx_conversation_members_user_status:用于查询当前用户的有效会话idx_conversation_members_conversation_status:用于查询会话内有效成员
业务约束:
- 单聊固定两个成员,角色统一使用
member - 群聊创建人写入
owner - 会话列表只返回当前用户
status = active的会话 - v2 阶段
last_read_message_id和last_read_at可以为空
建表后检查
sql
DESC conversations;
DESC conversation_members;
SHOW INDEX FROM conversations;
SHOW INDEX FROM conversation_members;最小验证
以下 SQL 假设 users 表中已经存在 id = 1 和 id = 2 的用户。
创建单聊:
sql
INSERT INTO conversations (type, direct_key)
VALUES ('direct', '1:2');
SET @conversation_id = LAST_INSERT_ID();
INSERT INTO conversation_members (conversation_id, user_id, role, status)
VALUES
(@conversation_id, 1, 'member', 'active'),
(@conversation_id, 2, 'member', 'active');查询用户 1 的会话:
sql
SELECT c.id, c.type, c.direct_key, cm.role, cm.status
FROM conversation_members cm
JOIN conversations c ON c.id = cm.conversation_id
WHERE cm.user_id = 1 AND cm.status = 'active';验证单聊唯一:
sql
INSERT INTO conversations (type, direct_key)
VALUES ('direct', '1:2');预期结果:失败,命中 uk_conversations_direct_key。
代码落地点
models/conversation_model.go定义Conversation和ConversationMember- 创建单聊时必须先生成稳定
direct_key - 创建单聊和群聊时必须使用数据库事务
conversation_members.status是会话列表、发消息、读消息的权限基础