93 lines
7.0 KiB
Markdown
93 lines
7.0 KiB
Markdown
# RailwaySystem 数据库 V2 迁移执行契约 (Execution Contract)
|
||
|
||
> **适用范围**:数据库 V2 迁移在测试环境与未来生产环境中的正式执行规范
|
||
> **技术基线**:KingbaseES V009R003C018 (`database=training`, `schema=public`, `database_mode=mysql`)
|
||
> **核心原则**:**双门禁强准入 (Gate A/B)、单文件显式事务、纯 SQL 执行器兼容、失败即刻熔断**
|
||
|
||
---
|
||
|
||
## 1. 执行器与客户端兼容规范
|
||
|
||
为杜绝因客户端专有指令导致的语法中断或解析失败,物理迁移 SQL 已全面实施去客户端化:
|
||
1. **纯标准 SQL 语法**:
|
||
- 彻底移除 `\echo`、`\set`、`DELIMITER` 等特定客户端(如 psql/ksql/mysql)专有元命令;
|
||
- 进度提示统一采用 PL/pgSQL 标准内置机制:`RAISE NOTICE '...'`;
|
||
- 失败阻断统一采用标准异常中断:`RAISE EXCEPTION '...'`。
|
||
2. **多客户端适配兼容性**:
|
||
- 支持通过 Kingbase 原生命令行工具 `ksql` 执行:`ksql -U kingbase -d training -f xxx.sql`;
|
||
- 支持通过通用数据库客户端(如 DBeaver、Navicat、DataGrip)以“执行脚本文件”模式执行;
|
||
- 支持通过自动化运维流水线或 JDBC Runner 顺序执行。
|
||
|
||
---
|
||
|
||
## 2. 迁移编排流水线与事务边界
|
||
|
||
迁移必须严格按照以下阶段顺序串行执行。**任何前置 Gate 失败或 Stage 报错,必须立即停止,绝对禁止跳步骤继续!**
|
||
|
||
```mermaid
|
||
graph TD
|
||
GateA[Gate A: 000_tx_capability_probe.sql] -->|PASS| GateB[Gate B: 000_preflight.sql]
|
||
GateB -->|PASS| S1[Stage 1: 001_backup_current_schema.sql]
|
||
S1 --> S2[Stage 2: 002_create_new_tables.sql]
|
||
S2 --> S3[Stage 3: 003_alter_master_tables.sql]
|
||
S3 --> S4[Stage 4: 004_rebuild_business_tables.sql]
|
||
S4 --> S5[Stage 5: 005_constraints.sql]
|
||
S5 --> S6[Stage 6: 006_indexes.sql]
|
||
S6 -.->|跳过字典初始化| S7[Stage 7: 008_migrate_teacher.sql]
|
||
S7 --> S8[Stage 8: 009_drop_legacy_score.sql]
|
||
S8 --> S9[Stage 9: 010_verify.sql]
|
||
S9 --> Done[迁移完成 交付测试验收]
|
||
```
|
||
|
||
### 详细阶段契约表
|
||
|
||
| 阶段 | 脚本文件 | 事务边界 | 失败处理与影响 |
|
||
| :---: | :--- | :---: | :--- |
|
||
| **Gate A** | [`000_tx_capability_probe.sql`](../../RuoYi-Vue/sql/train/v2/000_tx_capability_probe.sql) | 探针显式事务 | **强阻断**:实证探测实例 DDL 回滚能力。若表残留立即抛出异常并中止,严禁进入后续阶段 |
|
||
| **Gate B** | [`000_preflight.sql`](../../RuoYi-Vue/sql/train/v2/000_preflight.sql) | 纯只读骨架断言 | **强阻断**:集合差集校验 14旧表PK、24旧表FK、7组UNIQUE、6个identity主键、9触发器与行数基线,任何不符立即中止 |
|
||
| **Stage 1** | [`001_backup_current_schema.sql`](../../RuoYi-Vue/sql/train/v2/001_backup_current_schema.sql) | `BEGIN ... COMMIT` | **强阻断**:全量快照 14 张表至 `bak_v1_*`;若已存在备份表则阻断;失败全单回滚 |
|
||
| **Stage 2** | [`002_create_new_tables.sql`](../../RuoYi-Vue/sql/train/v2/002_create_new_tables.sql) | `BEGIN ... COMMIT` | 创建 V2 新增 8 张表;严禁 `IF NOT EXISTS`;失败事务回滚,新表全部撤销 |
|
||
| **Stage 3** | [`003_alter_master_tables.sql`](../../RuoYi-Vue/sql/train/v2/003_alter_master_tables.sql) | `BEGIN ... COMMIT` | 调整 8 张主数据表;移除旧触发器与阻断外键,添加 V2 新列;失败事务回滚 |
|
||
| **Stage 4** | [`004_rebuild_business_tables.sql`](../../RuoYi-Vue/sql/train/v2/004_rebuild_business_tables.sql) | `BEGIN ... COMMIT` | 断言 0 行后重构 5 张业务表;失败事务回滚,原表结构保持不变 |
|
||
| **Stage 5** | [`005_constraints.sql`](../../RuoYi-Vue/sql/train/v2/005_constraints.sql) | `BEGIN ... COMMIT` | 集中注入 13 组 UNIQUE、26 组 FK (NO ACTION)、9 组 CHECK;失败事务回滚 |
|
||
| **Stage 6** | [`006_indexes.sql`](../../RuoYi-Vue/sql/train/v2/006_indexes.sql) | `BEGIN ... COMMIT` | 创建外键索引、排课多维复合索引及双非空部分唯一索引;失败事务回滚 |
|
||
| **-** | [`007_dicts.sql`](../../RuoYi-Vue/sql/train/v2/007_dicts.sql) | - | **【本迁移流水线跳过不执行】** 业务字典留待应用接口及权限配置阶段接入 |
|
||
| **Stage 7** | [`008_migrate_teacher.sql`](../../RuoYi-Vue/sql/train/v2/008_migrate_teacher.sql) | `BEGIN ... COMMIT` | 迁移并断言教师 1 行数据,固化 NOT NULL,安全清理旧列;失败事务回滚 |
|
||
| **Stage 8** | [`009_drop_legacy_score.sql`](../../RuoYi-Vue/sql/train/v2/009_drop_legacy_score.sql) | `BEGIN ... COMMIT` | 断言 0 行后下线旧表 `train_score_info`;失败事务回滚,旧表完好保留 |
|
||
| **Stage 9** | [`010_verify.sql`](../../RuoYi-Vue/sql/train/v2/010_verify.sql) | 纯只读深度断言 | **强阻断**:定义级全量验收 21 表、UNIQUE 列清单、FK NO ACTION、CHECK 表达式、12 Identity、默认值及系统表零受损 |
|
||
|
||
---
|
||
|
||
## 3. 已冻结的核心架构决策 (技术负责人正式拍板)
|
||
|
||
在数据库 V2 迁移及后续业务开发中,以下两项设计原则已作为**已冻结架构决策**执行:
|
||
|
||
### 决策 A:排课与住宿并发控制
|
||
- **决策结论**:一期**绝不引入**外部排课引擎或复杂时间区间调度框架。
|
||
- **技术实现**:
|
||
1. 数据库层面配置针对性复合检索索引(`idx_lesson_teacher_time`, `idx_lesson_classroom_time`, `idx_lesson_site_time`);
|
||
2. 业务层面由排课与住宿分配 Service 在单个本地事务内执行区间交叉检索;
|
||
3. 必要时使用 `SELECT ... FOR UPDATE` 悲观锁锁定宿位或教师日历,保障并发一致性。
|
||
|
||
### 决策 B:跨培训班核心业务一致性 (防串班)
|
||
- **决策结论**:**绝不**为了防止串班而在考勤、成绩、自主学习时长等细粒度业务表冗余增加 `plan_id` 反范式列,严格保持数据库 V2 的 3NF 规范化设计。
|
||
- **技术实现**:
|
||
由应用层业务 Service 在写入和处理业务时强制校验一致性链条:
|
||
- `checkin.enrollment.plan_id = lesson.plan_course.plan_id` (考勤打卡班级一致)
|
||
- `student_score.enrollment.plan_id = score_item.plan_id` (成绩录入班级一致)
|
||
- 当 `score_item.plan_course_id IS NOT NULL` 时,`score_item.plan_id = plan_course.plan_id`
|
||
- `study_duration.enrollment.plan_id = plan_course.plan_id` (学习记录班级一致)
|
||
任何不一致均由 Service 抛出业务异常阻断入库。
|
||
|
||
---
|
||
|
||
## 4. 失败处理与应急回滚规范
|
||
|
||
1. **单点失败即刻熔断**:
|
||
- 若流水线中任何一个脚本执行报错,**严禁跳过该步骤继续执行后续脚本**!
|
||
- 单文件具备 `BEGIN ... COMMIT`,当前失败脚本的所有物理改动会自动回滚撤销。
|
||
2. **应急回滚调用准则**:
|
||
- 若在 Stage 2 ~ Stage 8 中途发生不可调和的异常,必须立即暂停,并由 DBA 评估调用 [`rollback/`](../../RuoYi-Vue/sql/train/v2/rollback/) 脚本;
|
||
- 回滚流水线严格按照:`001_rollback_new_tables.sql` -> `002_rollback_modified_tables.sql` -> `003_restore_legacy_score.sql` 倒序执行;
|
||
- 回滚完毕后,必须运行 `000_preflight.sql` 校验是否完全恢复至 Phase 0.5 精确基线。
|