# 数据库设计说明书

## （一）引言

### 1. 编写目的
本数据库说明书旨在为专家库系统的开发、维护和后续扩展提供清晰的数据库结构说明，帮助开发人员、测试人员及系统管理员理解数据模型及其关系。主要读者包括：
- 系统架构师：用于了解整体数据库结构；
- 开发人员：用于实现业务逻辑与数据库交互；
- 测试人员：用于验证数据完整性与一致性；
- 系统管理员：用于维护数据库及性能调优。

### 2. 风险承担者
- **任务提出者（需求方）**：确保需求描述准确，避免因需求变更带来的返工风险。
- **软件开发者**：负责按照需求文档完成数据库建模、表结构设计及索引优化，需承担数据模型不合理导致的性能问题。
- **产品使用者（用户）**：在使用过程中反馈数据异常或功能缺陷，需承担因误操作或数据输入错误引发的问题。

### 3. 文档约定
- 命名方法：采用小写字母加下划线的方式命名表、字段、索引等对象。
- 提示方式：使用中文注释标注关键字段的含义。
- 通配符号：`*` 表示可重复项，`?` 表示可选字段。

---

## （二）数据库命名规则

| 类型 | 命名规则 | 示例 |
|------|----------|------|
| 数据库 | `zjk_` + 功能模块缩写 | `zjk_db` |
| 表 | `zjk_` + 实体名称 | `zjk_expert`, `zjk_project` |
| 字段 | 小写字母+下划线 | `expert_id`, `create_time` |
| 主键 | [id](file://D:\jyh-zjk\ruoyi-modules\zjk-api\src\main\java\org\dromara\zjk\domain\ZjkPoint.java#L22-L23) 或 `table_name_id` | `money_id`, `expert_id` |
| 外键 | `referenced_table_name_id` | `expert_id` 引用 `zjk_expert.expert_id` |
| 索引 | `idx_table_column` | `idx_zjk_expert_create_time` |
| 视图 | `v_` + 描述 | `v_expert_summary` |

---

## （三）数据库设计说明

### 1.1 数据库逻辑设计

根据专家库系统业务需求，核心实体包括：
- 专家 (`Expert`)
- 项目 (`Project`)
- 评审阶段 (`ReviewPhase`)
- 抽取记录 (`ExtractionRecord`)
- 费用管理 (`MoneyInfo`)
- 发票 (`Invoice`)
- 积分 (`Point`)
- 学习资料 (`LearningMaterials`)
- 评价 (`Evaluation`)
- 用户 (`User`)

实体之间的关系如下：
- 一个专家可以参与多个项目评审。
- 一个项目包含多个评审阶段。
- 每个评审阶段对应多个抽取记录。
- 抽取记录关联专家、项目及评审阶段。
- 专家费用信息与发票、支付状态相关联。
- 专家积分来源于学习、评价、奖惩等行为。
- 专家可上传论文、专利、荣誉证书等资料。

> 注：此处应附上完整的E-R图。

---

### 1.2 数据库物理设计

#### 范式检查
- 所有表满足第三范式（3NF），无冗余字段。
- 外键约束完整，主键唯一标识每条记录。
- 日期时间字段统一使用 [timestamp](file://D:\jyh-zjk\ruoyi-visual\ruoyi-sentinel-dashboard\src\main\java\com\alibaba\csp\sentinel\dashboard\domain\vo\MetricVo.java#L29-L29) 类型。
- 数值金额字段统一使用 `numeric(precision, scale)` 类型。

#### 物理结构E-R图
> 注：此处应附上物理结构E-R图。

---

### 1.3 数据库分布

| 表名 | 存储位置 | 用途 |
|------|----------|------|
| zjk_expert | PostgreSQL | 存储专家基本信息 |
| zjk_project | PostgreSQL | 存储项目信息 |
| zjk_review_phase | PostgreSQL | 存储评审阶段信息 |
| zjk_expert_item | PostgreSQL | 存储抽取记录 |
| zjk_expert_money_info | PostgreSQL | 存储费用结算信息 |
| zjk_expert_money_fp | PostgreSQL | 存储发票信息 |
| zjk_point | PostgreSQL | 存储积分记录 |
| zjk_learning_materials | PostgreSQL | 存储学习资料信息 |
| zjk_evaluate | PostgreSQL | 存储评价信息 |

---

### 1.4 视图设计

| 视图名 | 定义 | 用途 |
|--------|------|------|
| v_expert_summary | `SELECT expert_id, expert_name, COUNT(*) AS project_count FROM zjk_expert_item GROUP BY expert_id` | 统计专家参与项目数量 |
| v_money_statement | `SELECT expert_id, SUM(expert_money) AS total_fee FROM zjk_expert_money_info GROUP BY expert_id` | 费用统计报表 |
| v_invoice_status | `SELECT fp_num, fp_status, expert_name FROM zjk_expert_money_fp JOIN zjk_expert ON ...` | 查询发票审核状态 |

---

### 1.5 基表设计

以 `zjk_expert_money_info` 为例：

| 字段名 | 类型 | 是否主键 | 可为空 | 默认值 | 描述 |
|--------|------|-----------|--------|--------|------|
| money_id | int8 | 是 | 否 | - | 费用ID |
| expert_id | varchar(255) | 否 | 是 | - | 专家ID |
| expert_money | numeric(255,0) | 否 | 是 | - | 专家费金额 |
| create_time | timestamp | 否 | 是 | - | 创建时间 |
| update_time | timestamp | 否 | 是 | - | 更新时间 |
| status | int | 否 | 是 | 0 | 是否结算（0未结束，1结算） |

其他表结构请参考提供的SQL语句。

---

### 1.6 索引设计

| 索引名 | 表名 | 字段 | 类型 |
|--------|------|------|------|
| idx_zjk_expert_create_time | zjk_expert | create_time | B-tree |
| idx_zjk_money_info_expert_id | zjk_expert_money_info | expert_id | B-tree |
| idx_zjk_invoice_fp_num | zjk_expert_money_fp | fp_num | Hash |

---

### 1.7 完整性约束

| 约束名 | 类型 | 描述 |
|--------|------|------|
| fk_zjk_money_info_expert_id | 外键约束 | 关联 `zjk_expert.expert_id` |
| fk_zjk_invoice_money_id | 外键约束 | 关联 `zjk_expert_money_info.money_id` |
| uk_zjk_expert_email | 唯一性约束 | 专家邮箱唯一 |
| ck_zjk_expert_age_range | 检查约束 | 年龄范围必须大于等于18岁 |

---