| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- -- =====================================================================================
- -- 1.0.506 · S0 MASTER DATA PLATFORM · PHASE 2 · BATCH 4
- --
- -- 目标:在 Phase 1 已验证的 S0Dim 通用框架上扩展两个 C1 维度,**只加 Definition,不加服务**。
- -- EmployeeMaster → mdp_stg_s0_employee → dim_employee
- -- LineMaster → mdp_stg_s0_line → dim_line
- --
- -- 本批边界(与 Phase 1 一致):
- -- · 不建、不改、不删共享表 mdp_stg_location / mdp_stg_employee / mdp_stg_line
- -- (后两张属 DOPDEMORQ,当前 0 行,但不是 S0 的 authority —— 故另建 S0 专用 stg)
- -- · 不写 mdp_source / mdp_field_mapping;不碰 mdp_std_item / mdp_std_supplier
- -- · 不动 S1–S9 既有对象、不动 S0 CRUD、不动前端
- --
- -- 取号:开发期用 WIP 名,提交那刻按 origin/master 实际最大号 +1 改名为 1.0.<n>.sql
- -- (verify 脚本必须同批同号改名,AutoVersionUpdate 用 Path.ChangeExtension 配对)。
- --
- -- 租户契约(P0,实测依据):
- -- · Employee 身份 = tenant_id + Employee (Domain / company / factory 均为属性,非身份)
- -- · Line 身份 = tenant_id + Line (Domain / company / factory 均为属性,非身份)
- --
- -- 身份口径按「当前业务证据优先」重判(2026-09-07 Semantic Gate),**不继承旧物理唯一键**:
- -- · Employee CRUD 查重 = tenant + FactoryRefId + Employee,不含 Domain;而 FactoryRefId 由
- -- AdoS0OrgScope.ResolveAsync 仅按租户解析并强制 stamp ⇒ 等价于 tenant + Employee。
- -- · Employee 真实 consumer 一律 `ON p.Buyer=e.Employee AND e.tenant_id=p.tenant_id`(5 处),无一处用 Domain。
- -- · Line CRUD 无任何查重守卫;consumer GetLinesAsync 只用 (TenantId, Line)。
- -- · 数据实测:tenant+Employee 租户内重复=0;Line 四个候选租户内重复全部=0,
- -- 且每个租户在 LineMaster 只有 1 个 Domain / 1 个 company / 1 个 factory ⇒ 租户内常量、零区分力。
- -- · 租户仍必须入身份:Employee 跨租户碰撞 19 组 / 38 行,Line 20 组 / 80 行;
- -- Domain 与 factory_ref_id=1000 均被多租户复用,都不具备隔离能力。
- -- =====================================================================================
- -- ── 一、S0 专用贴源表(2 张)──────────────────────────────────────────────────────
- -- UK 刻意包含 source_system:共享表 mdp_stg_location 的 UK 不含它,导致同名源表在不同源
- -- 之间串键(Phase 1 已实证)。S0 自有表一律补上,即使当前只有一个源。
- CREATE TABLE IF NOT EXISTS `mdp_stg_s0_employee` (
- `id` bigint NOT NULL AUTO_INCREMENT,
- `tenant_id` bigint NOT NULL DEFAULT 0,
- `factory_id` bigint DEFAULT NULL,
- `source_system` varchar(50) NOT NULL DEFAULT 'AIDOPDEV_MYSQL',
- `source_table` varchar(100) NOT NULL,
- `source_row_id` varchar(100) NOT NULL,
- `source_biz_key` varchar(300) DEFAULT NULL,
- `sync_batch_id` varchar(100) NOT NULL,
- `sync_time` datetime NOT NULL,
- `process_status` varchar(20) NOT NULL DEFAULT 'PENDING',
- `raw_data` json NOT NULL,
- `process_message` varchar(500) DEFAULT NULL,
- `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
- PRIMARY KEY (`id`),
- UNIQUE KEY `uk_stg_s0_employee` (`tenant_id`,`source_system`,`source_table`,`source_row_id`),
- KEY `idx_stg_s0_employee_biz` (`source_biz_key`),
- KEY `idx_stg_s0_employee_batch` (`tenant_id`,`sync_batch_id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='S0 主数据贴源:雇员(源 EmployeeMaster)';
- CREATE TABLE IF NOT EXISTS `mdp_stg_s0_line` (
- `id` bigint NOT NULL AUTO_INCREMENT,
- `tenant_id` bigint NOT NULL DEFAULT 0,
- `factory_id` bigint DEFAULT NULL,
- `source_system` varchar(50) NOT NULL DEFAULT 'AIDOPDEV_MYSQL',
- `source_table` varchar(100) NOT NULL,
- `source_row_id` varchar(100) NOT NULL,
- `source_biz_key` varchar(300) DEFAULT NULL,
- `sync_batch_id` varchar(100) NOT NULL,
- `sync_time` datetime NOT NULL,
- `process_status` varchar(20) NOT NULL DEFAULT 'PENDING',
- `raw_data` json NOT NULL,
- `process_message` varchar(500) DEFAULT NULL,
- `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
- PRIMARY KEY (`id`),
- UNIQUE KEY `uk_stg_s0_line` (`tenant_id`,`source_system`,`source_table`,`source_row_id`),
- KEY `idx_stg_s0_line_biz` (`source_biz_key`),
- KEY `idx_stg_s0_line_batch` (`tenant_id`,`sync_batch_id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='S0 主数据贴源:生产线(源 LineMaster)';
- -- ── 二、维度表(2 张)────────────────────────────────────────────────────────────
- -- tenant_id 一律 NOT NULL 且为唯一键首列;FULL REPLACE 按 tenant_id 分区删改。
- --
- -- 舍弃的源列(明确记录,避免下次误以为漏了):
- -- EmployeeMaster:Sex / Phone / Email / BirthDate / MaritalStatus / City / Country /
- -- BusinessPhone / CarId / DefaultWorkLocation —— 个人信息或无主数据语义,
- -- 维度层不承载 PII;CreateUser/CreateTime/UpdateUser/RecID —— 审计列,非主数据属性。
- -- LineMaster: line_describe(恒空影子列,真列是 Describe)· PickingLocation(0/169 填充) ·
- -- location3(0/169) · VLocation / MidLocation / location2(各 28/169,
- -- 三个无标准语义的备用库位槽,含义未经业务确认)· CreateUser/CreateTime/UpdateUser/RecID。
- CREATE TABLE IF NOT EXISTS `dim_employee` (
- `id` bigint NOT NULL AUTO_INCREMENT COMMENT '技术行号;每轮 FULL 重建即变,禁止外部引用',
- `tenant_id` bigint NOT NULL COMMENT '租户',
- `company_id` bigint NOT NULL COMMENT '← $.company_ref_id;属性,不入身份',
- `factory_id` bigint NOT NULL COMMENT '← $.factory_ref_id;属性,不入身份(1000 被多租户共用,无隔离能力)',
- `employee_code` varchar(100) NOT NULL COMMENT '工号(**唯一业务键**)← $.Employee',
- `domain_code` varchar(50) NOT NULL COMMENT 'ATTRIBUTE ← $.Domain;仅供部门父连接与引用校验,**不是身份**',
- `employee_name` varchar(200) DEFAULT NULL COMMENT '← $.Name',
- `department_code` varchar(100) DEFAULT NULL COMMENT '← $.Department;自由文本软引用 dim_department,无 DB FK;NULL=未分配(不算孤儿)',
- `job_title` varchar(100) DEFAULT NULL COMMENT '← $.JobTitle',
- `work_center_code` varchar(100) DEFAULT NULL COMMENT '← $.WorkCtr;按业务键引用 dim_work_center,无 DB FK',
- `employment_status` varchar(50) DEFAULT NULL COMMENT '← $.EmploymentStatus',
- `date_employed` datetime DEFAULT NULL COMMENT '← $.DateEmployed',
- `date_terminated` datetime DEFAULT NULL COMMENT '← $.DateTerminated',
- `sys_user_id` bigint DEFAULT NULL COMMENT '← $.sys_user_id;稀疏(源 7/1105 非空)。**属性,绝不参与业务键**',
- `is_active` tinyint(1) NOT NULL COMMENT '源 IsActive 透传(raw_data 中为 JSON BOOLEAN)',
- `source_system` varchar(50) NOT NULL,
- `source_biz_key` varchar(300) NOT NULL COMMENT '回溯 staging 用',
- `source_updated_at` datetime DEFAULT NULL COMMENT '← $.UpdateTime;源 97% 非空,允许 NULL,不得回填假时间',
- `sync_batch_id` varchar(64) NOT NULL,
- `sync_time` datetime NOT NULL,
- `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
- `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`id`),
- UNIQUE KEY `uk_dim_employee` (`tenant_id`,`employee_code`),
- KEY `idx_dim_employee_batch` (`sync_batch_id`),
- KEY `idx_dim_employee_dept` (`tenant_id`,`domain_code`,`department_code`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='S0 主数据维度:雇员。源 EmployeeMaster,FULL REPLACE。';
- CREATE TABLE IF NOT EXISTS `dim_line` (
- `id` bigint NOT NULL AUTO_INCREMENT COMMENT '技术行号;每轮 FULL 重建即变,禁止外部引用',
- `tenant_id` bigint NOT NULL COMMENT '租户',
- `company_id` bigint NOT NULL COMMENT 'LEGACY_SCOPE ← $.company_ref_id;f(tenant),**不是身份**',
- `factory_id` bigint NOT NULL COMMENT 'LEGACY_SCOPE ← $.factory_ref_id;f(tenant),**不是身份**。⚠️ 绝不可设进 MdpPullContext.FactoryId,见 I-015',
- `line_code` varchar(100) NOT NULL COMMENT '产线编码(**唯一业务键**)← $.Line',
- `domain_code` varchar(50) NOT NULL COMMENT 'LEGACY_SCOPE ← $.Domain;租户内常量,**不是身份**',
- `line_name` varchar(255) DEFAULT NULL COMMENT '← $.Describe(真列;同表 line_describe 恒空,是影子列)',
- `line_type` varchar(50) DEFAULT NULL COMMENT '← $.LineType',
- `line_category` varchar(50) DEFAULT NULL COMMENT '← $.LineCategory',
- `workshop` varchar(50) DEFAULT NULL COMMENT '← $.Workshop',
- `location_code` varchar(50) DEFAULT NULL COMMENT '← $.Location;按业务键软引用 dim_location,无 DB FK',
- `is_active` tinyint(1) NOT NULL COMMENT '源 IsActive 透传',
- `source_system` varchar(50) NOT NULL,
- `source_biz_key` varchar(300) NOT NULL COMMENT '回溯 staging 用',
- `source_updated_at` datetime DEFAULT NULL COMMENT '← $.UpdateTime;源 100% 非空',
- `sync_batch_id` varchar(64) NOT NULL,
- `sync_time` datetime NOT NULL,
- `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
- `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`id`),
- UNIQUE KEY `uk_dim_line` (`tenant_id`,`line_code`),
- KEY `idx_dim_line_batch` (`sync_batch_id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='S0 主数据维度:生产线。源 LineMaster,FULL REPLACE。';
- -- ── 三、mdp_entity 入站配置(2 条,全 FULL)──────────────────────────────────────
- --
- -- · sync_mode 必须 FULL、incr_column 必须 NULL:Phase 2 既定策略。
- -- 即便 Employee UpdateTime 97%、Line 100%,也不切 INCR ——
- -- 留 incr_column 会让 BuildSelectSql 生成 "col > @cursor",使水位为 NULL 的行永久不可达
- -- (Employee 实测有 29 行 UpdateTime 为 NULL)。
- -- · biz_key_expr 是【源物理列名】逗号列表,须与 Definition.SourceBizKeyColumns 逐字一致,
- -- 否则 S0DimMaterializer.AssertEntityContractAsync 会当场报配置漂移。
- -- · batch_size 必须大于单租户最大行数(Employee 最大 613、Line 最大 109),5000 余量充足。
- SET @src_id = (SELECT `id` FROM `mdp_source` WHERE `source_code` = 'AIDOPDEV_MYSQL' LIMIT 1);
- INSERT INTO `mdp_entity`
- (`tenant_id`,`source_id`,`entity_code`,`entity_name`,`entity_type`,
- `source_table_name`,`target_table_name`,`sync_mode`,`incr_column`,`batch_size`,
- `biz_key_expr`,`status`,`create_time`,`update_time`)
- SELECT 0, @src_id, 'S0_EMPLOYEE', 'S0 雇员主数据入站', 'TABLE',
- 'EmployeeMaster', 'mdp_stg_s0_employee', 'FULL', NULL, 5000,
- 'Employee', 1, NOW(), NOW()
- WHERE @src_id IS NOT NULL
- AND NOT EXISTS (SELECT 1 FROM `mdp_entity` WHERE `entity_code` = 'S0_EMPLOYEE');
- INSERT INTO `mdp_entity`
- (`tenant_id`,`source_id`,`entity_code`,`entity_name`,`entity_type`,
- `source_table_name`,`target_table_name`,`sync_mode`,`incr_column`,`batch_size`,
- `biz_key_expr`,`status`,`create_time`,`update_time`)
- SELECT 0, @src_id, 'S0_LINE', 'S0 生产线主数据入站', 'TABLE',
- 'LineMaster', 'mdp_stg_s0_line', 'FULL', NULL, 5000,
- 'Line', 1, NOW(), NOW()
- WHERE @src_id IS NOT NULL
- AND NOT EXISTS (SELECT 1 FROM `mdp_entity` WHERE `entity_code` = 'S0_LINE');
- -- ── 回滚(注释,非可执行;执行前请确认无消费者)──────────────────────────────────
- -- DROP TABLE IF EXISTS `dim_line`;
- -- DROP TABLE IF EXISTS `dim_employee`;
- -- DROP TABLE IF EXISTS `mdp_stg_s0_line`;
- -- DROP TABLE IF EXISTS `mdp_stg_s0_employee`;
- -- DELETE FROM `mdp_entity` WHERE `tenant_id` = 0 AND `entity_code` IN ('S0_EMPLOYEE','S0_LINE');
|