# RailwaySystem 数据库 V2 约束与索引技术审查报告 (Round 1 修订版) > **审查依据**:[`RailwaySystem 数据库 V2 字段设计与 Kingbase DDL 规范 V1.0.md`](file:///Users/wzb/Desktop/项目/RailwaySystem/doc/RailwaySystem%20数据库%20V2%20字段设计与%20Kingbase%20DDL%20规范%20V1.0.md) 及 Round 1 审查要求 > **审查对象**:[`005_constraints.sql`](file:///Users/wzb/Desktop/项目/RailwaySystem/RuoYi-Vue/sql/train/v2/005_constraints.sql) 与 [`006_indexes.sql`](file:///Users/wzb/Desktop/项目/RailwaySystem/RuoYi-Vue/sql/train/v2/006_indexes.sql) --- ## 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)审查 [`006_indexes.sql`](file:///Users/wzb/Desktop/项目/RailwaySystem/RuoYi-Vue/sql/train/v2/006_indexes.sql) 包含外键索引、排课多维复合索引与部分唯一索引: 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` 为空而单号有值时的幂等逃逸。