-- ============================================================================ -- 1.0.529 · S5 IQC Inspection Detail · Batch 1 Persistence Foundation -- -- 用途:为后续 IQC item-level inspection 建立持久化基础(两张 Ai-DOP 自有运行表)。 -- 本批只建结构,不写任何数据、不接任何代码路径。 -- ⇒ 应用本脚本后系统业务行为与应用前完全一致,只是多了两张空表。 -- -- 后续批次:Batch 2 生成时写入检规快照 / Batch 3 录入项目结果 / Batch 4 详情 UI。 -- -- ── 红线(本脚本自我约束)──────────────────────────────────────────────────── -- · 只 CREATE TABLE IF NOT EXISTS 两张 ado_s5_* 新表 -- · 零 ALTER / 零 DROP / 零 INSERT / 零 UPDATE / 零 DELETE -- · 不触碰 qms_jygf / qms_jygfzb / qms_qcp_inspbill / qms_qcp_insappnentry -- —— 尤其【不新增 qms_jygfzb.lrlx】:qms_* 属源/贴源体系(热回读 INSERT + -- MdpDbPushExecutor 回写白名单),非 Ai-DOP 可扩展 Schema -- · 不建 FOREIGN KEY(实测 204 张 ado_* 表 FK 数 = 0,符合仓库惯例) -- · 不注册 mdp_entity / 不建 mdp_stg / mdp_std / 不改 HotWatch / PushExecutor -- -- ── 数据归属 ──────────────────────────────────────────────────────────────── -- 两张表 = S5 Operational Truth,仅 S5 IQC 模块运行期代码可直接事务读写。 -- 跨模块消费者(S6/S7/S8/S9/看板/KPI/统计/对外供数)一律禁止直接 SELECT/JOIN, -- 必须走 ado_s5_iqc_* → mdp_entity → MDP staging/standard → consumer。 -- -- ── 租户隔离(四层,硬原则)────────────────────────────────────────────────── -- ① tenant_id NOT NULL -- ② 所有业务 UK / secondary index 首列 = tenant_id(PRIMARY KEY(id) 为物理主键例外) -- ③ valid-tenant CHECK:沿用仓库既有范式(全库 21 条 CHECK 中 18 条同形) -- tenant_id IS NOT NULL AND tenant_id NOT IN (0,1,1300000000001) -- 1300000000001 = AdoS0TenantScope.cs:18 MainTenantId(超管未选目标租户的主租户) -- ④ 未来所有读写 SQL 必须显式带 tenant_id 谓词(本批无 C# 代码,仅为其备好边界) -- -- ── 单一真源(measurement truth)──────────────────────────────────────────── -- result_type='NUMERIC' → 真源 = ado_s5_iqc_insp_bill_item_sample 行集 -- item.qualified_qty / unqualified_qty 必须为 NULL -- (由 ck_s5_iqc_item_truth 在 DB 层强制) -- result_type='NON_NUMERIC' → 真源 = item.qualified_qty / unqualified_qty -- 该 item 不得有 sample 行 -- (跨表约束,DB CHECK 无法表达;本批【不引入 trigger】, -- 由 Batch 3 的 save-detail 强制 + 巡检 SQL 兜底) -- result_type IS NULL → 不允许记录任何测量事实 -- -- ── 列宽依据(实测 qms_jygfzb,36686 行)──────────────────────────────────── -- jyxm max 242 / jybz max 363 / jygjjyff max 538 / txfl max 255 -- cyfa max 63 / zs max 247 / sx,xx max 7 / xh ∈ [1,91] 且 9 行为 NULL -- ★ method_tool 必须 VARCHAR(1000):源 jygjjyff 已有 1 条真实记录 538 字符, -- 缩为 VARCHAR(500) 会截断(禁止擅自缩短) -- 行宽按 utf8mb4 声明上限估算 ≈ 18.7KB,远低于 65535 ⇒ 无需任何字符集降级 -- ============================================================================ -- ============ ① IQC 检验单项目实例(检规快照 + 项目级结果)============ CREATE TABLE IF NOT EXISTS ado_s5_iqc_insp_bill_item ( id BIGINT NOT NULL AUTO_INCREMENT, tenant_id BIGINT NOT NULL COMMENT '租户ID(隔离域,所有读写必带)', inspection_bill_id BIGINT NOT NULL COMMENT '所属检验单 qms_qcp_inspbill.id(唯一关联键,不冗余单号)', seq INT NULL COMMENT '展示序号,快照自 qms_jygfzb.xh(可空可重复,不作键)', source_spec_id BIGINT NOT NULL COMMENT '来源检规 qms_jygf.id —— 仅 lineage 追溯,允许未来悬挂', source_spec_item_id BIGINT NOT NULL COMMENT '来源检规明细 qms_jygfzb.id —— 仅 lineage 追溯,允许未来悬挂', -- ── Specification Snapshot:Batch 2 生成时一次写入,之后 IMMUTABLE ── inspection_item VARCHAR(500) NULL COMMENT '快照 qms_jygfzb.jyxm 检验项目(实测 max 242)', inspection_standard VARCHAR(1000) NULL COMMENT '快照 qms_jygfzb.jybz 检验标准(实测 max 363;公差常内嵌于此)', method_tool VARCHAR(1000) NULL COMMENT '快照 qms_jygfzb.jygjjyff 检验工具/方法(实测 max 538 ⇒ 必须 1000,禁缩为 500)', image_category VARCHAR(500) NULL COMMENT '快照 qms_jygfzb.txfl 图像分类(实测 max 255)', sampling_scheme VARCHAR(500) NULL COMMENT '快照 qms_jygfzb.cyfa 抽样方案(实测 max 63)', spec_remark VARCHAR(500) NULL COMMENT '快照 qms_jygfzb.zs 检规注释(实测 max 247)—— 区别于 result_remark', upper_limit VARCHAR(50) NULL COMMENT '快照 qms_jygfzb.sx 上限(原样文本,不解析)', lower_limit VARCHAR(50) NULL COMMENT '快照 qms_jygfzb.xx 下限(原样文本,不解析)', -- ── Result Contract:运行期事实,仅 N1 态可写(Batch 3) ── result_type VARCHAR(20) NULL COMMENT '录入类型 NUMERIC/NON_NUMERIC。★非快照★ 不来自检规;N1 首次录入时选定,N1 态可改但须清空本项目测量事实。NULL=未定(合法初态)', qualified_qty DECIMAL(18,6) NULL COMMENT '【NON_NUMERIC 唯一真源】合格数;NUMERIC 时必须为 NULL', unqualified_qty DECIMAL(18,6) NULL COMMENT '【NON_NUMERIC 唯一真源】不合格数;NUMERIC 时必须为 NULL', item_judgement VARCHAR(16) NULL COMMENT '项目判定 PASS/FAIL/INVALID;NULL=未录。派生值,后端唯一写入方(已删除 PENDING 枚举)', judgement_source VARCHAR(8) NULL COMMENT 'AUTO=由真源实时重算 / MANUAL=检验员显式结论;测量事实一旦变更即强制复位为 AUTO', result_remark VARCHAR(500) NULL COMMENT '项目级结果备注(≠ spec_remark)', last_result_by BIGINT NULL COMMENT '最后录入人 SysUser.Id', last_result_at DATETIME NULL COMMENT '最后录入时间', -- ── Audit:与同类 raw-DDL 表(ado_s6_process_inspection_*)一致,不加 create_user/is_deleted ── create_time DATETIME NULL DEFAULT CURRENT_TIMESTAMP, update_time DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_s5_iqc_item_scope (tenant_id, inspection_bill_id, source_spec_item_id), KEY idx_s5_iqc_item_src (tenant_id, source_spec_id), CONSTRAINT ck_s5_iqc_item_tenant CHECK ( tenant_id IS NOT NULL AND tenant_id NOT IN (0, 1, 1300000000001) ), CONSTRAINT ck_s5_iqc_item_result_type CHECK ( result_type IS NULL OR result_type IN ('NUMERIC', 'NON_NUMERIC') ), -- 单一真源:NUMERIC 分支不得携带计数(其真源在 sample 表)。 -- NULL 分支显式声明放行,不依赖 MySQL「CHECK 求值为 NULL 视为满足」的隐式行为。 CONSTRAINT ck_s5_iqc_item_truth CHECK ( result_type IS NULL OR result_type <> 'NUMERIC' OR (qualified_qty IS NULL AND unqualified_qty IS NULL) ), CONSTRAINT ck_s5_iqc_item_judgement CHECK ( item_judgement IS NULL OR item_judgement IN ('PASS', 'FAIL', 'INVALID') ), CONSTRAINT ck_s5_iqc_item_jsrc CHECK ( judgement_source IS NULL OR judgement_source IN ('AUTO', 'MANUAL') ) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='S5 IQC检验单项目实例(检规快照+项目级结果)。S5 Operational Truth;跨模块消费须经 MDP,禁止直接 JOIN'; -- ============ ② IQC 检验单项目实测值(逐样本,仅 NUMERIC 使用)============ CREATE TABLE IF NOT EXISTS ado_s5_iqc_insp_bill_item_sample ( id BIGINT NOT NULL AUTO_INCREMENT, tenant_id BIGINT NOT NULL COMMENT '租户ID(隔离域,所有读写必带)', inspection_bill_id BIGINT NOT NULL COMMENT '反规范化:支持按单一次取全部样本免 JOIN', item_id BIGINT NOT NULL COMMENT '所属项目 ado_s5_iqc_insp_bill_item.id', sample_index INT NOT NULL COMMENT '样本序号 1..N(无硬上限,不用 j1..j50 定长列)', sample_value_raw VARCHAR(200) NOT NULL COMMENT '【NUMERIC 唯一真源】检验员录入原文,原样保留(供 INVALID 复盘)。空值语义=该样本不存在⇒删行,不存空串', sample_numeric DECIMAL(18,6) NULL COMMENT '后端解析值;不可解析=NULL(不丢原文)', judgement VARCHAR(16) NULL COMMENT 'PASS/FAIL/INVALID;后端唯一写入方,前端传值一律忽略', remark VARCHAR(500) NULL COMMENT '样本级备注', inspector_id BIGINT NULL COMMENT '样本级录入人 SysUser.Id', inspection_time DATETIME NULL COMMENT '样本级录入时刻', create_time DATETIME NULL DEFAULT CURRENT_TIMESTAMP, update_time DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_s5_iqc_sample_scope (tenant_id, item_id, sample_index), KEY idx_s5_iqc_sample_bill (tenant_id, inspection_bill_id), CONSTRAINT ck_s5_iqc_sample_tenant CHECK ( tenant_id IS NOT NULL AND tenant_id NOT IN (0, 1, 1300000000001) ), CONSTRAINT ck_s5_iqc_sample_index CHECK ( sample_index >= 1 ), CONSTRAINT ck_s5_iqc_sample_judgement CHECK ( judgement IS NULL OR judgement IN ('PASS', 'FAIL', 'INVALID') ) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='S5 IQC检验单项目实测值(逐样本,仅NUMERIC)。S5 Operational Truth;跨模块消费须经 MDP,禁止直接 JOIN';