1.0.529.sql 11 KB

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