refactor(flight-schd): 按现场 11g 约束将运营航班存储改为宽表 (ACM2-28 修订)

现场环境仅提供 Oracle 11g(无任何 JSON 能力),废除 FLTR_JSON JSONB 整文档存储:

- V1.1.0 迁移重写:FLIGHT_SCHD 改为一行一航班宽表(SCHD.FLTR 标量字段列 +
  1:N 明细集合序列化文本列),SCHD_GEN.FLIDS_JSON 展开为 SCHD_GEN_FLID(FDAY, FLID);
  已应用过旧版迁移的环境需重建 schema 重放
- 契约层:FlightChange/Handler 在线视图改为字段集映射(与 legacy flightInfo
  hash 同构),仓储白名单拒绝未知字段;增量写=字段级合并(hmset 同语义),
  快照=整体替换
- 事件载荷:快照投递与投影重建经 FlightFieldsJson 确定性序列化(键序稳定)
- 影子对拍:FlightStoreDiffTool 改为 PG 宽表列值 vs legacy FLTR JSON 逐字段
  归一化比对,新增嵌套集合比对用例
- 测试:61 用例全绿(不变量门槛 1/2/3、UTC 方言、真实 PG 方言集成、清场五场景)
- 文档:decision-flight-state.md 追加 §8 修订记录(不改写定案历史),design.md 表说明同步

11g 方言移植(ON CONFLICT→MERGE、advisory lock 替代、Flyway/驱动矩阵)、
集合列升子表、类型化列提升等未尽事项另立 Plane issue 跟踪。
This commit is contained in:
windyboy
2026-09-07 17:04:57 +08:00
parent 7b7b61f100
commit ff6cec08c8
19 changed files with 556 additions and 234 deletions
@@ -1,32 +1,115 @@
-- =====================================================================
-- 自有 PostgreSQL 库 · 阶段 A 运营航班表与计划代迁移 · ACM2-28 定案(选项 C)
-- 自有库 · 阶段 A 运营航班表与计划代迁移 · ACM2-28 定案(选项 C)· 11g 修订
-- ---------------------------------------------------------------------
-- 存储边界(ACM2-28 定案,取代 ACM2-12「FLIGHT_STATE 缓做不落表、Redis 永续权威」口径):
-- · FLIGHT_SCHDSCHD 日计划快照 + FLOP/ADFT 增量合并后的当前运营航班权威态,落自有 PG
-- · SCHD_GEN:各日代版本与当前代航班全量集合(差删依据),由 Redis 回归自有 PG
-- · Redis:彻底退出动态权威与全部写路径;阶段 A 读写事务全在自有 PG 原子完成。
-- · FLIGHT_SCHDSCHD 日计划快照 + FLOP/ADFT 增量合并后的当前运营航班权威态,一行一航班
-- · SCHD_GEN / SCHD_GEN_FLID:各日代版本(SQL CAS)与当前代航班全量集合(差删依据)
-- · Redis:彻底退出动态权威与全部写路径;阶段 A 读写事务全在自有原子完成。
-- · 增量 Upsert 语义:
-- - 快照全量写入(DNLD):声明/更新 FDAY 归属,更新 FLTR_JSON
-- - 增量写入(FLOP/ADFT):新插置 NULL,已有行通过 ON CONFLICT 保留原 FDAY
-- - 按代差删域化:DELETE FROM FLIGHT_SCHD WHERE FDAY = :day AND FLID = ANY(:diffSet)
-- - 快照全量写入(DNLD):声明/更新 FDAY 归属,航班字段整体替换
-- - 增量写入(FLOP/ADFT):新插置 NULL FDAY,已有行保留原 FDAY,按字段列更新
-- (与 legacy flightInfo hash「仅新增/覆盖 field」同语义);
-- - 按代差删域化:DELETE FROM FLIGHT_SCHD WHERE FDAY = :day AND FLID IN (:diffSet)
-- 仅删除仍属旧代的行,ADFT(FDAY=NULL)与已迁移至新代的同 FLID 行天然存活。
-- · 时间列规范:统一使用 TIMESTAMP(6) WITH TIME ZONE (TIMESTAMPTZ)
-- · 时间列规范:统一使用 TIMESTAMP(6) WITH TIME ZONE。
-- ---------------------------------------------------------------------
-- 11g 修订(现场数据库版本 11g,废除 FLTR_JSON JSONB 整文档存储):
-- · 表形态 = 运营航班宽表:一行一航班,字段即列,天然可索引、可直查、可加约束;
-- · 列清单锚定 legacy SIS 契约(unisysaodbsis.xsd SCHD.FLTR 记录,ACMA-4 基线,
-- 32 个 Handler 的 KEEP/FIX 翻译即以此为闭集):
-- - 标量字段 → 真实列(约 45 列 + legacy 派生列 ABDG/LPSDT/ABN);
-- - 1:N 明细集合(登机口/柜台/转盘/桥/延误/航线等,单航班可达 99 条)各占一列
-- 存序列化文本(TEXT;11g 移植为 CLOB),阶段 2/3 语义钉死后按需升独立子表;
-- · 值语义保持 legacy 字符串原样(不做库端类型转换),保证影子对拍逐字段保真;
-- 范围查询需要的类型化列(如 SODT→DATE)按查询需求逐列后置提升。
-- =====================================================================
-- ① 运营航班表(当前运营航班动态权威,FLID 与 legacy flightInfo 同键)
-- ① 运营航班表(当前运营航班动态权威,FLID 与 legacy flightInfo 同键;一行一航班
CREATE TABLE FLIGHT_SCHD (
FLID VARCHAR(32) NOT NULL PRIMARY KEY, -- AODB 唯一航班标识
FDAY DATE NULL, -- 所属日计划代;NULL = 非代所有(ADFT/增量增建)
FLTR_JSON JSONB NOT NULL, -- 航班全量记录(与 legacy flightInfo value 同构)
CREATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL
FLID VARCHAR(32) NOT NULL PRIMARY KEY, -- AODB 唯一航班标识
FDAY DATE NULL, -- 所属日计划代;NULL = 非代所有(ADFT/增量增建)
-- ==== SCHD.FLTR 标量字段(unisysaodbsis.xsd,值保持 legacy 字符串原样)====
ALCD VARCHAR(64) NULL, -- 航空公司代码
ALSC VARCHAR(64) NULL, -- 航空公司简称
FLNO VARCHAR(64) NULL, -- 航班号
MVIN VARCHAR(64) NULL, -- 进离港标识(A=到港 D=离港)
SODT VARCHAR(64) NULL, -- 计划时间(ddMMMyyHHmm
FLTY VARCHAR(64) NULL, -- 航班类型
FLIN VARCHAR(64) NULL, -- 国内/国际/混合属性
ACFT VARCHAR(64) NULL, -- 机型
RENO VARCHAR(64) NULL, -- 机尾号
TAOP VARCHAR(64) NULL, -- 实际承运人代码
TAFL VARCHAR(64) NULL, -- 实际承运航班号
TAID VARCHAR(64) NULL, -- 实际承运航班 FLID
TRML VARCHAR(64) NULL, -- 航站楼
MAXP VARCHAR(64) NULL, -- 最大旅客数
CSOP VARCHAR(64) NULL, -- 共享承运人代码
CSFT VARCHAR(64) NULL, -- 共享航班号
MAID VARCHAR(32) NULL, -- 共享主航班 FLID
ESTT VARCHAR(64) NULL, -- 预计时间
ACTT VARCHAR(64) NULL, -- 实际时间
STND VARCHAR(64) NULL, -- 备降站
PHAG VARCHAR(64) NULL, -- 地服代理(值机)
CNCL VARCHAR(64) NULL, -- 取消时间
REMC VARCHAR(80) NULL, -- 备注
BOTM VARCHAR(64) NULL, -- 摆渡车时间
LACL VARCHAR(64) NULL, -- 行李确认时间
FINT VARCHAR(64) NULL, -- 完成时间
APPT VARCHAR(64) NULL, -- 旅客到达时间
EGSR VARCHAR(64) NULL, -- 保障开始时间
EGST VARCHAR(64) NULL, -- 保障结束时间
FHAG VARCHAR(64) NULL, -- 地服代理(货运)
MHAG VARCHAR(64) NULL, -- 地服代理(机务)
VIPP VARCHAR(64) NULL, -- VIP 旅客数
VIPR VARCHAR(64) NULL, -- VIP 等级
LBNO VARCHAR(64) NULL, -- 行李件数
LBWT VARCHAR(64) NULL, -- 行李重量
PAXC VARCHAR(64) NULL, -- 旅客计数
EXSC VARCHAR(64) NULL, -- 例外代码
EXSR VARCHAR(256) NULL, -- 例外原因
FTSS VARCHAR(64) NULL, -- 航班状态
PEDT VARCHAR(64) NULL, -- 前序估计时间
NEAT VARCHAR(64) NULL, -- 下机完成时间
PADT VARCHAR(64) NULL, -- 旅客登机时间
NAAT VARCHAR(64) NULL, -- 关门时间
-- ==== legacy flightInfo 派生标量字段(user-stories §SCHD.FLTR====
ABDG VARCHAR(64) NULL, -- 当前登机桥(派生)
LPSDT VARCHAR(64) NULL, -- 历史计划机位(派生)
ABN VARCHAR(64) NULL, -- 异常标识(派生)
-- ==== 1:N 明细集合(序列化文本,一列一集合;阶段 2/3 按需升独立子表)====
ROUT_TXT TEXT NULL, -- 航线(ROUTEDAILY ×6
ERUT_TXT TEXT NULL, -- 扩展航线(ROUTEDAILY ×2..7
CHDT_TXT TEXT NULL, -- 廊桥/ chute 数据(×99
GTDT_TXT TEXT NULL, -- 登机口(×99
PSDT_TXT TEXT NULL, -- 机位(×9
CKDT_TXT TEXT NULL, -- 值机柜台(×99
CLDT_TXT TEXT NULL, -- 行李转盘(×99
DELY_TXT TEXT NULL, -- 延误(不限)
CHOT_TXT TEXT NULL, -- 客桥桥载(×99
ABTM_TXT TEXT NULL, -- 登机桥(×99
SRVT_TXT TEXT NULL, -- 服务(不限)
VIPF_TXT TEXT NULL, -- VIP(不限)
MAFL_TXT TEXT NULL, -- 共享航班列表(legacy 派生集合)
FDIV_TXT TEXT NULL, -- 备降明细
FRET_TXT TEXT NULL, -- 返航明细
FLAB_TXT TEXT NULL, -- 中止明细
CREATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL,
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL
);
CREATE INDEX idx_flight_schd_fday ON FLIGHT_SCHD (FDAY); -- 日代扫描与影子对拍分片
-- 运营查询索引按需逐列追加(11g/PG 均为普通 B-tree,零方言成本)
-- ② 日计划代与差删元数据表(代版本推进与版本 CAS)
CREATE TABLE SCHD_GEN (
FDAY DATE NOT NULL PRIMARY KEY, -- 计划日(yyyy-MM-dd
VERSION BIGINT NOT NULL, -- 代版本号(单调递增)
FLIDS_JSON JSONB NOT NULL, -- 当前代有效航班 FLID 集合
UPDATED_AT TIMESTAMP(6) WITH TIME ZONE NOT NULL
);
-- ③ 当前代有效航班 FLID 集合(差删依据)
CREATE TABLE SCHD_GEN_FLID (
FDAY DATE NOT NULL, -- 所属计划日(FK 级联删除)
FLID VARCHAR(32) NOT NULL, -- 当前代有效航班
CONSTRAINT pk_schd_gen_flid PRIMARY KEY (FDAY, FLID),
CONSTRAINT fk_schd_gen_flid FOREIGN KEY (FDAY) REFERENCES SCHD_GEN (FDAY) ON DELETE CASCADE
);