Skip to content

数据库表创建-会话 ​

版本归属 ​

用于 v2 会话基础版。

表清单 ​

  • conversations
  • conversation_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:会话内部 ID
  • type:会话类型,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:成员记录 ID
  • conversation_id:会话 ID
  • user_id:成员用户 ID
  • role:成员角色,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 是会话列表、发消息、读消息的权限基础

基于 MIT 许可发布