2026-09-14 02:13:16 +08:00
# RailwaySystem 数据库 V2 约束与索引技术审查报告 (Round 1 修订版)
2026-09-17 16:53:03 +08:00
> **审查依据**: [`RailwaySystem 数据库 V2 字段设计与 Kingbase DDL 规范 V1.0.md`](../archive/database-history/RailwaySystem%20数据库%20V2%20字段设计与%20Kingbase%20DDL%20规范%20V1.0.md) 及 Round 1 审查要求
> **审查对象**: [`005_constraints.sql`](../../RuoYi-Vue/sql/train/v2/005_constraints.sql) 与 [`006_indexes.sql`](../../RuoYi-Vue/sql/train/v2/006_indexes.sql)
2026-09-14 02:13:16 +08:00
---
## 1. 主键(PRIMARY KEY)审查
V2 模型包含 21 张正式业务表,主键设计清晰划分为两类:
### 1.1 业务编码主键 (8 张基础表,varchar(32))
- 适用表:`train_teacher` (t_id), `train_student` (s_id), `train_course` (c_id), `train_resource` (resource_id), `train_classroom_info` (class_room_id), `train_training_site` (site_id), `train_electronic_board` (board_id), `train_dormitory_info` (dorm_id), `train_class_plan` (plan_id)。
- **审查结论**:保持既有若依与业务系统自定义编码惯例,支持业务前缀与分布式生成;在 Kingbase 中具备唯一 B-Tree 聚集索引。
### 1.2 数字自增主键 (13 张关系/过程表,bigint identity)
- 适用表:`train_course_resource` (id), `train_plan_course` (plan_course_id), `train_enrollment` (enrollment_id), `train_lesson` (lesson_id), `train_accommodation` (accommodation_id), `train_dorm_auth` (auth_id), `train_class_report` (report_id), `train_student_checkin` (checkin_id), `train_score_item` (score_item_id), `train_student_score` (score_id), `train_study_duration` (dur_id), `train_student_portrait` (portrait_id)。
- **语法形式**: `BIGINT GENERATED BY DEFAULT AS IDENTITY` 。
- **审查结论**:严格杜绝 MySQL 方言 `AUTO_INCREMENT` ,在 KingbaseES 下生成标准序列并被 JDBC 驱动识别。
---
## 2. 外键约束(FOREIGN KEY)审查
### 2.1 26 组业务外键全量拓扑
```text
train_course_resource (c_id) -> train_course (c_id)
train_course_resource (resource_id) -> train_resource (resource_id)
train_electronic_board (bind_classroom_id) -> train_classroom_info (class_room_id)
train_plan_course (plan_id) -> train_class_plan (plan_id)
train_plan_course (c_id) -> train_course (c_id)
train_enrollment (plan_id) -> train_class_plan (plan_id)
train_enrollment (student_id) -> train_student (s_id)
train_lesson (plan_course_id) -> train_plan_course (plan_course_id)
train_lesson (t_id) -> train_teacher (t_id)
train_lesson (class_room_id) -> train_classroom_info (class_room_id)
train_lesson (site_id) -> train_training_site (site_id)
train_accommodation (enrollment_id) -> train_enrollment (enrollment_id)
train_accommodation (dorm_id) -> train_dormitory_info (dorm_id)
train_dorm_auth (accommodation_id) -> train_accommodation (accommodation_id)
train_class_report (enrollment_id) -> train_enrollment (enrollment_id)
train_student_checkin (enrollment_id) -> train_enrollment (enrollment_id)
train_student_checkin (lesson_id) -> train_lesson (lesson_id)
train_student_checkin (board_id) -> train_electronic_board (board_id)
train_score_item (plan_id) -> train_class_plan (plan_id)
train_score_item (plan_course_id) -> train_plan_course (plan_course_id)
train_student_score (enrollment_id) -> train_enrollment (enrollment_id)
train_student_score (score_item_id) -> train_score_item (score_item_id)
train_study_duration (enrollment_id) -> train_enrollment (enrollment_id)
train_study_duration (plan_course_id) -> train_plan_course (plan_course_id)
train_study_duration (resource_id) -> train_resource (resource_id)
train_student_portrait (enrollment_id) -> train_enrollment (enrollment_id)
```
### 2.2 删除规则原则审查
- **核心合规**:所有 26 组外键规则均为 `ON DELETE NO ACTION` , **零级联删除(CASCADE) **;
- **业务依据**:培训班作废、课程停用或学员离校,绝不可导致学员考勤、历史成绩、学时记录与住宿轨迹发生连带物理抹除,系统必须保留可追溯痕迹;
- **系统表解耦**:所有培训表未对 `sys_user` 建立物理外键约束,仅在业务代码层做逻辑关联,避免跨领域强耦合。
---
## 3. 唯一约束(UNIQUE)审查
V2 DDL 共注入 13 组核心业务 UNIQUE 约束:
| 序号 | 约束名称 | 作用表 | 约束字段 | 业务防重目标 |
| :--- | :--- | :--- | :--- | :--- |
| 1 | `uq_student_idcard_hash` | `train_student` | `id_card_hash` | 学员身份证精确防重(允许 NULL) |
| 2 | `uq_course_code` | `train_course` | `c_code` | 课程业务编码全局唯一 |
| 3 | `uq_board_sn` | `train_electronic_board` | `board_sn` | 班牌设备硬件序列号全局唯一 |
| 4 | `uq_dorm_building_room` | `train_dormitory_info` | `(dorm_building, dorm_room)` | 楼栋与房间组合唯一 |
| 5 | `uq_course_resource` | `train_course_resource` | `(c_id, resource_id)` | 课程与资源绑定防重复 |
| 6 | `uq_plan_course` | `train_plan_course` | `(plan_id, c_id)` | 同一培训班不可重复配置相同课程 |
| 7 | `uq_enrollment` | `train_enrollment` | `(plan_id, student_id)` | 同一学员不可重复加入同一培训班 |
| 8 | `uq_accommodation` | `train_accommodation` | `(enrollment_id)` | 一次参训单期唯一有效住宿分配 |
| 9 | `uq_dorm_auth` | `train_dorm_auth` | `(accommodation_id)` | 一次住宿安排对应唯一门禁同步记录 |
| 10 | `uq_class_report` | `train_class_report` | `(enrollment_id)` | 一次参训对应唯一现场报到结论 |
| 11 | `uq_student_checkin` | `train_student_checkin` | `(enrollment_id, lesson_id)` | 一个学员一堂课只有一条考勤结论 |
| 12 | `uq_student_score` | `train_student_score` | `(enrollment_id, score_item_id)` | 一个学员在某考核项只有一条最终得分 |
| 13 | `uq_student_portrait` | `train_student_portrait` | `(enrollment_id)` | 一次参训对应一份全周期评价画像 |
---
## 4. 检查约束(CHECK)审查 (Round 1 扩充)
在 Round 1 审查中,单行检查约束由原先的 4 条大幅扩充至 9 条,全面覆盖时间有效性、场地互斥、数值合法与系统字段联动:
| 序号 | 约束名称 | 作用表 | 约束定义 | 校验逻辑目标 |
| :---: | :--- | :--- | :--- | :--- |
| 1 | `chk_lesson_time` | `train_lesson` | `start_time < end_time` | 课次开始时间必须早于结束时间 |
| 2 | `chk_lesson_venue` | `train_lesson` | `(venue_type = 1 AND class_room_id IS NOT NULL AND site_id IS NULL) OR (venue_type = 2 AND site_id IS NOT NULL AND class_room_id IS NULL)` | **场地互斥** :教室与实训场地二选一,杜绝混淆 |
| 3 | `chk_score_item_weight` | `train_score_item` | `weight >= 0.00 AND weight <= 100.00` | 单项成绩权重必须在 0~100 之间 |
| 4 | `chk_score_item_full` | `train_score_item` | `full_score > 0.00` | 满分设定必须大于 0 |
| 5 | `chk_student_score_nonneg` | `train_student_score` | `score >= 0.00` | **分值非负** :未录入不建行,录入则必须非负 |
| 6 | `chk_study_seconds` | `train_study_duration` | `study_seconds >= 0` | 累计学习秒数必须非负 |
| 7 | `chk_study_time` | `train_study_duration` | `end_time IS NULL OR start_time IS NULL OR end_time >= start_time` | **学时先后** :学习结束时间不得早于开始时间 |
| 8 | `chk_study_source_system` | `train_study_duration` | `source_event_id IS NULL OR source_system IS NOT NULL` | **单号匹配** :有外部单号时必须声明来源系统 |
| 9 | `chk_dorm_capacity` | `train_dormitory_info` | `capacity > 0` | **容量正数** :宿舍房间核定床位数必须大于 0 |
---
## 5. 索引(INDEX)审查
2026-09-17 16:53:03 +08:00
[`006_indexes.sql` ](../../RuoYi-Vue/sql/train/v2/006_indexes.sql ) 包含外键索引、排课多维复合索引与部分唯一索引:
2026-09-14 02:13:16 +08:00
1. **外键索引** :为所有 26 组外键列配置独立 B-Tree 索引,杜绝父表更新锁定子表或关联全表扫描;
2. **排课多维冲突高频复合索引** :
- 教师时间冲突检测:`idx_lesson_teacher_time (t_id, start_time, end_time)` ;
- 教室时间冲突检测:`idx_lesson_classroom_time (class_room_id, start_time, end_time)` ;
- 场地时间冲突检测:`idx_lesson_site_time (site_id, start_time, end_time)` ;
3. **双非空过滤的部分唯一索引(Partial Unique Index) ** :
- `uq_idx_study_source_event` on `train_study_duration(source_system, source_event_id) WHERE source_system IS NOT NULL AND source_event_id IS NOT NULL` ;
- **审查要点**:严格杜绝 `source_system` 为空而单号有值时的幂等逃逸。