8.7 KiB
8.7 KiB
RailwaySystem 数据库 V2 约束与索引技术审查报告 (Round 1 修订版)
审查依据:
RailwaySystem 数据库 V2 字段设计与 Kingbase DDL 规范 V1.0.md及 Round 1 审查要求 审查对象:005_constraints.sql与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 组业务外键全量拓扑
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 包含外键索引、排课多维复合索引与部分唯一索引:
- 外键索引:为所有 26 组外键列配置独立 B-Tree 索引,杜绝父表更新锁定子表或关联全表扫描;
- 排课多维冲突高频复合索引:
- 教师时间冲突检测:
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);
- 教师时间冲突检测:
- 双非空过滤的部分唯一索引(Partial Unique Index):
uq_idx_study_source_eventontrain_study_duration(source_system, source_event_id) WHERE source_system IS NOT NULL AND source_event_id IS NOT NULL;- 审查要点:严格杜绝
source_system为空而单号有值时的幂等逃逸。