6.3 KiB
6.3 KiB
数据库设计文档
一、数据库概览
| 项目 | 说明 |
|---|---|
| 数据库名称 | wordbook |
| 字符集 | utf8mb4 |
| 排序规则 | utf8mb4_unicode_ci |
| 存储引擎 | InnoDB |
二、ER 图
erDiagram
USER ||--|{ WORD : has
USER {
uuid id PK "用户ID"
string username UK "用户名"
string password "密码(hash)"
datetime created_at "创建时间"
datetime updated_at "更新时间"
tinyint is_deleted "软删除标记"
}
WORD {
uuid id PK "单词记录ID"
uuid user_id FK "所属用户ID"
string word "单词"
text definition "释义"
json examples "例句列表"
string ai_provider "AI模型来源"
datetime created_at "创建时间"
datetime updated_at "更新时间"
tinyint is_deleted "软删除标记"
}
三、数据表详情
3.1 用户表 (users)
| 用户表名 | users |
|---|
| 字段名 | 数据类型 | 约束 | 索引 | 说明 |
|---|---|---|---|---|
id |
CHAR(36) | PRIMARY KEY | - | 用户唯一标识符(UUID 格式) |
username |
VARCHAR(50) | NOT NULL, UNIQUE | UNIQUE KEY | 用户名,全局唯一,用于登录 |
password |
VARCHAR(255) | NOT NULL | - | 用户密码,存储 bcrypt 哈希值,严禁明文存储 |
created_at |
DATETIME | DEFAULT CURRENT_TIMESTAMP | - | 账户创建时间 |
updated_at |
DATETIME | ON UPDATE CURRENT_TIMESTAMP | - | 账户最后更新时间 |
is_deleted |
TINYINT | DEFAULT 0 | INDEX | 软删除标记,0 表示未删除,1 表示已删除 |
索引设计:
- 主键索引:
id - 唯一索引:
username(防止重复注册)
3.2 单词记录表 (words)
| 单词表名 | words |
|---|
| 字段名 | 数据类型 | 约束 | 索引 | 说明 |
|---|---|---|---|---|
id |
CHAR(36) | PRIMARY KEY | - | 单词记录唯一标识符(UUID 格式) |
user_id |
CHAR(36) | NOT NULL, FOREIGN KEY | - | 所属用户 ID,关联 users.id |
word |
VARCHAR(100) | NOT NULL | INDEX idx_word_search(20) | 单词文本,支持前缀搜索优化 |
definition |
TEXT | NOT NULL | - | AI 生成的单词释义 |
examples |
JSON | NOT NULL | - | 例句列表,存储 JSON 数组格式 |
ai_provider |
ENUM | NOT NULL | - | AI 模型来源标识(deepseek=DeepSeek,qwen=通义千问) |
created_at |
DATETIME | DEFAULT CURRENT_TIMESTAMP | - | 单词记录创建时间 |
updated_at |
DATETIME | ON UPDATE CURRENT_TIMESTAMP | - | 单词记录最后更新时间 |
is_deleted |
TINYINT | DEFAULT 0 | INDEX idx_user_word | 软删除标记 |
索引设计:
- 主键索引:
id - 外键索引:
user_id(自动创建) - 唯一索引:
uk_user_word(user_id, word(50)) - 防止同一用户保存重复单词 - 复合索引:
idx_user_word(user_id, is_deleted) - 优化用户单词列表分页查询 - 前缀索引:
idx_word_search(word(20)) - 支持单词前缀搜索优化
四、表关联关系
4.1 用户与单词的关系
用户 (users) 1 ---- N 单词记录 (words)
- 关系类型:一对多
- 外键约束:
words.user_id→users.id - 级联规则:
ON DELETE CASCADE- 当用户被删除时,该用户的所有单词记录也会被自动删除
4.2 关联查询示例
-- 查询某用户的所有单词(排除已删除)
SELECT * FROM words
WHERE user_id = ? AND is_deleted = 0
ORDER BY created_at DESC
LIMIT ? OFFSET ?;
-- 联表查询用户信息及单词数量
SELECT u.id, u.username, COUNT(w.id) as word_count
FROM users u
LEFT JOIN words w ON u.id = w.user_id AND w.is_deleted = 0
WHERE u.is_deleted = 0
GROUP BY u.id;
4.2 唯一约束说明
uk_user_word 约束确保同一用户不能保存相同的单词两次:
- 触发场景:在"手动保存单词"时
- 业务逻辑:前端应先调用"智能查询单词"接口检查是否已保存,避免触发重复错误
- 不触发场景:"智能查询单词"接口只查询不保存,不会触发此约束
五、核心业务 SQL 查询示例
5.1 智能查询单词
业务逻辑:先检查数据库,未命中则调用 AI(不保存)
-- 查询:检查用户是否已保存该单词
SELECT id, word, definition, examples, ai_provider
FROM words
WHERE user_id = ? AND word = ? AND is_deleted = 0;
5.2 手动保存单词
业务逻辑:将 AI 返回的结果写入数据库
-- 插入:保存单词记录(受 uk_user_word 唯一约束保护)
INSERT INTO words (id, user_id, word, definition, examples, ai_provider)
VALUES (?, ?, ?, ?, ?, ?);
5.3 获取单词列表(分页)
业务逻辑:获取用户所有已保存的单词,支持分页
-- 查询:分页获取单词列表(按创建时间倒序)
SELECT id, word, definition, examples, ai_provider, created_at
FROM words
WHERE user_id = ? AND is_deleted = 0
ORDER BY created_at DESC
LIMIT ? OFFSET ?;
-- 计算总数(用于分页器)
SELECT COUNT(*) as total
FROM words
WHERE user_id = ? AND is_deleted = 0;
5.4 删除单词(软删除)
业务逻辑:根据单词 ID 软删除记录
-- 更新:软删除单词记录
UPDATE words
SET is_deleted = 1, updated_at = CURRENT_TIMESTAMP
WHERE id = ? AND user_id = ? AND is_deleted = 0;
六、索引优化说明
6.1 查询场景分析
| 查询场景 | 涉及字段 | 索引策略 |
|---|---|---|
| 用户登录 | username | UNIQUE KEY |
| 智能查询单词 | user_id, word, deleted_at | uk_user_word(唯一约束) |
| 用户单词列表(分页) | user_id, deleted_at | 复合索引 idx_user_word |
| 单词搜索 | word | 前缀索引 idx_word_search |
| 按用户 ID 查找单词 | user_id | 外键自动索引 |
6.2 示例 JSON 数据结构 (examples 字段)
[
"The word 'serendipity' means finding something good without looking for it.",
"It was pure serendipity that I met my best friend at the coffee shop.",
"Many scientific discoveries are the result of serendipity."
]
七、数据初始化
数据库初始化脚本位于 docs/init.sql,该脚本会在 Docker Compose 启动 MySQL 容器时自动执行。
严禁使用 GORM 的 AutoMigrate 功能进行建表,必须通过此 SQL 脚本初始化数据库。