1.0.513.sql 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. -- =====================================================================================
  2. -- WIP-C3B · S0 · C3-B 物料桥:ProductStructureMaster / ItemSubstituteDetail
  3. -- (占位名,提交那刻 rename 为正式 1.0.<next>.sql)
  4. --
  5. -- ProductStructureMaster → mdp_stg_s0_item_bom → bridge_item_bom
  6. -- ItemSubstituteDetail → mdp_stg_s0_item_substitute → bridge_item_substitute
  7. --
  8. -- 🔴🔴 legacy 代理键跨租户实证(2026-09-08):
  9. -- ComponentMaterialId → ItemMaster.RecID 同租户失败 170 / 忽略租户失败 0
  10. -- ParentMaterialId → ItemMaster.RecID 同租户失败 2060 / 忽略租户失败 0
  11. -- 那 170 行恰恰全部挂到**别的租户**的 RecID 上 —— 去掉租户条件不报错,只会静默串租户。
  12. -- 同租户可解析的 61866 行里,代理键解出的码与 ComponentItem 61866/61866 完全一致
  13. -- ⇒ 自然键完全可靠。本批一律走自然键,两个 id 仅作技术属性留痕。
  14. -- =====================================================================================
  15. CREATE TABLE IF NOT EXISTS `mdp_stg_s0_item_bom` (
  16. `id` bigint NOT NULL AUTO_INCREMENT,
  17. `tenant_id` bigint NOT NULL DEFAULT 0,
  18. `factory_id` bigint DEFAULT NULL,
  19. `source_system` varchar(50) NOT NULL DEFAULT 'AIDOPDEV_MYSQL',
  20. `source_table` varchar(100) NOT NULL,
  21. `source_row_id` varchar(100) NOT NULL,
  22. `source_biz_key` varchar(300) DEFAULT NULL,
  23. `sync_batch_id` varchar(100) NOT NULL,
  24. `sync_time` datetime NOT NULL,
  25. `process_status` varchar(20) NOT NULL DEFAULT 'PENDING',
  26. `raw_data` json NOT NULL,
  27. `process_message` varchar(500) DEFAULT NULL,
  28. `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  29. `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  30. PRIMARY KEY (`id`),
  31. UNIQUE KEY `uk_stg_s0_item_bom` (`tenant_id`,`source_system`,`source_table`,`source_row_id`),
  32. KEY `idx_stg_s0_item_bom_biz` (`source_biz_key`),
  33. KEY `idx_stg_s0_item_bom_batch` (`tenant_id`,`sync_batch_id`)
  34. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='S0 贴源:BOM 结构(源 ProductStructureMaster)';
  35. CREATE TABLE IF NOT EXISTS `bridge_item_bom` (
  36. `id` bigint NOT NULL AUTO_INCREMENT,
  37. `tenant_id` bigint NOT NULL,
  38. `item_code` varchar(50) NOT NULL COMMENT '业务键 + 父键 ← $.ParentItem(BOM 父件);父 = dim_item.item_code(实测孤儿 0/62036)',
  39. `component_item_code` varchar(50) NOT NULL COMMENT '业务键 ← $.ComponentItem(子件);对 dim_item 同样零孤儿,但框架单父故不设父',
  40. `qty` decimal(18,5) DEFAULT NULL COMMENT '← $.Qty',
  41. `unit` varchar(50) DEFAULT NULL COMMENT '← $.UM',
  42. `scrap` decimal(18,5) DEFAULT NULL COMMENT '← $.Scrap',
  43. `qty_consumed` decimal(18,5) DEFAULT NULL COMMENT '← $.QtyConsumed',
  44. `qty_exchanged` decimal(18,5) DEFAULT NULL COMMENT '← $.QtyExchd',
  45. `refs` varchar(200) DEFAULT NULL COMMENT '← $.Refs',
  46. `operation_no` int DEFAULT NULL COMMENT '← $.Op',
  47. `company_id` bigint NOT NULL COMMENT 'LEGACY_SCOPE ← $.CompanyRefId',
  48. `factory_id` bigint NOT NULL COMMENT 'LEGACY_SCOPE ← $.FactoryRefId',
  49. `legacy_parent_item_id` bigint NOT NULL COMMENT '🔴 技术属性 ← $.ParentMaterialId。解析 → ItemMaster.RecID 时**必须带 tenant_id**:忽略租户会 0 失败但静默串租户(同租户失败 2060 行)',
  50. `legacy_component_item_id` bigint NOT NULL COMMENT '🔴 技术属性 ← $.ComponentMaterialId。同上:忽略租户 0 失败,而那 170 行恰恰全挂到别的租户',
  51. `source_system` varchar(50) NOT NULL,
  52. `source_biz_key` varchar(300) NOT NULL,
  53. `source_updated_at` datetime DEFAULT NULL COMMENT '← $.UpdatedAt(源仅 4/62036,保留系框架约定槽位)',
  54. `sync_batch_id` varchar(64) NOT NULL,
  55. `sync_time` datetime NOT NULL,
  56. `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  57. `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  58. PRIMARY KEY (`id`),
  59. -- 索引字节 = 8 + 50*4 + 50*4 = 408 < 3072
  60. UNIQUE KEY `uk_bridge_item_bom` (`tenant_id`,`item_code`,`component_item_code`),
  61. KEY `idx_bib_parent` (`tenant_id`,`item_code`),
  62. KEY `idx_bib_component` (`tenant_id`,`component_item_code`),
  63. KEY `idx_bib_batch` (`sync_batch_id`)
  64. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
  65. COMMENT='S0 关系桥:BOM 结构。源 ProductStructureMaster,FULL REPLACE。父 = dim_item(自然键 item_code)。IsActive 是 bit(1) 且含 1 行 NULL,双重地雷故不物化;IsEnabled/SequenceNum/StructureType distinct=1、LineOp/Remark/StartEff/EndEff 全空,一并不物化。';
  66. CREATE TABLE IF NOT EXISTS `mdp_stg_s0_item_substitute` (
  67. `id` bigint NOT NULL AUTO_INCREMENT,
  68. `tenant_id` bigint NOT NULL DEFAULT 0,
  69. `factory_id` bigint DEFAULT NULL,
  70. `source_system` varchar(50) NOT NULL DEFAULT 'AIDOPDEV_MYSQL',
  71. `source_table` varchar(100) NOT NULL,
  72. `source_row_id` varchar(100) NOT NULL,
  73. `source_biz_key` varchar(300) DEFAULT NULL,
  74. `sync_batch_id` varchar(100) NOT NULL,
  75. `sync_time` datetime NOT NULL,
  76. `process_status` varchar(20) NOT NULL DEFAULT 'PENDING',
  77. `raw_data` json NOT NULL,
  78. `process_message` varchar(500) DEFAULT NULL,
  79. `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  80. `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  81. PRIMARY KEY (`id`),
  82. UNIQUE KEY `uk_stg_s0_item_substitute` (`tenant_id`,`source_system`,`source_table`,`source_row_id`),
  83. KEY `idx_stg_s0_item_substitute_biz` (`source_biz_key`),
  84. KEY `idx_stg_s0_item_substitute_batch` (`tenant_id`,`sync_batch_id`)
  85. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='S0 贴源:替代料(源 ItemSubstituteDetail)';
  86. CREATE TABLE IF NOT EXISTS `bridge_item_substitute` (
  87. `id` bigint NOT NULL AUTO_INCREMENT,
  88. `tenant_id` bigint NOT NULL,
  89. `parent_item_code` varchar(100) NOT NULL COMMENT '业务键 ← $.ParentItem;对 dim_item 零孤儿但框架单父故不设父。实测与 item_code 16 行无一相等,是真实不同信息',
  90. `item_code` varchar(100) NOT NULL COMMENT '业务键 + 父键 ← $.ItemNum(被替代的料);父 = dim_item.item_code(实测孤儿 0/16)',
  91. `substitute_item_code` varchar(100) NOT NULL COMMENT '业务键 ← $.SubstituteItem;对 dim_item 零孤儿,不设父',
  92. `substitute_qty` decimal(18,6) DEFAULT NULL COMMENT '← $.SubstituteQty',
  93. `substitute_type` varchar(20) DEFAULT NULL COMMENT '← $.SubstituteType',
  94. `remark` varchar(255) DEFAULT NULL COMMENT '← $.Remark',
  95. `domain_code` varchar(50) NOT NULL COMMENT 'LEGACY_SCOPE ← $.Domain;在旧 UK 内但按 D-025 不入身份',
  96. `source_system` varchar(50) NOT NULL,
  97. `source_biz_key` varchar(300) NOT NULL,
  98. `source_updated_at` datetime DEFAULT NULL COMMENT '← $.UpdateTime',
  99. `sync_batch_id` varchar(64) NOT NULL,
  100. `sync_time` datetime NOT NULL,
  101. `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  102. `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  103. PRIMARY KEY (`id`),
  104. -- 索引字节 = 8 + 100*4 + 100*4 + 100*4 = 1208 < 3072
  105. UNIQUE KEY `uk_bridge_item_substitute` (`tenant_id`,`parent_item_code`,`item_code`,`substitute_item_code`),
  106. KEY `idx_bis_parent` (`tenant_id`,`item_code`),
  107. KEY `idx_bis_batch` (`sync_batch_id`)
  108. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
  109. COMMENT='S0 关系桥:替代料。源 ItemSubstituteDetail,FULL REPLACE。父 = dim_item(自然键 item_code = 被替代料)。三个 item 引用全部统一到 dim_item。';
  110. SET @src_id = (SELECT `id` FROM `mdp_source` WHERE `source_code` = 'AIDOPDEV_MYSQL' LIMIT 1);
  111. -- batch_size 按最大租户留 3× 余量:ProductStructureMaster 单租户最大 57199 → 200000。
  112. -- AssertNoSourceDuplicateAsync 是 sourceCount >= batchSize 严格判定,必须单页装下。
  113. INSERT INTO `mdp_entity`
  114. (`tenant_id`,`source_id`,`entity_code`,`entity_name`,`entity_type`,
  115. `source_table_name`,`target_table_name`,`sync_mode`,`incr_column`,`batch_size`,
  116. `biz_key_expr`,`status`,`create_time`,`update_time`)
  117. SELECT 0, @src_id, 'S0_ITEM_BOM', 'S0 BOM 结构入站', 'TABLE',
  118. 'ProductStructureMaster', 'mdp_stg_s0_item_bom', 'FULL', NULL, 200000,
  119. 'ParentItem,ComponentItem', 1, NOW(), NOW()
  120. WHERE @src_id IS NOT NULL
  121. AND NOT EXISTS (SELECT 1 FROM `mdp_entity` WHERE `entity_code` = 'S0_ITEM_BOM');
  122. INSERT INTO `mdp_entity`
  123. (`tenant_id`,`source_id`,`entity_code`,`entity_name`,`entity_type`,
  124. `source_table_name`,`target_table_name`,`sync_mode`,`incr_column`,`batch_size`,
  125. `biz_key_expr`,`status`,`create_time`,`update_time`)
  126. SELECT 0, @src_id, 'S0_ITEM_SUBSTITUTE', 'S0 替代料入站', 'TABLE',
  127. 'ItemSubstituteDetail', 'mdp_stg_s0_item_substitute', 'FULL', NULL, 5000,
  128. 'ParentItem,ItemNum,SubstituteItem', 1, NOW(), NOW()
  129. WHERE @src_id IS NOT NULL
  130. AND NOT EXISTS (SELECT 1 FROM `mdp_entity` WHERE `entity_code` = 'S0_ITEM_SUBSTITUTE');
  131. -- ── 回滚(注释,非可执行)──
  132. -- DROP TABLE IF EXISTS `bridge_item_bom`, `bridge_item_substitute`;
  133. -- DROP TABLE IF EXISTS `mdp_stg_s0_item_bom`, `mdp_stg_s0_item_substitute`;
  134. -- DELETE FROM `mdp_entity` WHERE `tenant_id`=0 AND `entity_code` IN ('S0_ITEM_BOM','S0_ITEM_SUBSTITUTE');