-- ============================================================================== -- RailwaySystem 数据库 V2 迁移脚本: 005_constraints.sql -- 适用数据库: KingbaseES V009R003C018 (schema: public) -- 执行目标: 集中创建外键约束 (FK)、唯一约束 (UNIQUE) 与单行一致性检查约束 (CHECK) -- 事务边界: 全程在显式事务 BEGIN ... COMMIT 中执行 -- 设计依据: RailwaySystem 数据库 V2 字段设计与 Kingbase DDL 规范 V1.0 及 Round 1 审查要求 -- 核心原则: -- 1. 所有外键严格使用 ON DELETE NO ACTION,严禁使用 CASCADE -- 2. 唯一约束保护核心领域关系防重 -- 3. 检查约束全面覆盖单行时间、场地互斥、分值非负、容量合法及系统单号联动逻辑 -- ============================================================================== BEGIN; -- ============================================================================== -- 一、唯一约束 (UNIQUE CONSTRAINTS - 共 13 组) -- ============================================================================== -- 1. 学员身份证哈希唯一 (允许 NULL,防重) ALTER TABLE train_student DROP CONSTRAINT IF EXISTS uq_student_idcard_hash; ALTER TABLE train_student ADD CONSTRAINT uq_student_idcard_hash UNIQUE (id_card_hash); -- 2. 课程编码唯一 (允许 NULL) ALTER TABLE train_course DROP CONSTRAINT IF EXISTS uq_course_code; ALTER TABLE train_course ADD CONSTRAINT uq_course_code UNIQUE (c_code); -- 3. 电子班牌硬件序列号全局唯一 ALTER TABLE train_electronic_board DROP CONSTRAINT IF EXISTS uq_board_sn; ALTER TABLE train_electronic_board ADD CONSTRAINT uq_board_sn UNIQUE (board_sn); -- 4. 宿舍房间唯一 (楼栋 + 房号) ALTER TABLE train_dormitory_info DROP CONSTRAINT IF EXISTS uq_dorm_building_room; ALTER TABLE train_dormitory_info ADD CONSTRAINT uq_dorm_building_room UNIQUE (dorm_building, dorm_room); -- 5. 课程与教学资源绑定唯一 ALTER TABLE train_course_resource DROP CONSTRAINT IF EXISTS uq_course_resource; ALTER TABLE train_course_resource ADD CONSTRAINT uq_course_resource UNIQUE (c_id, resource_id); -- 6. 培训班与课程关联唯一 (一个班不能重复加入同一门课) ALTER TABLE train_plan_course DROP CONSTRAINT IF EXISTS uq_plan_course; ALTER TABLE train_plan_course ADD CONSTRAINT uq_plan_course UNIQUE (plan_id, c_id); -- 7. 参训学员档案唯一 (同一学员不能重复加入同一培训班) ALTER TABLE train_enrollment DROP CONSTRAINT IF EXISTS uq_enrollment; ALTER TABLE train_enrollment ADD CONSTRAINT uq_enrollment UNIQUE (plan_id, student_id); -- 8. 住宿安排唯一 (一次参训保留一个有效住宿记录) ALTER TABLE train_accommodation DROP CONSTRAINT IF EXISTS uq_accommodation_enroll; ALTER TABLE train_accommodation ADD CONSTRAINT uq_accommodation_enroll UNIQUE (enrollment_id); -- 9. 门禁授权唯一 (一次住宿安排对应一条门禁同步主记录) ALTER TABLE train_dorm_auth DROP CONSTRAINT IF EXISTS uq_dorm_auth_accomm; ALTER TABLE train_dorm_auth ADD CONSTRAINT uq_dorm_auth_accomm UNIQUE (accommodation_id); -- 10. 报到记录唯一 (一次参训对应一次报到结果) ALTER TABLE train_class_report DROP CONSTRAINT IF EXISTS uq_class_report_enroll; ALTER TABLE train_class_report ADD CONSTRAINT uq_class_report_enroll UNIQUE (enrollment_id); -- 11. 课次考勤打卡唯一 (一个学员在一堂课只有一条考勤主结果) ALTER TABLE train_student_checkin DROP CONSTRAINT IF EXISTS uq_student_checkin_enroll_lesson; ALTER TABLE train_student_checkin ADD CONSTRAINT uq_student_checkin_enroll_lesson UNIQUE (enrollment_id, lesson_id); -- 12. 学员考核项成绩唯一 (一个学员在某考核项只有一条最终得分) ALTER TABLE train_student_score DROP CONSTRAINT IF EXISTS uq_student_score_enroll_item; ALTER TABLE train_student_score ADD CONSTRAINT uq_student_score_enroll_item UNIQUE (enrollment_id, score_item_id); -- 13. 学员参训综合画像唯一 (一次参训生成一份画像) ALTER TABLE train_student_portrait DROP CONSTRAINT IF EXISTS uq_student_portrait_enroll; ALTER TABLE train_student_portrait ADD CONSTRAINT uq_student_portrait_enroll UNIQUE (enrollment_id); -- ============================================================================== -- 二、外键约束 (FOREIGN KEY CONSTRAINTS - 共 26 组,全部 ON DELETE NO ACTION) -- ============================================================================== -- 1. train_course_resource (2 FK) ALTER TABLE train_course_resource DROP CONSTRAINT IF EXISTS fk_cr_course; ALTER TABLE train_course_resource ADD CONSTRAINT fk_cr_course FOREIGN KEY (c_id) REFERENCES train_course (c_id) ON DELETE NO ACTION; ALTER TABLE train_course_resource DROP CONSTRAINT IF EXISTS fk_cr_resource; ALTER TABLE train_course_resource ADD CONSTRAINT fk_cr_resource FOREIGN KEY (resource_id) REFERENCES train_resource (resource_id) ON DELETE NO ACTION; -- 2. train_electronic_board (1 FK) ALTER TABLE train_electronic_board DROP CONSTRAINT IF EXISTS fk_board_classroom; ALTER TABLE train_electronic_board ADD CONSTRAINT fk_board_classroom FOREIGN KEY (bind_classroom_id) REFERENCES train_classroom_info (class_room_id) ON DELETE NO ACTION; -- 3. train_plan_course (2 FK) ALTER TABLE train_plan_course DROP CONSTRAINT IF EXISTS fk_plancourse_plan; ALTER TABLE train_plan_course ADD CONSTRAINT fk_plancourse_plan FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION; ALTER TABLE train_plan_course DROP CONSTRAINT IF EXISTS fk_plancourse_course; ALTER TABLE train_plan_course ADD CONSTRAINT fk_plancourse_course FOREIGN KEY (c_id) REFERENCES train_course (c_id) ON DELETE NO ACTION; -- 4. train_enrollment (2 FK) ALTER TABLE train_enrollment DROP CONSTRAINT IF EXISTS fk_enrollment_plan; ALTER TABLE train_enrollment ADD CONSTRAINT fk_enrollment_plan FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION; ALTER TABLE train_enrollment DROP CONSTRAINT IF EXISTS fk_enrollment_student; ALTER TABLE train_enrollment ADD CONSTRAINT fk_enrollment_student FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION; -- 5. train_lesson (4 FK) ALTER TABLE train_lesson DROP CONSTRAINT IF EXISTS fk_lesson_plancourse; ALTER TABLE train_lesson ADD CONSTRAINT fk_lesson_plancourse FOREIGN KEY (plan_course_id) REFERENCES train_plan_course (plan_course_id) ON DELETE NO ACTION; ALTER TABLE train_lesson DROP CONSTRAINT IF EXISTS fk_lesson_teacher; ALTER TABLE train_lesson ADD CONSTRAINT fk_lesson_teacher FOREIGN KEY (t_id) REFERENCES train_teacher (t_id) ON DELETE NO ACTION; ALTER TABLE train_lesson DROP CONSTRAINT IF EXISTS fk_lesson_classroom; ALTER TABLE train_lesson ADD CONSTRAINT fk_lesson_classroom FOREIGN KEY (class_room_id) REFERENCES train_classroom_info (class_room_id) ON DELETE NO ACTION; ALTER TABLE train_lesson DROP CONSTRAINT IF EXISTS fk_lesson_site; ALTER TABLE train_lesson ADD CONSTRAINT fk_lesson_site FOREIGN KEY (site_id) REFERENCES train_training_site (site_id) ON DELETE NO ACTION; -- 6. train_accommodation (2 FK) ALTER TABLE train_accommodation DROP CONSTRAINT IF EXISTS fk_accomm_enrollment; ALTER TABLE train_accommodation ADD CONSTRAINT fk_accomm_enrollment FOREIGN KEY (enrollment_id) REFERENCES train_enrollment (enrollment_id) ON DELETE NO ACTION; ALTER TABLE train_accommodation DROP CONSTRAINT IF EXISTS fk_accomm_dorm; ALTER TABLE train_accommodation ADD CONSTRAINT fk_accomm_dorm FOREIGN KEY (dorm_id) REFERENCES train_dormitory_info (dorm_id) ON DELETE NO ACTION; -- 7. train_dorm_auth (1 FK) ALTER TABLE train_dorm_auth DROP CONSTRAINT IF EXISTS fk_dormauth_accomm; ALTER TABLE train_dorm_auth ADD CONSTRAINT fk_dormauth_accomm FOREIGN KEY (accommodation_id) REFERENCES train_accommodation (accommodation_id) ON DELETE NO ACTION; -- 8. train_class_report (1 FK) ALTER TABLE train_class_report DROP CONSTRAINT IF EXISTS fk_report_enrollment; ALTER TABLE train_class_report ADD CONSTRAINT fk_report_enrollment FOREIGN KEY (enrollment_id) REFERENCES train_enrollment (enrollment_id) ON DELETE NO ACTION; -- 9. train_student_checkin (3 FK) ALTER TABLE train_student_checkin DROP CONSTRAINT IF EXISTS fk_checkin_enrollment; ALTER TABLE train_student_checkin ADD CONSTRAINT fk_checkin_enrollment FOREIGN KEY (enrollment_id) REFERENCES train_enrollment (enrollment_id) ON DELETE NO ACTION; ALTER TABLE train_student_checkin DROP CONSTRAINT IF EXISTS fk_checkin_lesson; ALTER TABLE train_student_checkin ADD CONSTRAINT fk_checkin_lesson FOREIGN KEY (lesson_id) REFERENCES train_lesson (lesson_id) ON DELETE NO ACTION; ALTER TABLE train_student_checkin DROP CONSTRAINT IF EXISTS fk_checkin_board; ALTER TABLE train_student_checkin ADD CONSTRAINT fk_checkin_board FOREIGN KEY (board_id) REFERENCES train_electronic_board (board_id) ON DELETE NO ACTION; -- 10. train_score_item (2 FK) ALTER TABLE train_score_item DROP CONSTRAINT IF EXISTS fk_scoreitem_plan; ALTER TABLE train_score_item ADD CONSTRAINT fk_scoreitem_plan FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION; ALTER TABLE train_score_item DROP CONSTRAINT IF EXISTS fk_scoreitem_plancourse; ALTER TABLE train_score_item ADD CONSTRAINT fk_scoreitem_plancourse FOREIGN KEY (plan_course_id) REFERENCES train_plan_course (plan_course_id) ON DELETE NO ACTION; -- 11. train_student_score (2 FK) ALTER TABLE train_student_score DROP CONSTRAINT IF EXISTS fk_score_enrollment; ALTER TABLE train_student_score ADD CONSTRAINT fk_score_enrollment FOREIGN KEY (enrollment_id) REFERENCES train_enrollment (enrollment_id) ON DELETE NO ACTION; ALTER TABLE train_student_score DROP CONSTRAINT IF EXISTS fk_score_item; ALTER TABLE train_student_score ADD CONSTRAINT fk_score_item FOREIGN KEY (score_item_id) REFERENCES train_score_item (score_item_id) ON DELETE NO ACTION; -- 12. train_study_duration (3 FK) ALTER TABLE train_study_duration DROP CONSTRAINT IF EXISTS fk_study_enrollment; ALTER TABLE train_study_duration ADD CONSTRAINT fk_study_enrollment FOREIGN KEY (enrollment_id) REFERENCES train_enrollment (enrollment_id) ON DELETE NO ACTION; ALTER TABLE train_study_duration DROP CONSTRAINT IF EXISTS fk_study_plancourse; ALTER TABLE train_study_duration ADD CONSTRAINT fk_study_plancourse FOREIGN KEY (plan_course_id) REFERENCES train_plan_course (plan_course_id) ON DELETE NO ACTION; ALTER TABLE train_study_duration DROP CONSTRAINT IF EXISTS fk_study_resource; ALTER TABLE train_study_duration ADD CONSTRAINT fk_study_resource FOREIGN KEY (resource_id) REFERENCES train_resource (resource_id) ON DELETE NO ACTION; -- 13. train_student_portrait (1 FK) ALTER TABLE train_student_portrait DROP CONSTRAINT IF EXISTS fk_portrait_enrollment; ALTER TABLE train_student_portrait ADD CONSTRAINT fk_portrait_enrollment FOREIGN KEY (enrollment_id) REFERENCES train_enrollment (enrollment_id) ON DELETE NO ACTION; -- ============================================================================== -- 三、单行检查约束 (CHECK CONSTRAINTS) -- ============================================================================== -- 1. 排课时间逻辑检查: 开始时间必须早于结束时间 ALTER TABLE train_lesson DROP CONSTRAINT IF EXISTS chk_lesson_time; ALTER TABLE train_lesson ADD CONSTRAINT chk_lesson_time CHECK (start_time < end_time); -- 2. 排课场地类型单行互斥约束 ALTER TABLE train_lesson DROP CONSTRAINT IF EXISTS chk_lesson_venue; ALTER TABLE train_lesson ADD CONSTRAINT chk_lesson_venue CHECK ( (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. 成绩项目单项权重范围: 0 ~ 100 ALTER TABLE train_score_item DROP CONSTRAINT IF EXISTS chk_score_item_weight; ALTER TABLE train_score_item ADD CONSTRAINT chk_score_item_weight CHECK (weight >= 0.00 AND weight <= 100.00); -- 4. 成绩项目满分设定: 必须大于 0 ALTER TABLE train_score_item DROP CONSTRAINT IF EXISTS chk_score_item_full; ALTER TABLE train_score_item ADD CONSTRAINT chk_score_item_full CHECK (full_score > 0.00); -- 5. 学员得分非负约束 (未录成绩不建行,录入则非负) ALTER TABLE train_student_score DROP CONSTRAINT IF EXISTS chk_student_score_nonneg; ALTER TABLE train_student_score ADD CONSTRAINT chk_student_score_nonneg CHECK (score >= 0.00); -- 6. 学习时长非负检查 ALTER TABLE train_study_duration DROP CONSTRAINT IF EXISTS chk_study_seconds; ALTER TABLE train_study_duration ADD CONSTRAINT chk_study_seconds CHECK (study_seconds >= 0); -- 7. 学习记录时间逻辑检查 ALTER TABLE train_study_duration DROP CONSTRAINT IF EXISTS chk_study_time; ALTER TABLE train_study_duration ADD CONSTRAINT chk_study_time CHECK (end_time IS NULL OR start_time IS NULL OR end_time >= start_time); -- 8. 学习记录外部单号与来源系统一致性检查 ALTER TABLE train_study_duration DROP CONSTRAINT IF EXISTS chk_study_source_system; ALTER TABLE train_study_duration ADD CONSTRAINT chk_study_source_system CHECK (source_event_id IS NULL OR source_system IS NOT NULL); -- 9. 宿舍核定容量正数检查 ALTER TABLE train_dormitory_info DROP CONSTRAINT IF EXISTS chk_dorm_capacity; ALTER TABLE train_dormitory_info ADD CONSTRAINT chk_dorm_capacity CHECK (capacity > 0); COMMIT;