Files
platform-pipi/packages/design-document/database-design.md
T
2026-01-23 17:42:48 +08:00

299 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 字词学习平台 - 数据库设计文档
## 1. 数据库选型
### 1.1 推荐方案:PostgreSQL
**选择理由:**
-**关系型数据优势**:字词、关联关系、用户等数据具有强关联性,适合关系型数据库
-**JSON 支持**PostgreSQL 原生支持 JSON/JSONB,可以灵活存储 SVG 数据
-**全文搜索**:内置全文搜索功能,适合字词搜索场景
-**扩展性强**:支持数组类型,适合存储多个拼音、多个读音等
-**成熟稳定**:企业级数据库,性能优秀
-**开源免费**:成本可控
### 1.2 备选方案
**MySQL 8.0+**
- 优势:生态成熟,使用广泛
- 劣势:JSON 支持不如 PostgreSQL 完善
**MongoDB**
- 优势:文档型数据库,灵活性强
- 劣势:关联查询复杂,不适合强关联关系场景
## 2. 数据表设计
### 2.1 核心设计思路
**是否分离英语和汉字?**
**建议:统一表设计,通过类型字段区分**
**理由:**
1.**数据结构相似**:汉字、词语、英语单词、字母的基础字段基本相同
2.**关联关系统一**:都需要关联图片、句子、关联字词等
3.**查询便利**:统一表结构便于统一查询和筛选
4.**维护简单**:减少表数量,降低维护成本
5.**扩展性好**:后续如需新增类型,只需扩展类型枚举
**如果数据量特别大,可以考虑:**
- 按类型分表(水平分表)
- 使用数据库分区功能
## 3. 数据表详细设计
### 3.1 字词主表 (words)
存储所有字词的基础信息。
```sql
CREATE TABLE words (
id BIGSERIAL PRIMARY KEY,
content VARCHAR(50) NOT NULL COMMENT '字词内容',
type VARCHAR(20) NOT NULL COMMENT '类型: chinese_char(汉字), chinese_word(词语), english_word(英语单词), english_letter(英语字母)',
grade INT COMMENT '年级: 1-9NULL表示未设置',
pinyins TEXT[] COMMENT '拼音数组,支持多音字',
pronunciations TEXT[] COMMENT '读音数组,存储音频文件路径或读音标注',
svg_data JSONB COMMENT 'SVG笔画数据,JSON格式',
description TEXT COMMENT '描述信息',
status VARCHAR(20) DEFAULT 'active' COMMENT '状态: active(启用), inactive(禁用)',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_by BIGINT COMMENT '创建人ID',
updated_by BIGINT COMMENT '更新人ID',
-- 索引
INDEX idx_content (content),
INDEX idx_type (type),
INDEX idx_grade (grade),
INDEX idx_status (status),
INDEX idx_created_at (created_at)
);
-- 全文搜索索引
CREATE INDEX idx_content_fulltext ON words USING GIN (to_tsvector('simple', content));
```
**字段说明:**
- `content`: 字词内容,如"中"、"中国"、"hello"
- `type`: 类型枚举,便于后续扩展
- `grade`: 年级,1-9年级,NULL 表示未设置
- `pinyins`: PostgreSQL 数组类型,存储多个拼音
- `pronunciations`: 读音数组,可以是音频文件路径或文本标注
- `svg_data`: JSONB 类型,存储 SVG 配置数据
- `status`: 启用/禁用状态,支持软删除
### 3.2 图片表 (word_images)
存储字词关联的图片信息。
```sql
CREATE TABLE word_images (
id BIGSERIAL PRIMARY KEY,
word_id BIGINT NOT NULL COMMENT '关联的字词ID',
image_type VARCHAR(20) NOT NULL COMMENT '图片类型: original(原图), standard(标准图)',
file_path VARCHAR(500) NOT NULL COMMENT '图片文件路径',
file_name VARCHAR(200) NOT NULL COMMENT '原始文件名',
file_size BIGINT COMMENT '文件大小(字节)',
width INT COMMENT '图片宽度',
height INT COMMENT '图片高度',
mime_type VARCHAR(50) COMMENT 'MIME类型',
is_primary BOOLEAN DEFAULT FALSE COMMENT '是否为主图',
sort_order INT DEFAULT 0 COMMENT '排序顺序',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (word_id) REFERENCES words(id) ON DELETE CASCADE,
INDEX idx_word_id (word_id),
INDEX idx_image_type (image_type),
INDEX idx_is_primary (is_primary)
);
```
**字段说明:**
- `word_id`: 关联的字词ID
- `image_type`: 区分原图和标准图
- `file_path`: 图片存储路径
- `is_primary`: 标记主图,用于列表展示
- `sort_order`: 排序字段,支持多图排序
### 3.3 字词关联表 (word_relations)
存储字词之间的关联关系。
```sql
CREATE TABLE word_relations (
id BIGSERIAL PRIMARY KEY,
source_word_id BIGINT NOT NULL COMMENT '源字词ID',
target_word_id BIGINT NOT NULL COMMENT '目标字词ID',
relation_type VARCHAR(20) NOT NULL COMMENT '关联类型: word_to_char(词包含字), char_to_word(字的组词), synonym(同义词), antonym(反义词)',
sort_order INT DEFAULT 0 COMMENT '排序顺序',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (source_word_id) REFERENCES words(id) ON DELETE CASCADE,
FOREIGN KEY (target_word_id) REFERENCES words(id) ON DELETE CASCADE,
UNIQUE (source_word_id, target_word_id, relation_type),
INDEX idx_source_word (source_word_id),
INDEX idx_target_word (target_word_id),
INDEX idx_relation_type (relation_type)
);
```
**关联类型说明:**
- `word_to_char`: 词包含字,如"中国"关联"中"和"国"
- `char_to_word`: 字的组词,如"中"关联"中国"、"中间"等
- `synonym`: 同义词(后续扩展)
- `antonym`: 反义词(后续扩展)
### 3.4 句子表 (sentences)
存储字词关联的例句。
```sql
CREATE TABLE sentences (
id BIGSERIAL PRIMARY KEY,
content TEXT NOT NULL COMMENT '句子内容',
translation TEXT COMMENT '翻译(英语句子需要)',
audio_path VARCHAR(500) COMMENT '音频文件路径',
source VARCHAR(100) COMMENT '来源,如教材名称',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_content_fulltext (to_tsvector('simple', content))
);
```
### 3.5 字词-句子关联表 (word_sentences)
存储字词和句子的关联关系。
```sql
CREATE TABLE word_sentences (
id BIGSERIAL PRIMARY KEY,
word_id BIGINT NOT NULL COMMENT '字词ID',
sentence_id BIGINT NOT NULL COMMENT '句子ID',
sort_order INT DEFAULT 0 COMMENT '排序顺序',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (word_id) REFERENCES words(id) ON DELETE CASCADE,
FOREIGN KEY (sentence_id) REFERENCES sentences(id) ON DELETE CASCADE,
UNIQUE (word_id, sentence_id),
INDEX idx_word_id (word_id),
INDEX idx_sentence_id (sentence_id)
);
```
### 3.6 用户表 (users)
存储管理员用户信息。
```sql
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名',
email VARCHAR(100) UNIQUE COMMENT '邮箱',
password_hash VARCHAR(255) NOT NULL COMMENT '密码哈希',
role VARCHAR(20) NOT NULL DEFAULT 'admin' COMMENT '角色: super_admin(超级管理员), admin(一般管理员)',
real_name VARCHAR(50) COMMENT '真实姓名',
avatar VARCHAR(500) COMMENT '头像URL',
status VARCHAR(20) DEFAULT 'active' COMMENT '状态: active(启用), inactive(禁用)',
last_login_at TIMESTAMP COMMENT '最后登录时间',
last_login_ip VARCHAR(50) COMMENT '最后登录IP',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_username (username),
INDEX idx_email (email),
INDEX idx_role (role),
INDEX idx_status (status)
);
```
### 3.7 操作日志表 (operation_logs)
记录用户操作日志,用于审计。
```sql
CREATE TABLE operation_logs (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT COMMENT '操作用户ID',
action VARCHAR(50) NOT NULL COMMENT '操作类型: create, update, delete, upload等',
resource_type VARCHAR(50) NOT NULL COMMENT '资源类型: word, image, sentence等',
resource_id BIGINT COMMENT '资源ID',
description TEXT COMMENT '操作描述',
ip_address VARCHAR(50) COMMENT 'IP地址',
user_agent TEXT COMMENT '用户代理',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL,
INDEX idx_user_id (user_id),
INDEX idx_action (action),
INDEX idx_resource (resource_type, resource_id),
INDEX idx_created_at (created_at)
);
```
## 4. 数据库关系图
```
words (字词主表)
├── word_images (图片表) - 一对多
├── word_relations (字词关联) - 自关联(多对多)
├── word_sentences (字词-句子关联) - 多对多
└── operation_logs (操作日志) - 关联资源
sentences (句子表)
└── word_sentences (字词-句子关联) - 多对多
users (用户表)
└── operation_logs (操作日志) - 一对多
```
## 5. 索引优化建议
### 5.1 查询优化索引
- 字词内容索引:支持快速查找
- 类型+年级组合索引:支持类型和年级筛选
- 全文搜索索引:支持模糊搜索
### 5.2 关联查询优化
- 外键索引:所有外键字段建立索引
- 关联表索引:word_relations、word_sentences 的关联字段索引
## 6. 数据迁移策略
### 6.1 初始化数据
- 创建默认超级管理员账户
- 初始化年级数据字典(可选)
### 6.2 数据导入
- 支持批量导入字词数据
- 支持 CSV/Excel 格式导入
## 7. 数据备份策略
### 7.1 备份方案
- 每日全量备份
- 实时增量备份(可选)
### 7.2 恢复方案
- 支持时间点恢复
- 定期恢复演练
## 8. 性能优化建议
### 8.1 查询优化
- 使用连接池管理数据库连接
- 复杂查询使用视图或物化视图
- 合理使用缓存(Redis
### 8.2 数据量预估
- 字词数据:预计 10,000+ 条
- 图片数据:预计 50,000+ 条
- 关联关系:预计 100,000+ 条
### 8.3 分表策略(如需要)
- 当 words 表数据量超过 100 万时,考虑按类型分表
- 使用 PostgreSQL 分区功能