26 KiB
26 KiB
数据库设计文档
版本: v1.0
创建日期: 2025-10-10
数据库: PostgreSQL 15+
ORM: Prisma
📋 目录
数据库概述
设计原则
- ✅ 遵循第三范式(3NF)
- ✅ 使用UUID作为主键
- ✅ 所有表包含created_at和updated_at时间戳
- ✅ 使用软删除(保留deleted_at字段,重要表)
- ✅ 外键约束使用CASCADE删除
- ✅ 敏感字段加密存储(密码使用bcrypt)
命名规范
- 表名:复数形式,下划线分隔(如:
users、knowledge_bases) - 字段名:下划线分隔(如:
created_at、user_id) - 索引名:
idx_表名_字段名(如:idx_users_email) - 外键名:
fk_表名_关联表名(如:fk_projects_users)
ER图
┌─────────────┐
│ Users │
└──────┬──────┘
│
│ 1:N
├──────────────────────┐
│ │
├──────────────────┐ │
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌──────────────┐ ┌──────────────────────┐
│ Projects │ │ Knowledge │ │ General │
│ │ │ Bases │ │ Conversations ⭐ │
└──────┬──────┘ └──────┬───────┘ └──────┬───────────────┘
│ │ │
│ 1:N │ 1:N │ 1:N
▼ ▼ ▼
┌─────────────┐ ┌──────────────┐ ┌──────────────────────┐
│Conversations│ │ Documents │ │ General Messages ⭐ │
│ Projects │ │KnowledgeBases│
└──────┬──────┘ └──────┬───────┘
│ │
│ 1:N │ 1:N
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│Conversations │ │ Documents │
└──────┬───────┘ └──────────────┘
│
│ 1:N
│
▼
┌──────────────┐
│ Messages │
└──────────────┘
表结构设计
1. users - 用户表
用途: 存储用户基本信息和认证信息
CREATE TABLE users (
id VARCHAR(50) PRIMARY KEY DEFAULT gen_random_uuid()::VARCHAR,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL, -- bcrypt加密
name VARCHAR(100),
avatar_url TEXT,
-- 角色和状态
role VARCHAR(20) NOT NULL DEFAULT 'user', -- user, admin
status VARCHAR(20) NOT NULL DEFAULT 'active', -- active, inactive, suspended
-- 配额(知识库限制)
kb_quota INTEGER DEFAULT 3,
kb_used INTEGER DEFAULT 0,
-- 试用信息
trial_ends_at TIMESTAMP,
is_trial BOOLEAN DEFAULT true,
-- 时间戳
last_login_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
-- 索引
CONSTRAINT check_email_format CHECK (email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}$'),
CONSTRAINT check_kb_quota CHECK (kb_used <= kb_quota)
);
-- 索引
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_status ON users(status);
CREATE INDEX idx_users_created_at ON users(created_at);
-- 注释
COMMENT ON TABLE users IS '用户表';
COMMENT ON COLUMN users.role IS '用户角色:user-普通用户, admin-管理员';
COMMENT ON COLUMN users.status IS '账户状态:active-激活, inactive-未激活, suspended-暂停';
字段说明:
| 字段 | 类型 | 说明 | 必填 | 默认值 |
|---|---|---|---|---|
| id | VARCHAR(50) | 用户ID(UUID) | ✅ | 自动生成 |
| VARCHAR(255) | 邮箱(登录名) | ✅ | - | |
| password | VARCHAR(255) | 密码(bcrypt) | ✅ | - |
| name | VARCHAR(100) | 用户姓名 | ❌ | NULL |
| role | VARCHAR(20) | 角色 | ✅ | 'user' |
| status | VARCHAR(20) | 状态 | ✅ | 'active' |
| kb_quota | INTEGER | 知识库配额 | ✅ | 3 |
| kb_used | INTEGER | 已使用知识库数 | ✅ | 0 |
2. projects - 项目/课题表
用途: 存储用户创建的研究项目/课题
CREATE TABLE projects (
id VARCHAR(50) PRIMARY KEY DEFAULT gen_random_uuid()::VARCHAR,
user_id VARCHAR(50) NOT NULL,
-- 项目信息
name VARCHAR(200) NOT NULL,
description TEXT NOT NULL, -- 项目背景信息(重要!用于上下文注入)
-- 统计信息
conversation_count INTEGER DEFAULT 0,
-- 时间戳
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
-- 外键
CONSTRAINT fk_projects_users FOREIGN KEY (user_id)
REFERENCES users(id) ON DELETE CASCADE
);
-- 索引
CREATE INDEX idx_projects_user_id ON projects(user_id);
CREATE INDEX idx_projects_created_at ON projects(created_at);
-- 注释
COMMENT ON TABLE projects IS '项目/课题表';
COMMENT ON COLUMN projects.description IS '项目背景信息,会自动注入到对话上下文中';
3. conversations - 对话表
用途: 存储用户与智能体的对话会话
CREATE TABLE conversations (
id VARCHAR(50) PRIMARY KEY DEFAULT gen_random_uuid()::VARCHAR,
user_id VARCHAR(50) NOT NULL,
project_id VARCHAR(50), -- 可选,全局快速问答时为NULL
agent_id VARCHAR(50) NOT NULL, -- 智能体ID(对应config/agents.yaml)
-- 对话信息
title VARCHAR(200) NOT NULL,
model_name VARCHAR(50) DEFAULT 'deepseek-v3',
-- 统计信息
message_count INTEGER DEFAULT 0,
total_tokens INTEGER DEFAULT 0,
-- 时间戳
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
-- 外键
CONSTRAINT fk_conversations_users FOREIGN KEY (user_id)
REFERENCES users(id) ON DELETE CASCADE,
CONSTRAINT fk_conversations_projects FOREIGN KEY (project_id)
REFERENCES projects(id) ON DELETE CASCADE
);
-- 索引
CREATE INDEX idx_conversations_user_id ON conversations(user_id);
CREATE INDEX idx_conversations_project_id ON conversations(project_id);
CREATE INDEX idx_conversations_agent_id ON conversations(agent_id);
CREATE INDEX idx_conversations_created_at ON conversations(created_at);
-- 注释
COMMENT ON TABLE conversations IS '对话会话表';
COMMENT ON COLUMN conversations.project_id IS '项目ID,全局快速问答时为NULL';
COMMENT ON COLUMN conversations.agent_id IS '智能体ID,对应配置文件中的智能体';
4. messages - 消息表
用途: 存储对话中的每条消息
CREATE TABLE messages (
id VARCHAR(50) PRIMARY KEY DEFAULT gen_random_uuid()::VARCHAR,
conversation_id VARCHAR(50) NOT NULL,
-- 消息内容
role VARCHAR(20) NOT NULL, -- user, assistant
content TEXT NOT NULL,
-- 元数据(可选)
metadata JSONB, -- 存储额外信息,如引用的知识库、模型参数等
-- 统计信息
tokens INTEGER,
-- 是否固定到项目背景
is_pinned BOOLEAN DEFAULT false,
-- 时间戳
created_at TIMESTAMP DEFAULT NOW(),
-- 外键
CONSTRAINT fk_messages_conversations FOREIGN KEY (conversation_id)
REFERENCES conversations(id) ON DELETE CASCADE,
-- 约束
CONSTRAINT check_role CHECK (role IN ('user', 'assistant'))
);
-- 索引
CREATE INDEX idx_messages_conversation_id ON messages(conversation_id);
CREATE INDEX idx_messages_created_at ON messages(created_at);
CREATE INDEX idx_messages_is_pinned ON messages(is_pinned);
-- 注释
COMMENT ON TABLE messages IS '对话消息表';
COMMENT ON COLUMN messages.is_pinned IS '是否固定到项目背景,用于动态更新项目描述';
COMMENT ON COLUMN messages.metadata IS 'JSON格式,存储引用的知识库、使用的模型等';
5. knowledge_bases - 知识库表
用途: 存储用户创建的个人知识库
CREATE TABLE knowledge_bases (
id VARCHAR(50) PRIMARY KEY DEFAULT gen_random_uuid()::VARCHAR,
user_id VARCHAR(50) NOT NULL,
-- 知识库信息
name VARCHAR(100) NOT NULL,
description TEXT,
-- Dify集成
dify_dataset_id VARCHAR(100) NOT NULL, -- Dify中的知识库ID
-- 统计信息
file_count INTEGER DEFAULT 0,
total_size_bytes BIGINT DEFAULT 0,
-- 时间戳
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
-- 外键
CONSTRAINT fk_kb_users FOREIGN KEY (user_id)
REFERENCES users(id) ON DELETE CASCADE,
-- 约束:每个用户最多3个知识库
CONSTRAINT check_kb_limit CHECK (
(SELECT COUNT(*) FROM knowledge_bases WHERE user_id = knowledge_bases.user_id) <= 3
)
);
-- 索引
CREATE INDEX idx_kb_user_id ON knowledge_bases(user_id);
CREATE INDEX idx_kb_dify_dataset_id ON knowledge_bases(dify_dataset_id);
-- 注释
COMMENT ON TABLE knowledge_bases IS '知识库表,每个用户最多3个';
COMMENT ON COLUMN knowledge_bases.dify_dataset_id IS 'Dify中对应的数据集ID';
6. documents - 文档表
用途: 存储知识库中上传的文档
CREATE TABLE documents (
id VARCHAR(50) PRIMARY KEY DEFAULT gen_random_uuid()::VARCHAR,
kb_id VARCHAR(50) NOT NULL,
user_id VARCHAR(50) NOT NULL,
-- 文件信息
filename VARCHAR(255) NOT NULL,
file_type VARCHAR(20) NOT NULL, -- pdf, docx
file_size_bytes BIGINT NOT NULL,
file_url TEXT NOT NULL, -- 对象存储URL
-- Dify集成
dify_document_id VARCHAR(100) NOT NULL, -- Dify中的文档ID
-- 处理状态
status VARCHAR(20) DEFAULT 'uploading', -- uploading, processing, completed, failed
progress INTEGER DEFAULT 0, -- 0-100
error_message TEXT,
-- 处理结果
segments_count INTEGER, -- 切分的段落数
tokens_count INTEGER, -- token数量
-- 时间戳
uploaded_at TIMESTAMP DEFAULT NOW(),
processed_at TIMESTAMP,
-- 外键
CONSTRAINT fk_documents_kb FOREIGN KEY (kb_id)
REFERENCES knowledge_bases(id) ON DELETE CASCADE,
CONSTRAINT fk_documents_users FOREIGN KEY (user_id)
REFERENCES users(id) ON DELETE CASCADE,
-- 约束:每个知识库最多50个文档
CONSTRAINT check_doc_limit CHECK (
(SELECT COUNT(*) FROM documents WHERE kb_id = documents.kb_id) <= 50
),
-- 约束:状态和进度
CONSTRAINT check_status CHECK (status IN ('uploading', 'processing', 'completed', 'failed')),
CONSTRAINT check_progress CHECK (progress >= 0 AND progress <= 100)
);
-- 索引
CREATE INDEX idx_documents_kb_id ON documents(kb_id);
CREATE INDEX idx_documents_user_id ON documents(user_id);
CREATE INDEX idx_documents_status ON documents(status);
CREATE INDEX idx_documents_dify_document_id ON documents(dify_document_id);
-- 注释
COMMENT ON TABLE documents IS '文档表,每个知识库最多50个文档';
COMMENT ON COLUMN documents.status IS '处理状态:uploading-上传中, processing-处理中, completed-完成, failed-失败';
7. admin_logs - 管理员操作日志表(可选)
用途: 记录管理员的敏感操作
CREATE TABLE admin_logs (
id SERIAL PRIMARY KEY,
admin_id VARCHAR(50) NOT NULL,
-- 操作信息
action VARCHAR(100) NOT NULL, -- 操作类型
resource_type VARCHAR(50), -- 资源类型:user, conversation, etc.
resource_id VARCHAR(50), -- 资源ID
-- 详细信息
details JSONB,
ip_address VARCHAR(45),
user_agent TEXT,
-- 时间戳
created_at TIMESTAMP DEFAULT NOW(),
-- 外键
CONSTRAINT fk_admin_logs_users FOREIGN KEY (admin_id)
REFERENCES users(id) ON DELETE CASCADE
);
-- 索引
CREATE INDEX idx_admin_logs_admin_id ON admin_logs(admin_id);
CREATE INDEX idx_admin_logs_created_at ON admin_logs(created_at);
CREATE INDEX idx_admin_logs_action ON admin_logs(action);
-- 注释
COMMENT ON TABLE admin_logs IS '管理员操作日志表,用于审计';
8. general_conversations - 通用对话表
用途: 存储智能问答的对话记录(无需项目和智能体)
CREATE TABLE general_conversations (
id VARCHAR(36) PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id VARCHAR(36) NOT NULL,
-- 对话信息
title VARCHAR(255) NOT NULL,
model_name VARCHAR(50), -- 主要使用的模型
-- 时间戳
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
deleted_at TIMESTAMP, -- 软删除
-- 外键
CONSTRAINT fk_general_conversations_users FOREIGN KEY (user_id)
REFERENCES users(id) ON DELETE CASCADE
);
-- 索引
CREATE INDEX idx_general_conversations_user_id ON general_conversations(user_id);
CREATE INDEX idx_general_conversations_created_at ON general_conversations(created_at);
CREATE INDEX idx_general_conversations_updated_at ON general_conversations(updated_at);
-- 注释
COMMENT ON TABLE general_conversations IS '通用对话表,用于智能问答功能';
字段说明:
| 字段 | 类型 | 说明 | 约束 |
|---|---|---|---|
| id | VARCHAR(36) | 对话ID | PRIMARY KEY, UUID |
| user_id | VARCHAR(36) | 用户ID | NOT NULL, FK → users |
| title | VARCHAR(255) | 对话标题(自动生成) | NOT NULL |
| model_name | VARCHAR(50) | 主要使用的模型 | - |
| created_at | TIMESTAMP | 创建时间 | DEFAULT NOW() |
| updated_at | TIMESTAMP | 最后更新时间 | DEFAULT NOW() |
| deleted_at | TIMESTAMP | 删除时间(软删除) | - |
9. general_messages - 通用消息表
用途: 存储智能问答的消息记录
CREATE TABLE general_messages (
id VARCHAR(36) PRIMARY KEY DEFAULT uuid_generate_v4(),
conversation_id VARCHAR(36) NOT NULL,
-- 消息内容
role VARCHAR(20) NOT NULL, -- user / assistant
content TEXT NOT NULL,
-- AI响应信息
model VARCHAR(50), -- 使用的具体模型
tokens INTEGER, -- token消耗
metadata JSONB, -- 扩展信息(如knowledgeBaseIds、usage等)
-- 时间戳
created_at TIMESTAMP DEFAULT NOW(),
-- 外键
CONSTRAINT fk_general_messages_conversations FOREIGN KEY (conversation_id)
REFERENCES general_conversations(id) ON DELETE CASCADE
);
-- 索引
CREATE INDEX idx_general_messages_conversation_id ON general_messages(conversation_id);
CREATE INDEX idx_general_messages_created_at ON general_messages(created_at);
-- 注释
COMMENT ON TABLE general_messages IS '通用消息表,用于智能问答功能';
字段说明:
| 字段 | 类型 | 说明 | 约束 |
|---|---|---|---|
| id | VARCHAR(36) | 消息ID | PRIMARY KEY, UUID |
| conversation_id | VARCHAR(36) | 对话ID | NOT NULL, FK → general_conversations |
| role | VARCHAR(20) | 角色(user/assistant) | NOT NULL |
| content | TEXT | 消息内容 | NOT NULL |
| model | VARCHAR(50) | 使用的模型 | - |
| tokens | INTEGER | token消耗 | - |
| metadata | JSONB | 元数据(知识库IDs、使用统计等) | - |
| created_at | TIMESTAMP | 创建时间 | DEFAULT NOW() |
metadata结构示例:
{
"knowledgeBaseIds": ["kb-uuid-1", "kb-uuid-2"],
"usage": {
"promptTokens": 150,
"completionTokens": 200,
"totalTokens": 350
}
}
索引设计
主要索引
| 表名 | 索引字段 | 类型 | 用途 |
|---|---|---|---|
| users | UNIQUE | 登录查询 | |
| users | status | INDEX | 按状态筛选用户 |
| projects | user_id | INDEX | 查询用户的项目 |
| conversations | user_id | INDEX | 查询用户的对话 |
| conversations | project_id | INDEX | 查询项目的对话 |
| conversations | agent_id | INDEX | 统计智能体使用情况 |
| messages | conversation_id | INDEX | 查询对话消息 |
| knowledge_bases | user_id | INDEX | 查询用户的知识库 |
| documents | kb_id | INDEX | 查询知识库的文档 |
| documents | status | INDEX | 筛选处理状态 |
| general_conversations | user_id | INDEX | 查询用户的通用对话 |
| general_conversations | created_at | INDEX | 按时间排序 |
| general_messages | conversation_id | INDEX | 查询对话消息 |
复合索引(如需优化性能可添加)
-- 按时间范围查询用户的对话
CREATE INDEX idx_conversations_user_created
ON conversations(user_id, created_at DESC);
-- 按项目查询特定智能体的对话
CREATE INDEX idx_conversations_project_agent
ON conversations(project_id, agent_id);
数据约束
业务约束
-
知识库数量限制
- 每个用户最多3个知识库
- 通过CHECK约束和应用层双重控制
-
文档数量限制
- 每个知识库最多50个文档
- 通过CHECK约束和应用层双重控制
-
邮箱格式验证
- 使用正则表达式验证邮箱格式
-
密码安全
- 使用bcrypt加密,成本因子12
- 密码长度至少8位(应用层验证)
数据完整性
-
级联删除
- 删除用户 → 级联删除其项目、对话、知识库
- 删除项目 → 级联删除其对话
- 删除知识库 → 级联删除其文档
-
外键约束
- 所有外键都设置了ON DELETE CASCADE
- 保证数据一致性
数据迁移策略
初始化迁移
# 创建初始迁移
npx prisma migrate dev --name init
# 生成Prisma Client
npx prisma generate
迁移命名规范
yyyymmdd_描述.sql
例如:
20251010_init.sql
20251015_add_admin_logs.sql
20251020_add_user_quotas.sql
生产环境迁移流程
- 在开发环境测试迁移
- 备份生产数据库
- 执行迁移脚本
- 验证数据完整性
- 回滚计划(如有问题)
Prisma Schema
完整的schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(uuid())
email String @unique
password String
name String?
avatarUrl String? @map("avatar_url")
role String @default("user")
status String @default("active")
kbQuota Int @default(3) @map("kb_quota")
kbUsed Int @default(0) @map("kb_used")
trialEndsAt DateTime? @map("trial_ends_at")
isTrial Boolean @default(true) @map("is_trial")
lastLoginAt DateTime? @map("last_login_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
projects Project[]
conversations Conversation[]
knowledgeBases KnowledgeBase[]
documents Document[]
adminLogs AdminLog[]
@@index([email])
@@index([status])
@@index([createdAt])
@@map("users")
}
model Project {
id String @id @default(uuid())
userId String @map("user_id")
name String
description String @db.Text
conversationCount Int @default(0) @map("conversation_count")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
conversations Conversation[]
@@index([userId])
@@index([createdAt])
@@map("projects")
}
model Conversation {
id String @id @default(uuid())
userId String @map("user_id")
projectId String? @map("project_id")
agentId String @map("agent_id")
title String
modelName String @default("deepseek-v3") @map("model_name")
messageCount Int @default(0) @map("message_count")
totalTokens Int @default(0) @map("total_tokens")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
project Project? @relation(fields: [projectId], references: [id], onDelete: Cascade)
messages Message[]
@@index([userId])
@@index([projectId])
@@index([agentId])
@@index([createdAt])
@@map("conversations")
}
model Message {
id String @id @default(uuid())
conversationId String @map("conversation_id")
role String
content String @db.Text
metadata Json?
tokens Int?
isPinned Boolean @default(false) @map("is_pinned")
createdAt DateTime @default(now()) @map("created_at")
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
@@index([conversationId])
@@index([createdAt])
@@index([isPinned])
@@map("messages")
}
model KnowledgeBase {
id String @id @default(uuid())
userId String @map("user_id")
name String
description String?
difyDatasetId String @map("dify_dataset_id")
fileCount Int @default(0) @map("file_count")
totalSizeBytes BigInt @default(0) @map("total_size_bytes")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
documents Document[]
@@index([userId])
@@index([difyDatasetId])
@@map("knowledge_bases")
}
model Document {
id String @id @default(uuid())
kbId String @map("kb_id")
userId String @map("user_id")
filename String
fileType String @map("file_type")
fileSizeBytes BigInt @map("file_size_bytes")
fileUrl String @map("file_url")
difyDocumentId String @map("dify_document_id")
status String @default("uploading")
progress Int @default(0)
errorMessage String? @map("error_message")
segmentsCount Int? @map("segments_count")
tokensCount Int? @map("tokens_count")
uploadedAt DateTime @default(now()) @map("uploaded_at")
processedAt DateTime? @map("processed_at")
knowledgeBase KnowledgeBase @relation(fields: [kbId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([kbId])
@@index([userId])
@@index([status])
@@index([difyDocumentId])
@@map("documents")
}
model AdminLog {
id Int @id @default(autoincrement())
adminId String @map("admin_id")
action String
resourceType String? @map("resource_type")
resourceId String? @map("resource_id")
details Json?
ipAddress String? @map("ip_address")
userAgent String? @map("user_agent")
createdAt DateTime @default(now()) @map("created_at")
admin User @relation(fields: [adminId], references: [id], onDelete: Cascade)
@@index([adminId])
@@index([createdAt])
@@index([action])
@@map("admin_logs")
}
数据字典
枚举值定义
用户角色 (user.role)
user- 普通用户admin- 管理员
账户状态 (user.status)
active- 激活(正常使用)inactive- 未激活(注册但未验证邮箱)suspended- 暂停(违规或欠费)
消息角色 (message.role)
user- 用户消息assistant- AI助手消息
文档状态 (document.status)
uploading- 上传中processing- Dify处理中completed- 处理完成failed- 处理失败
文件类型 (document.file_type)
pdf- PDF文档docx- Word文档
数据安全
敏感数据处理
-
密码
- 使用bcrypt加密(成本因子12)
- 不可逆加密,无法还原明文
-
API Keys
- 不存储在数据库中
- 使用环境变量管理
-
用户数据隔离
- 所有查询必须包含user_id过滤
- 防止越权访问
备份策略
-
自动备份
- 每日全量备份
- 保留最近7天
-
手动备份
- 重大升级前手动备份
- 保留3个版本
性能优化建议
查询优化
-
分页查询
- 使用 LIMIT + OFFSET
- 或使用游标分页(基于ID)
-
避免N+1查询
- 使用Prisma的include和select
- 预加载关联数据
-
合理使用索引
- 频繁查询的字段建立索引
- 定期检查索引使用情况
数据归档
-
历史数据归档
- 对话超过6个月自动归档
- 归档数据移至单独的表
-
日志清理
- admin_logs保留3个月
- 定期清理过期日志
版本变更记录
| 版本 | 日期 | 变更内容 | 作者 |
|---|---|---|---|
| v1.0 | 2025-10-10 | 初始版本,定义所有核心表 | 开发团队 |
文档维护: 数据库结构变更需同步更新本文档
Review频率: 每个里程碑结束后Review一次