feat(db): 新增Kingbase数据库V2迁移与回滚脚本

This commit is contained in:
wangzhibiao committed 2026-09-14 02:13:09 +08:00
1 parent 277c9e210e
commit c791e23f3e
17 files changed
+3386

No files matched your search

@@ -0,0 +1,356 @@
-- ==============================================================================
-- RailwaySystem 数据库 V2 回滚基线: 000_phase05_exact_schema.sql
-- 适用数据库: KingbaseES V009R003C018 (schema: public)
-- 执行目标: 精确定义 Phase 0.5 历史基线 14 张培训业务表的完整物理 DDL
-- 依据来源: codebase-audit 13_live_database_snapshot.md 真实元数据基线
-- 包含内容:
-- 1. 14 张表物理字段定义、NOT NULL、DEFAULT
-- 2. 14 个 PRIMARY KEY (8 个 varchar(32), 6 个 bigint GENERATED BY DEFAULT AS IDENTITY)
-- 3. 7 组历史业务 UNIQUE 约束
-- 4. 24 组历史业务 FOREIGN KEY 约束
-- 5. 9 个 update_time 触发器 (绑定 func_train_update_modifytime)
-- 说明: 本文件为 Phase 0.5 原始结构标准,作为回滚操作的唯一结构依据,杜绝 CTAS 推断结构
-- ==============================================================================
-- 1. train_teacher 教师主档
CREATE TABLE train_teacher (
t_id VARCHAR(32) NOT NULL,
t_name VARCHAR(30) NOT NULL,
t_gender CHAR(2),
t_birth DATE,
t_department VARCHAR(50) NOT NULL,
t_title VARCHAR(30),
t_phone VARCHAR(20),
t_email VARCHAR(50),
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_teacher PRIMARY KEY (t_id)
);
-- 2. train_student 学员表
CREATE TABLE train_student (
s_id VARCHAR(32) NOT NULL,
s_name VARCHAR(30) NOT NULL,
s_gender CHAR(2),
s_birth DATE,
s_department VARCHAR(50) NOT NULL,
s_major VARCHAR(50) NOT NULL,
s_class VARCHAR(30),
s_phone VARCHAR(20),
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_student PRIMARY KEY (s_id)
);
-- 3. train_course 课程表
CREATE TABLE train_course (
c_id VARCHAR(32) NOT NULL,
c_name VARCHAR(100) NOT NULL,
c_type VARCHAR(30),
c_duration INTEGER,
teaching_objective TEXT,
course_content TEXT,
attach_doc TEXT,
attach_video TEXT,
attach_model_link TEXT,
model_resource_ids TEXT,
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_course PRIMARY KEY (c_id)
);
-- 4. train_class_plan 开班计划表
CREATE TABLE train_class_plan (
plan_id VARCHAR(32) NOT NULL,
plan_name VARCHAR(100) NOT NULL,
c_id VARCHAR(32) NOT NULL,
start_time TIMESTAMP NOT NULL,
end_time TIMESTAMP NOT NULL,
train_address VARCHAR(100),
t_id VARCHAR(32) NOT NULL,
recruit_num INTEGER,
apply_condition TEXT,
plan_status SMALLINT DEFAULT 0,
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_class_plan PRIMARY KEY (plan_id)
);
-- 5. train_dormitory_info 宿舍信息表
CREATE TABLE train_dormitory_info (
dorm_id VARCHAR(32) NOT NULL,
dorm_building VARCHAR(50),
dorm_room VARCHAR(30) NOT NULL,
bed_total INTEGER,
bed_used INTEGER DEFAULT 0,
lock_device_sn VARCHAR(64),
dorm_status SMALLINT DEFAULT 1,
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_dormitory_info PRIMARY KEY (dorm_id),
CONSTRAINT uq_dorm_building_room UNIQUE (dorm_building, dorm_room)
);
-- 6. train_dorm_auth 宿舍门禁表
CREATE TABLE train_dorm_auth (
auth_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
student_id VARCHAR(32) NOT NULL,
plan_id VARCHAR(32) NOT NULL,
dorm_id VARCHAR(32) NOT NULL,
bed_no VARCHAR(20),
face_sync_status SMALLINT DEFAULT 0,
auth_start TIMESTAMP,
auth_end TIMESTAMP,
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_dorm_auth PRIMARY KEY (auth_id),
CONSTRAINT uq_dormauth_stu_plan UNIQUE (student_id, plan_id)
);
-- 7. train_classroom_info 教室信息表
CREATE TABLE train_classroom_info (
class_room_id VARCHAR(32) NOT NULL,
room_name VARCHAR(60) NOT NULL,
room_location VARCHAR(100),
capacity INTEGER,
room_status SMALLINT DEFAULT 1,
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_classroom_info PRIMARY KEY (class_room_id)
);
-- 8. train_training_site 实训场地表
CREATE TABLE train_training_site (
site_id VARCHAR(32) NOT NULL,
site_name VARCHAR(80) NOT NULL,
site_location VARCHAR(100),
capacity INTEGER,
site_device TEXT,
site_status SMALLINT DEFAULT 1,
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_training_site PRIMARY KEY (site_id)
);
-- 9. train_class_report 报到记录表
CREATE TABLE train_class_report (
report_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
plan_id VARCHAR(32) NOT NULL,
student_id VARCHAR(32) NOT NULL,
report_way SMALLINT,
report_device_sn VARCHAR(64),
report_time TIMESTAMP,
report_status SMALLINT DEFAULT 0,
alloc_dorm_id VARCHAR(32),
alloc_classroom_id VARCHAR(32),
alloc_site_id VARCHAR(32),
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_train_class_report PRIMARY KEY (report_id),
CONSTRAINT uq_classreport_plan_stu UNIQUE (plan_id, student_id)
);
-- 10. train_electronic_board 电子班牌表
CREATE TABLE train_electronic_board (
board_id VARCHAR(32) NOT NULL,
board_sn VARCHAR(64) NOT NULL,
bind_classroom_id VARCHAR(32),
bind_plan_id VARCHAR(32),
board_ip VARCHAR(50),
board_content VARCHAR(500),
board_playmode SMALLINT DEFAULT 1,
support_checkin_type VARCHAR(30),
board_status SMALLINT DEFAULT 1,
last_heartbeat TIMESTAMP,
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_electronic_board PRIMARY KEY (board_id),
CONSTRAINT uq_board_sn UNIQUE (board_sn)
);
-- 11. train_student_checkin 考勤签到表
CREATE TABLE train_student_checkin (
checkin_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
plan_id VARCHAR(32) NOT NULL,
c_id VARCHAR(32) NOT NULL,
student_id VARCHAR(32) NOT NULL,
board_id VARCHAR(32),
checkin_way SMALLINT,
checkin_time TIMESTAMP,
checkin_status SMALLINT,
lesson_start_time TIMESTAMP,
lesson_end_time TIMESTAMP,
CONSTRAINT pk_train_student_checkin PRIMARY KEY (checkin_id),
CONSTRAINT uq_checkin_lesson_stu UNIQUE (plan_id, c_id, student_id, lesson_start_time)
);
-- 12. train_score_info 成绩信息表 (历史旧表)
CREATE TABLE train_score_info (
score_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
plan_id VARCHAR(32),
c_id VARCHAR(32),
student_id VARCHAR(32),
course_score NUMERIC(5,2),
train_score NUMERIC(5,2),
exam_score NUMERIC(5,2),
source_type SMALLINT,
source_system VARCHAR(50),
import_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_train_score_info PRIMARY KEY (score_id),
CONSTRAINT uq_scoreinfo_plan_c_stu UNIQUE (plan_id, c_id, student_id)
);
-- 13. train_study_duration 学习时长表
CREATE TABLE train_study_duration (
dur_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
student_id VARCHAR(32),
plan_id VARCHAR(32),
c_id VARCHAR(32),
device_type VARCHAR(50),
start_time TIMESTAMP,
end_time TIMESTAMP,
study_seconds INTEGER,
sync_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_train_study_duration PRIMARY KEY (dur_id)
);
-- 14. train_student_portrait 学员画像表
CREATE TABLE train_student_portrait (
portrait_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
student_id VARCHAR(32) NOT NULL,
plan_id VARCHAR(32) NOT NULL,
total_study_hour NUMERIC(8,2),
avg_score NUMERIC(5,2),
checkin_rate NUMERIC(5,2),
label_tag TEXT,
portrait_content TEXT,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_train_student_portrait PRIMARY KEY (portrait_id),
CONSTRAINT uq_portrait_stu_plan UNIQUE (student_id, plan_id)
);
-- ==============================================================================
-- 历史 24 个外键约束 (FOREIGN KEY CONSTRAINTS - 全部 ON DELETE NO ACTION)
-- ==============================================================================
-- train_class_plan (2 FK)
ALTER TABLE train_class_plan ADD CONSTRAINT fk_classplan_course
FOREIGN KEY (c_id) REFERENCES train_course (c_id) ON DELETE NO ACTION;
ALTER TABLE train_class_plan ADD CONSTRAINT fk_classplan_teacher
FOREIGN KEY (t_id) REFERENCES train_teacher (t_id) ON DELETE NO ACTION;
-- train_dorm_auth (3 FK)
ALTER TABLE train_dorm_auth ADD CONSTRAINT fk_dormauth_stu
FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION;
ALTER TABLE train_dorm_auth ADD CONSTRAINT fk_dormauth_plan
FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION;
ALTER TABLE train_dorm_auth ADD CONSTRAINT fk_dormauth_dorm
FOREIGN KEY (dorm_id) REFERENCES train_dormitory_info (dorm_id) ON DELETE NO ACTION;
-- train_class_report (5 FK)
ALTER TABLE train_class_report ADD CONSTRAINT fk_classreport_plan
FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION;
ALTER TABLE train_class_report ADD CONSTRAINT fk_classreport_stu
FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION;
ALTER TABLE train_class_report ADD CONSTRAINT fk_classreport_dorm
FOREIGN KEY (alloc_dorm_id) REFERENCES train_dormitory_info (dorm_id) ON DELETE NO ACTION;
ALTER TABLE train_class_report ADD CONSTRAINT fk_classreport_classroom
FOREIGN KEY (alloc_classroom_id) REFERENCES train_classroom_info (class_room_id) ON DELETE NO ACTION;
ALTER TABLE train_class_report ADD CONSTRAINT fk_classreport_site
FOREIGN KEY (alloc_site_id) REFERENCES train_training_site (site_id) ON DELETE NO ACTION;
-- train_electronic_board (2 FK)
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;
ALTER TABLE train_electronic_board ADD CONSTRAINT fk_board_plan
FOREIGN KEY (bind_plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION;
-- train_student_checkin (4 FK)
ALTER TABLE train_student_checkin ADD CONSTRAINT fk_checkin_plan
FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION;
ALTER TABLE train_student_checkin ADD CONSTRAINT fk_checkin_course
FOREIGN KEY (c_id) REFERENCES train_course (c_id) ON DELETE NO ACTION;
ALTER TABLE train_student_checkin ADD CONSTRAINT fk_checkin_stu
FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION;
ALTER TABLE train_student_checkin ADD CONSTRAINT fk_checkin_board
FOREIGN KEY (board_id) REFERENCES train_electronic_board (board_id) ON DELETE NO ACTION;
-- train_score_info (3 FK)
ALTER TABLE train_score_info ADD CONSTRAINT fk_scoreinfo_plan
FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION;
ALTER TABLE train_score_info ADD CONSTRAINT fk_scoreinfo_course
FOREIGN KEY (c_id) REFERENCES train_course (c_id) ON DELETE NO ACTION;
ALTER TABLE train_score_info ADD CONSTRAINT fk_scoreinfo_stu
FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION;
-- train_study_duration (3 FK)
ALTER TABLE train_study_duration ADD CONSTRAINT fk_studydur_stu
FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION;
ALTER TABLE train_study_duration ADD CONSTRAINT fk_studydur_plan
FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION;
ALTER TABLE train_study_duration ADD CONSTRAINT fk_studydur_course
FOREIGN KEY (c_id) REFERENCES train_course (c_id) ON DELETE NO ACTION;
-- train_student_portrait (2 FK)
ALTER TABLE train_student_portrait ADD CONSTRAINT fk_portrait_stu
FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION;
ALTER TABLE train_student_portrait ADD CONSTRAINT fk_portrait_plan
FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION;
-- ==============================================================================
-- 历史 9 个 update_time 触发器
-- ==============================================================================
CREATE OR REPLACE TRIGGER trig_train_teacher_modify
BEFORE UPDATE ON train_teacher
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_student_modify
BEFORE UPDATE ON train_student
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_course_modify
BEFORE UPDATE ON train_course
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_classroom_modify
BEFORE UPDATE ON train_classroom_info
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_trainsite_modify
BEFORE UPDATE ON train_training_site
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_board_modify
BEFORE UPDATE ON train_electronic_board
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_dorminfo_modify
BEFORE UPDATE ON train_dormitory_info
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_classplan_modify
BEFORE UPDATE ON train_class_plan
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_dormauth_modify
BEFORE UPDATE ON train_dorm_auth
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
@@ -0,0 +1,45 @@
-- ==============================================================================
-- RailwaySystem 数据库 V2 回滚脚本: 001_rollback_new_tables.sql
-- 适用数据库: KingbaseES V009R003C018 (schema: public)
-- 执行目标: 安全下线并删除数据库 V2 新增的 8 张培训业务表
-- 事务边界: 全程在显式事务 BEGIN ... COMMIT 中执行
-- 说明: 先显式解除外键约束,然后按依赖反序执行常规 DROP TABLE (无 CASCADE)
-- ==============================================================================
BEGIN;
-- 步骤 1: 显式解除 V2 新增表之间的外键约束
ALTER TABLE train_student_score DROP CONSTRAINT IF EXISTS fk_score_enrollment;
ALTER TABLE train_student_score DROP CONSTRAINT IF EXISTS fk_score_item;
ALTER TABLE train_score_item DROP CONSTRAINT IF EXISTS fk_scoreitem_plan;
ALTER TABLE train_score_item DROP CONSTRAINT IF EXISTS fk_scoreitem_plancourse;
ALTER TABLE train_lesson DROP CONSTRAINT IF EXISTS fk_lesson_plancourse;
ALTER TABLE train_lesson DROP CONSTRAINT IF EXISTS fk_lesson_teacher;
ALTER TABLE train_lesson DROP CONSTRAINT IF EXISTS fk_lesson_classroom;
ALTER TABLE train_lesson DROP CONSTRAINT IF EXISTS fk_lesson_site;
ALTER TABLE train_accommodation DROP CONSTRAINT IF EXISTS fk_accomm_enrollment;
ALTER TABLE train_accommodation DROP CONSTRAINT IF EXISTS fk_accomm_dorm;
ALTER TABLE train_enrollment DROP CONSTRAINT IF EXISTS fk_enrollment_plan;
ALTER TABLE train_enrollment DROP CONSTRAINT IF EXISTS fk_enrollment_student;
ALTER TABLE train_plan_course DROP CONSTRAINT IF EXISTS fk_plancourse_plan;
ALTER TABLE train_plan_course DROP CONSTRAINT IF EXISTS fk_plancourse_course;
ALTER TABLE train_course_resource DROP CONSTRAINT IF EXISTS fk_cr_course;
ALTER TABLE train_course_resource DROP CONSTRAINT IF EXISTS fk_cr_resource;
-- 步骤 2: 按依赖拓扑反序执行常规 DROP TABLE
DROP TABLE IF EXISTS train_student_score;
DROP TABLE IF EXISTS train_score_item;
DROP TABLE IF EXISTS train_lesson;
DROP TABLE IF EXISTS train_accommodation;
DROP TABLE IF EXISTS train_enrollment;
DROP TABLE IF EXISTS train_plan_course;
DROP TABLE IF EXISTS train_course_resource;
DROP TABLE IF EXISTS train_resource;
COMMIT;
@@ -0,0 +1,337 @@
-- ==============================================================================
-- RailwaySystem 数据库 V2 回滚脚本: 002_rollback_modified_tables.sql
-- 适用数据库: KingbaseES V009R003C018 (schema: public)
-- 执行目标: 严格基于 000_phase05_exact_schema.sql 结构与 bak_v1_* 数据还原 13 张表
-- 事务边界: 全程在显式事务 BEGIN ... COMMIT 中执行
-- 规范要求:
-- 1. 彻底摒弃 CTAS 丢失约束/默认值/触发器的不可靠方案
-- 2. 精确采用 Phase 0.5 原始 DDL 重建表结构
-- 3. 从 bak_v1_* 恢复真实数据并严格校验行数
-- ==============================================================================
BEGIN;
-- 步骤 1: 显式解除既有 V2 外键约束与旧外键
ALTER TABLE train_dorm_auth DROP CONSTRAINT IF EXISTS uq_dorm_auth_accomm;
ALTER TABLE train_dorm_auth DROP CONSTRAINT IF EXISTS fk_dormauth_accomm;
ALTER TABLE train_class_report DROP CONSTRAINT IF EXISTS uq_class_report_enroll;
ALTER TABLE train_class_report DROP CONSTRAINT IF EXISTS fk_report_enrollment;
ALTER TABLE train_student_checkin DROP CONSTRAINT IF EXISTS uq_student_checkin_enroll_lesson;
ALTER TABLE train_student_checkin DROP CONSTRAINT IF EXISTS fk_checkin_enrollment;
ALTER TABLE train_student_checkin DROP CONSTRAINT IF EXISTS fk_checkin_lesson;
ALTER TABLE train_student_checkin DROP CONSTRAINT IF EXISTS fk_checkin_board;
ALTER TABLE train_study_duration DROP CONSTRAINT IF EXISTS fk_study_enrollment;
ALTER TABLE train_study_duration DROP CONSTRAINT IF EXISTS fk_study_plancourse;
ALTER TABLE train_study_duration DROP CONSTRAINT IF EXISTS fk_study_resource;
ALTER TABLE train_student_portrait DROP CONSTRAINT IF EXISTS uq_student_portrait_enroll;
ALTER TABLE train_student_portrait DROP CONSTRAINT IF EXISTS fk_portrait_enrollment;
ALTER TABLE train_electronic_board DROP CONSTRAINT IF EXISTS fk_board_classroom;
-- 步骤 2: 常规 DROP 13 张表
DROP TABLE IF EXISTS train_student_portrait;
DROP TABLE IF EXISTS train_study_duration;
DROP TABLE IF EXISTS train_student_checkin;
DROP TABLE IF EXISTS train_class_report;
DROP TABLE IF EXISTS train_dorm_auth;
DROP TABLE IF EXISTS train_electronic_board;
DROP TABLE IF EXISTS train_dormitory_info;
DROP TABLE IF EXISTS train_class_plan;
DROP TABLE IF EXISTS train_training_site;
DROP TABLE IF EXISTS train_classroom_info;
DROP TABLE IF EXISTS train_course;
DROP TABLE IF EXISTS train_student;
DROP TABLE IF EXISTS train_teacher;
-- 步骤 3: 严格依据 Phase 0.5 原始 DDL 重建 13 张表物理结构
CREATE TABLE train_teacher (
t_id VARCHAR(32) NOT NULL,
t_name VARCHAR(30) NOT NULL,
t_gender CHAR(2),
t_birth DATE,
t_department VARCHAR(50) NOT NULL,
t_title VARCHAR(30),
t_phone VARCHAR(20),
t_email VARCHAR(50),
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_teacher PRIMARY KEY (t_id)
);
CREATE TABLE train_student (
s_id VARCHAR(32) NOT NULL,
s_name VARCHAR(30) NOT NULL,
s_gender CHAR(2),
s_birth DATE,
s_department VARCHAR(50) NOT NULL,
s_major VARCHAR(50) NOT NULL,
s_class VARCHAR(30),
s_phone VARCHAR(20),
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_student PRIMARY KEY (s_id)
);
CREATE TABLE train_course (
c_id VARCHAR(32) NOT NULL,
c_name VARCHAR(100) NOT NULL,
c_type VARCHAR(30),
c_duration INTEGER,
teaching_objective TEXT,
course_content TEXT,
attach_doc TEXT,
attach_video TEXT,
attach_model_link TEXT,
model_resource_ids TEXT,
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_course PRIMARY KEY (c_id)
);
CREATE TABLE train_classroom_info (
class_room_id VARCHAR(32) NOT NULL,
room_name VARCHAR(60) NOT NULL,
room_location VARCHAR(100),
capacity INTEGER,
room_status SMALLINT DEFAULT 1,
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_classroom_info PRIMARY KEY (class_room_id)
);
CREATE TABLE train_training_site (
site_id VARCHAR(32) NOT NULL,
site_name VARCHAR(80) NOT NULL,
site_location VARCHAR(100),
capacity INTEGER,
site_device TEXT,
site_status SMALLINT DEFAULT 1,
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_training_site PRIMARY KEY (site_id)
);
CREATE TABLE train_class_plan (
plan_id VARCHAR(32) NOT NULL,
plan_name VARCHAR(100) NOT NULL,
c_id VARCHAR(32) NOT NULL,
start_time TIMESTAMP NOT NULL,
end_time TIMESTAMP NOT NULL,
train_address VARCHAR(100),
t_id VARCHAR(32) NOT NULL,
recruit_num INTEGER,
apply_condition TEXT,
plan_status SMALLINT DEFAULT 0,
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_class_plan PRIMARY KEY (plan_id),
CONSTRAINT fk_classplan_course FOREIGN KEY (c_id) REFERENCES train_course (c_id) ON DELETE NO ACTION,
CONSTRAINT fk_classplan_teacher FOREIGN KEY (t_id) REFERENCES train_teacher (t_id) ON DELETE NO ACTION
);
CREATE TABLE train_dormitory_info (
dorm_id VARCHAR(32) NOT NULL,
dorm_building VARCHAR(50),
dorm_room VARCHAR(30) NOT NULL,
bed_total INTEGER,
bed_used INTEGER DEFAULT 0,
lock_device_sn VARCHAR(64),
dorm_status SMALLINT DEFAULT 1,
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_dormitory_info PRIMARY KEY (dorm_id),
CONSTRAINT uq_dorm_building_room UNIQUE (dorm_building, dorm_room)
);
CREATE TABLE train_electronic_board (
board_id VARCHAR(32) NOT NULL,
board_sn VARCHAR(64) NOT NULL,
bind_classroom_id VARCHAR(32),
bind_plan_id VARCHAR(32),
board_ip VARCHAR(50),
board_content VARCHAR(500),
board_playmode SMALLINT DEFAULT 1,
support_checkin_type VARCHAR(30),
board_status SMALLINT DEFAULT 1,
last_heartbeat TIMESTAMP,
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_electronic_board PRIMARY KEY (board_id),
CONSTRAINT uq_board_sn UNIQUE (board_sn),
CONSTRAINT fk_board_classroom FOREIGN KEY (bind_classroom_id) REFERENCES train_classroom_info (class_room_id) ON DELETE NO ACTION,
CONSTRAINT fk_board_plan FOREIGN KEY (bind_plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION
);
CREATE TABLE train_dorm_auth (
auth_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
student_id VARCHAR(32) NOT NULL,
plan_id VARCHAR(32) NOT NULL,
dorm_id VARCHAR(32) NOT NULL,
bed_no VARCHAR(20),
face_sync_status SMALLINT DEFAULT 0,
auth_start TIMESTAMP,
auth_end TIMESTAMP,
create_user VARCHAR(32) NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
remark VARCHAR(200),
CONSTRAINT pk_train_dorm_auth PRIMARY KEY (auth_id),
CONSTRAINT uq_dormauth_stu_plan UNIQUE (student_id, plan_id),
CONSTRAINT fk_dormauth_stu FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION,
CONSTRAINT fk_dormauth_plan FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION,
CONSTRAINT fk_dormauth_dorm FOREIGN KEY (dorm_id) REFERENCES train_dormitory_info (dorm_id) ON DELETE NO ACTION
);
CREATE TABLE train_class_report (
report_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
plan_id VARCHAR(32) NOT NULL,
student_id VARCHAR(32) NOT NULL,
report_way SMALLINT,
report_device_sn VARCHAR(64),
report_time TIMESTAMP,
report_status SMALLINT DEFAULT 0,
alloc_dorm_id VARCHAR(32),
alloc_classroom_id VARCHAR(32),
alloc_site_id VARCHAR(32),
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_train_class_report PRIMARY KEY (report_id),
CONSTRAINT uq_classreport_plan_stu UNIQUE (plan_id, student_id),
CONSTRAINT fk_classreport_plan FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION,
CONSTRAINT fk_classreport_stu FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION,
CONSTRAINT fk_classreport_dorm FOREIGN KEY (alloc_dorm_id) REFERENCES train_dormitory_info (dorm_id) ON DELETE NO ACTION,
CONSTRAINT fk_classreport_classroom FOREIGN KEY (alloc_classroom_id) REFERENCES train_classroom_info (class_room_id) ON DELETE NO ACTION,
CONSTRAINT fk_classreport_site FOREIGN KEY (alloc_site_id) REFERENCES train_training_site (site_id) ON DELETE NO ACTION
);
CREATE TABLE train_student_checkin (
checkin_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
plan_id VARCHAR(32) NOT NULL,
c_id VARCHAR(32) NOT NULL,
student_id VARCHAR(32) NOT NULL,
board_id VARCHAR(32),
checkin_way SMALLINT,
checkin_time TIMESTAMP,
checkin_status SMALLINT,
lesson_start_time TIMESTAMP,
lesson_end_time TIMESTAMP,
CONSTRAINT pk_train_student_checkin PRIMARY KEY (checkin_id),
CONSTRAINT uq_checkin_lesson_stu UNIQUE (plan_id, c_id, student_id, lesson_start_time),
CONSTRAINT fk_checkin_plan FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION,
CONSTRAINT fk_checkin_course FOREIGN KEY (c_id) REFERENCES train_course (c_id) ON DELETE NO ACTION,
CONSTRAINT fk_checkin_stu FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION,
CONSTRAINT fk_checkin_board FOREIGN KEY (board_id) REFERENCES train_electronic_board (board_id) ON DELETE NO ACTION
);
CREATE TABLE train_study_duration (
dur_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
student_id VARCHAR(32),
plan_id VARCHAR(32),
c_id VARCHAR(32),
device_type VARCHAR(50),
start_time TIMESTAMP,
end_time TIMESTAMP,
study_seconds INTEGER,
sync_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_train_study_duration PRIMARY KEY (dur_id),
CONSTRAINT fk_studydur_stu FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION,
CONSTRAINT fk_studydur_plan FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION,
CONSTRAINT fk_studydur_course FOREIGN KEY (c_id) REFERENCES train_course (c_id) ON DELETE NO ACTION
);
CREATE TABLE train_student_portrait (
portrait_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
student_id VARCHAR(32) NOT NULL,
plan_id VARCHAR(32) NOT NULL,
total_study_hour NUMERIC(8,2),
avg_score NUMERIC(5,2),
checkin_rate NUMERIC(5,2),
label_tag TEXT,
portrait_content TEXT,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_train_student_portrait PRIMARY KEY (portrait_id),
CONSTRAINT uq_portrait_stu_plan UNIQUE (student_id, plan_id),
CONSTRAINT fk_portrait_stu FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION,
CONSTRAINT fk_portrait_plan FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION
);
-- 步骤 4: 重建 9 个历史触发器
CREATE OR REPLACE TRIGGER trig_train_teacher_modify
BEFORE UPDATE ON train_teacher
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_student_modify
BEFORE UPDATE ON train_student
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_course_modify
BEFORE UPDATE ON train_course
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_classroom_modify
BEFORE UPDATE ON train_classroom_info
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_trainsite_modify
BEFORE UPDATE ON train_training_site
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_board_modify
BEFORE UPDATE ON train_electronic_board
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_dorminfo_modify
BEFORE UPDATE ON train_dormitory_info
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_classplan_modify
BEFORE UPDATE ON train_class_plan
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
CREATE OR REPLACE TRIGGER trig_train_dormauth_modify
BEFORE UPDATE ON train_dorm_auth
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
-- 步骤 5: 从 bak_v1_* 物理快照还原数据
INSERT INTO train_teacher SELECT * FROM bak_v1_train_teacher;
INSERT INTO train_student SELECT * FROM bak_v1_train_student;
INSERT INTO train_course SELECT * FROM bak_v1_train_course;
INSERT INTO train_classroom_info SELECT * FROM bak_v1_train_classroom_info;
INSERT INTO train_training_site SELECT * FROM bak_v1_train_training_site;
INSERT INTO train_class_plan SELECT * FROM bak_v1_train_class_plan;
INSERT INTO train_dormitory_info SELECT * FROM bak_v1_train_dormitory_info;
INSERT INTO train_electronic_board SELECT * FROM bak_v1_train_electronic_board;
INSERT INTO train_dorm_auth SELECT * FROM bak_v1_train_dorm_auth;
INSERT INTO train_class_report SELECT * FROM bak_v1_train_class_report;
INSERT INTO train_student_checkin SELECT * FROM bak_v1_train_student_checkin;
INSERT INTO train_study_duration SELECT * FROM bak_v1_train_study_duration;
INSERT INTO train_student_portrait SELECT * FROM bak_v1_train_student_portrait;
-- 步骤 6: 校验教师唯一数据还原结果
DO $$
DECLARE
v_cnt INT;
BEGIN
SELECT count(*) INTO v_cnt FROM train_teacher;
IF v_cnt <> 1 THEN
RAISE EXCEPTION '>>> [Rollback-FATAL] 教师数据还原失败: 期望 1 行,实际为 % 行', v_cnt;
END IF;
RAISE NOTICE '>>> [Rollback-PASS] 13 张表结构与教师数据已严格依据 Phase 0.5 标准 DDL 恢复完毕。';
END $$;
COMMIT;
@@ -0,0 +1,37 @@
-- ==============================================================================
-- RailwaySystem 数据库 V2 回滚脚本: 003_restore_legacy_score.sql
-- 适用数据库: KingbaseES V009R003C018 (schema: public)
-- 执行目标: 严格基于 000_phase05_exact_schema.sql 结构恢复旧表 train_score_info
-- 事务边界: 全程在显式事务 BEGIN ... COMMIT 中执行
-- 说明: 彻底摒弃 CTAS 伪造结构,严格恢复原字段、默认值、外键与唯一约束
-- ==============================================================================
BEGIN;
DROP TABLE IF EXISTS train_score_info;
-- 步骤 1: 依据 Phase 0.5 原始标准物理 DDL 重建表结构
CREATE TABLE train_score_info (
score_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
plan_id VARCHAR(32),
c_id VARCHAR(32),
student_id VARCHAR(32),
course_score NUMERIC(5,2),
train_score NUMERIC(5,2),
exam_score NUMERIC(5,2),
source_type SMALLINT,
source_system VARCHAR(50),
import_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_train_score_info PRIMARY KEY (score_id),
CONSTRAINT uq_scoreinfo_plan_c_stu UNIQUE (plan_id, c_id, student_id),
CONSTRAINT fk_scoreinfo_plan FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION,
CONSTRAINT fk_scoreinfo_course FOREIGN KEY (c_id) REFERENCES train_course (c_id) ON DELETE NO ACTION,
CONSTRAINT fk_scoreinfo_stu FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION
);
COMMENT ON TABLE train_score_info IS 'Phase 0.5 历史成绩表 (应急回滚精准恢复)';
-- 步骤 2: 从 bak_v1_train_score_info 快照表恢复数据
INSERT INTO train_score_info SELECT * FROM bak_v1_train_score_info;
COMMIT;
+91
View File
@@ -0,0 +1,91 @@
# RailwaySystem 数据库 V2 应急回滚指南 (Round 1 修订版)
> **技术基线**:KingbaseES V009R003C018 (`schema=public`)
> **回滚目标**:安全撤销 V2 数据库结构变更,将数据模型与物理约束 100% 精确还原至 Phase 0.5 历史基线。
---
## 1. 核心架构升级:解耦结构与数据
在 Round 1 审查中,彻底废除了使用 `CREATE TABLE ... AS SELECT * FROM bak_v1_*`(CTAS)推断历史结构的危险方案:
```text
┌─────────────────────────────────────────────────────────┐
│ Phase 0.5 精确物理结构 (表定义/列类型/PK/FK/UNIQUE/触发器) │
│ 来源: rollback/000_phase05_exact_schema.sql │
└───────────────────────────┬─────────────────────────────┘
│ (先精确重建物理表结构)
▼
┌─────────────────────────────────────────────────────────┐
│ Phase 0.5 真实数据 (唯一教师行 + 各表数据) │
│ 来源: 001 备份生成的 bak_v1_* 快照表 │
└───────────────────────────┬─────────────────────────────┘
│ (再通过 INSERT INTO 导入数据)
▼
【Phase 0.5 绝对还原】
```
- **`000_phase05_exact_schema.sql`**:作为唯一的物理结构基准,确保回滚后恢复所有 24 个旧外键、7 组旧业务唯一约束、NOT NULL、DEFAULT、IDENTITY 序列以及 9 个 `update_time` 触发器;
- **`bak_v1_*` 快照表**:仅承担纯粹的“数据暂存”职责。
---
## 2. 回滚脚本执行顺序
若在测试迁移或灰度验证阶段发现重大异常,需按照以下严格顺序执行回滚流水线:
```text
步骤 1: 执行 001_rollback_new_tables.sql
-> 显式解除外键依赖,安全下线并 DROP 掉 V2 新增的 8 张业务表
步骤 2: 执行 002_rollback_modified_tables.sql
-> 基于 000_phase05_exact_schema.sql 的精确结构重建 13 张表,并从 bak_v1_* 物理快照还原数据,严格断言教师数据为 1 行
步骤 3: 执行 003_restore_legacy_score.sql
-> 基于 000_phase05_exact_schema.sql 的精确结构重建 train_score_info 及 3 个历史外键与唯一约束
步骤 4: 人工核验 Phase 0.5 状态
-> 执行 000_preflight.sql 校验基线恢复,确认 14 张表、触发器与约束 100% 吻合
```
---
## 3. 强前置依赖与数据来源声明
> [!CAUTION]
> **回滚操作必须满足以下前置条件:**
1. **依赖 001 备份快照**:
- 步骤 2 与步骤 3 的数据还原依赖迁移前由 `001_backup_current_schema.sql` 生成的 `bak_v1_*` 快照表。
- 若 `bak_v1_*` 表意外被删,**严禁盲目执行数据还原语句**。
2. **唯一教师数据的物理还原**:
- 教师主档 `train_teacher` 的数据通过 `INSERT INTO train_teacher SELECT * FROM bak_v1_train_teacher;` 完整回灌。回滚脚本会严格校验恢复后的教师行数必须等于 1。
3. **事务安全性**:
- 每一个回滚 SQL 文件内部均由显式 `BEGIN ... COMMIT` 包裹,出现任何错误自动整单回滚,不产生中间半回滚状态。
---
## 4. 必须人工介入确认的场景
### 场景 A:V2 阶段已产生新业务数据
如果系统在执行 V2 DDL 之后,业务端或测试端已经在 `train_enrollment`、`train_lesson`、`train_student_score` 等表中写入了新数据:
- **直接执行回滚将导致这些新业务数据彻底物理清除!**
- **必须人工介入**:先通过数据导出工具将 V2 新增业务数据导出为 CSV/JSON 归档,确认业务无异议后方可执行回滚。
### 场景 B:bak_v1_* 备份表意外缺失
若 `bak_v1_*` 表不存在:
- 必须暂停脚本执行;
- 从数据库物理备份集(如 `sys_backup` / 逻辑转储快照)中恢复 14 张旧表数据。
---
## 5. 回滚后验收确认 Checklist
回滚完成后,在数据库客户端中直接运行 `000_preflight.sql` 即可自动化完成全量反向验收:
- [ ] 1. 运行 `000_preflight.sql` 成功输出 `[Preflight-PASS]`;
- [ ] 2. 确认已无任何 V2 独有表(如 `train_plan_course` 等);
- [ ] 3. 确认旧表 `train_score_info` 已恢复,且具备旧外键;
- [ ] 4. 确认 `train_teacher` 精确包含 1 条数据,且旧字段 `t_department` 存在且非空;
- [ ] 5. 确认 9 个旧触发器全部重新挂载生效;
- [ ] 6. 确认系统表 `sys_*` 完好无损。