简介:中国电信企业数据模型3.0是中国电信CTG-MBOSS体系中EDA分规范的分册,也是企业数据标准体系的关键组成部分,面向电信行业数据架构师、数据治理人员及业务分析师。内容涵盖概念数据模型与逻辑数据模型,本次修订聚焦BSS部分,涉及参与人、产品、帐务、市场营销、事件和地域六大主题域,并阐述了概念、逻辑、物理三层模型的定位与建模原则。资源为1个doc文档,压缩包大小4.45MB,文档从编制说明、EDM3.0框架到主题域分解均有详细呈现,便于直接阅读和参考。已有299人学习下载,对于需要理解中国电信数据模型演进、搭建企业级数据标准的读者,具有直接参考价值。
1. 中国电信企业数据模型3.0:一套让数仓少走三年弯路的分层规范
先还原一个真实场景:某公司要搭建企业级数据仓库,把 CRM、计费、客服、资源等十几个业务系统的数据拢到一张口径统一的模型里。刚开始大家都挺乐观,结果一碰细节就翻车——同一个“客户”在计费系统里按用户 ID 存,在客服系统里按合同号存,在 CRM 里又按证件号存,字段格式五花八门。这时候最需要的不是某个 SQL 技巧,而是一套能直接拿来用的企业级数据模型规范。中国电信企业数据模型3.0 就是这么一份资源:它覆盖从 MBOSS 各业务系统到 ODS、EDW、数据集市的完整分层,定义了主题域、命名规范、主外键策略和公共代码标准。适合正在做数仓建模、数据治理、贴源层开发的数据工程师和模型设计人员,拿它当参考,比自己从零定规范靠谱得多。
2. 从MBOSS到EDM 3.0:分层架构和ODS/EDW/ADS边界到底怎么切
2.1 五层架构:接口层、ODS、EDW、ADS、DM各自管什么
EDM 3.0 的核心不是一张表,而是一套自上而下的分层逻辑。按电信行业最常用的切法,数据从业务系统到最终应用,要经过五层:接口层(STG)、贴源层(ODS)、整合层(EDW)、集市层(ADS)和应用层(DM)。
接口层在 EDM 3.0 里通常是暂时不讲的,因为它是临时的落地区,只做抽取和格式转换,不承担模型职责。但从实际操作看,它却决定了后面模型能不能建得干净。我一般会在接口层做三件事:按源系统建库、保留源表结构、只加抽取时间和批次号两个字段。这样后面 ODS 出问题,还能回到接口层核对原始数据。
ODS 层在模型中的定位是“贴源”,核心原则是尽可能保持源系统原貌。MBOSS 里通常包含计费、客户关系管理、服务开通、资源管理、结算等多个子系统,ODS 就把每个子系统的核心表近乎原样地接进来,只做必要的清洗,比如去掉明显垃圾数据、统一字符集。EDW 才是 EDM 3.0 真正花心思的地方。它要把 ODS 里分散的、按源系统组织的数据,重新按业务主题组织成第三范式的关系模型,也就是把“客户”“产品”“订单”“资源”“事件”这些跨系统概念统一起来。
ADS 和 DM 层则是面向应用出口的,一般引入维度建模,把 EDW 的规范化模型转成星型或雪花型,便于报表和自助分析直接取数。经常有人问 ADS 和 DM 到底有什么区别,我的理解是:ADS 是面向分析主题的汇总层,DM 是特定应用独立建设的集市,如果组织架构里没有单独的应用集市要求,两者可以合并。EDM 3.0 给的是“逻辑分层 + 物理映射建议”,落地时不必五层全建,但 ODS 和 EDW 这两层必须有清晰边界。
2.2 建模方法论:为什么EDM 3.0用3NF关系建模而不是一上来就拉宽表
这是拆这份模型时我最想强调的点。EDM 3.0 在 EDW 整合层的主建模方法是第三范式(3NF)关系建模,而不是大多数人习惯的宽表思维。
原因要从电信业务的数据特征说起。电信业务里客户、账户、产品、订购关系、资源、账单这些实体之间关系非常复杂:一个客户可以有多个账户,一个账户下挂了多个产品实例,一个产品实例又可能依赖不同的物理资源。如果用宽表把这一切压平,字段动辄几百个,大量字段只对少数场景有用,空值率极高,而且业务口径一变就要改表结构。3NF 的做法的好处是,把每个主题域拆成粒度清晰、关系明确的实体表,比如客户主题域拆成客户基本信息、客户信用、客户接触等;产品主题域拆成产品定义、产品定价、产品目录等。表与表之间靠主外键关联,更新一个实体的属性不会波及整行。
集市层才引入星型模型,把最常用的分析维度如时间、地域、客户、产品抽出来,配上事实表。这个“3NF 整合 + 维度建模出口”的组合,就是电信行业数据模型几十年来沉淀下来的标准姿势。
另一个值得说的是 EDM 3.0 对“一致性维度”的处理。例如“地域”这个维度,在 ODS 里可能有的源系统叫“区号”,有的叫“本地网标识”,格式还不一样。EDM 3.0 的做法是在整合层定义一套统一的地域维,包含省份、地市、区县、本地网等多个层级,并用规范的代码表维护,所有下游集市都引用这套维度,而不是各自维护。这就避免了同一张报表在不同部门取出的“北京”一个是省份、一个是地市的尴尬。
2.3 从MBOSS到EDM 3.0的映射:一份主题域、分层与贴源表的对应关系
落地时最常遇到的第一个硬骨头,是怎么把 MBOSS 各系统的表映射到 EDM 3.0 的主题域和分层上。EDM 3.0 大体按十个主题域组织:客户、产品、营销、渠道、订单、服务开通、资源、服务保障、结算、事件。实际映射可以按下面这个表格来定调:
主题域 | 典型来源系统(MBOSS) | 模型层 | 核心实体示例 客户 | CRM、客服 | EDW | 客户基本信息、客户信用、客户等级 产品 | 产品管理、计费 | EDW | 产品定义、产品目录、产品价格 营销 | 营销管理 | EDW | 营销活动、营销目标客户群 订单 | 订单中心、CRM | EDW | 主订单、订单项、订单状态流转 资源 | 资源管理、管线系统 | EDW | 局站、设备、端口、号码资源 结算 | 计费、结算系统 | EDW | 账单、账目、缴费记录、调账记录
这个映射不是一次性能做对的。我第一回做也犯过错误,把“订单”主题直接对应到了 CRM 的销售订单表,忽略了无线上网卡、宽带提速包这些不经过 CRM 的电子渠道订单。后面改模型才补上了“订单来源渠道”这个属性。
每个主题域内部,EDM 3.0 会给出实体清单、属性清单和关系图。拿到这份资源后,特别推荐先做一个动作:把自己公司的源系统清单列出来,按这张表逐个归类,标出哪些源表是主数据(客户、产品、资源),哪些是过程数据(订单、账单、事件),哪些是配置数据(编码、目录)。主数据进 EDM 时要做去重合并,过程数据进 EDM 是按业务过程组织的事实,配置数据则直接抽成维表或码表。这个归类一旦做对了,后面建表、调度、对账都会顺畅很多。
3. 落地EDM 3.0的正确姿势:命名规范、主外键和公共代码的实操细节
3.1 命名规范:从表名前缀到字段后缀,一抄就能用
EDM 3.0 里最容易被低估、也最容易执行的就是命名规范。实际项目里,因为命名不规范导致的数据血缘断裂,比建模能力不足还要普遍。EDM 3.0 给出的命名规范可以归纳成下面这套模式,拿过来稍作调整就能用。
表名结构一般分为三段:分层前缀_业务域_业务实体。
- ods_crm_customer_base:ODS 层 CRM 系统客户基础信息
- edw_cust_customer_info:EDW 层客户主题域客户信息表
- ads_prod_sales_monthly:ADS 层产品主题月度销售汇总
字段命名建议统一采用“业务含义 + 类型后缀”的模式,避免缩写泛滥。
- 客户编号字段统一叫 cust_id,不接受 cus_no、customer_num、cust_code 这类变体
- 时间统一用 dt 做分区后缀,如 dt=‘2025-06-01’,内部业务时间用 biz_date
- 公共字段每张表都带 data_dt(数据日期)、etl_time(ETL 加工时间)、src_sys_cd(源系统编码)
提示:命名规范一定要在建模第一天就固定下来,并且把登记表放在所有人能看见的地方。一旦表建起来再改名,成本是几何级数上升的。
这里我一般会在执行层再补一条约定:ETL 临时表统一加 tmp_ 前缀,调度日志表统一加 log_ 前缀,它们不属于模型资产,但如果混进正式表的命名序列,数据字典会乱到不可用。
3.2 主键、外键与缓慢变化维的处理约定
EDM 3.0 在 EDW 层对主外键有明确建议,落地时最容易踩坑的是“源系统主键能不能直接拿来当模型主键”。答案通常是不能。
源系统主键往往带有很强的业务局限,比如 CRM 的客户主键只对 CRM 有效,计费系统的用户标识只对计费有效,要跨系统关联就得在 EDW 层生成一个统一的企业主键。常见的做法是两种:一是用“源系统编码 + 源系统主键”的双字段组合键,保证可追溯;二是建立代理键,在 EDM 层生成整层唯一的代理主键,源系统主键作为业务键单独存放。我经历过的项目里,电信领域更推荐代理键,因为双字段组合键在关联订单和客户时会出现一对多、多对多的复杂情况,代理键可以简化关联条件,也方便在数据更正时保持关联稳定。
另一个容易翻车的是缓慢变化维(SCD)的处理。客户等级、产品状态这些属性是会随时间变化的,如果直接覆盖更新,历史分析时口径就丢了。EDM 3.0 对这类变化一般推荐 SCD2,也就是保留历史版本,用 effective_date、expired_date、current_flag 三个字段标记有效期和当前版本。在 Hive 里实现 SCD2 我一般会先对源数据做全量比对,把变化的数据标记出来,再对目标表拉起失效时间和版本。SQL 不复杂,但比对逻辑必须严谨,否则会出现同一天对同一个客户生成两条 current 记录。
3.3 公共代码与数据字典怎么映射到Hive/IDB物理模型
EDM 3.0 里公共代码是灵魂,也是最容易被当摆设的部分。它定义了省份编码、运营商编码、业务类型编码、账目类型编码等一套全企业统一的编码体系。比如省份编码采用 2 位数字,地市编码采用 2 位省份码 + 2 位地市码,这个规则一旦定了就不能在业务侧随意改。
物理映射到 Hive 或其它大数据平台时,我的做法是把公共代码拆成两类:一类是维度属性型的公共代码,直接在集成层建码表,比如 dim_pub_province_code、dim_pub_business_type,字段结构通常是 code_value、code_name、parent_code、status、sort_no;另一类是枚举说明型的公共代码,不适合建表,就维护在模型说明文档里,并在字段注释里写清楚枚举含义。
用建表语句来示意:
CREATE TABLE dim_pub_province_code ( prov_id STRING COMMENT '省份编码', prov_name STRING COMMENT '省份名称', region_id STRING COMMENT '大区编码', region_name STRING COMMENT '大区名称', status TINYINT COMMENT '状态:1有效,0无效', sort_no INT COMMENT '排序号' ) COMMENT '省份公共代码维表' PARTITIONED BY (dt STRING COMMENT '数据日期分区') STORED AS PARQUET;这里有两类参数值得注意:partitioned by 按 dt 分区,每天全量刷一遍公共代码;STORED AS PARQUET 是为了压缩和列式读取,后续关联省份时 I/O 消耗更小。这份模型资源里的表结构定义,拿到自己环境后第一步就是做方言转换,把字段类型和分区策略适配到自研平台,再考虑数据加载。
建表只是第一步,更关键的是公共代码的“消费”规则。我强制要求下游所有表关联公共代码时只能通过维表的主键关联,不允许在事实表里直接存编码含义文本。开始执行时确实有些反人性,但好处在写报表时才会体现——口径变更只需要改维表,不用回头改几十张事实表。
4. 调度与加工:从ODS贴源到EDW整合的典型三层任务链
4.1 ODS层任务:抽取、清洗、落地,先解决幂等
从 MBOSS 到数仓的落地,第一个环节就是 ODS 层的抽取任务。EDM 3.0 不负责告诉你用什么工具抽,但落地时“怎么抽得干净”是模型能稳定运行的前提。我常见的做法是把 ODS 抽取拆成三个子任务:抽取、清洗、落分区。
抽取环节关键是把增量做到可控。如果是业务库直连,一般是基于时间戳增量抽取,这一天取的是 create_time 或 modify_time 大于上次数仓快照时间的记录;如果是文件交换,则是按日解析接口文件。清洗环节重点做三件事:去除完全重复记录、把明显乱码或空主键的行标记并过滤、统一字符串长度和字符集。落分区这一环节是幂等的关键——每一次抽取都往一个新的分区里写,用 dt 分区隔离,不允许覆盖上一次结果。
一个典型的 ODS 层同步脚本示意:
#!/bin/bash # 参数: $1=业务日期 yyyyMMdd BIZ_DATE=$1 ods_table="ods_crm_customer_base" src_schema="crm" src_table="customer_base" sqoop import \ --connect jdbc:oracle:thin:@//10.20.30.40:1521/crmdb \ --username ${SRC_USER} --password ${SRC_PASS} \ --query "SELECT cust_id, cust_name, cert_type, cert_no, \ create_time, modify_time, 'CRM' AS src_sys_cd \ FROM ${src_schema}.${src_table} \ WHERE modify_time >= TO_DATE('${BIZ_DATE}','YYYYMMDD') \ AND modify_time < TO_DATE('${BIZ_DATE}','YYYYMMDD') + 1" \ --target-dir /warehouse/ods/crm/${ods_table}/dt=${BIZ_DATE} \ --delete-target-dir \ --fields-terminated-by '\001' \ --m 4这段脚本有四个参数值得解释一下。目标目录按动态分区写,每天一个独立分区,不会污染历史数据;delete-target-dir 配合分区目录使用,保证当天任务重跑时是“删除重写”,不是叠加;m 为并行度,电信来源表一般数据量可控,4 个 map 足够,再大就按主键范围拆分提升并发;fields-terminated-by 用 \001 是为了避免源数据里出现同款分隔符导致列错位。
ODS 层我还会保留一个字段:src_sys_cd,用来标识数据来自哪个源系统。这是后面做数据血缘和问题排查的重要入口,没有它,一条客户数据出问题基本没法回溯。
4.2 EDW整合层:事实表与维表的加工顺序,以及SCD2的实现
EDW 层加工是 EDM 3.0 最核心的落地动作。从 ODS 进入 EDW,要做的事是“转、并、分、升”。转,是把源系统字段名改为符合模型规范的统一名称;并,是把分散在多个源系统的同一个实体合并为一张主数据表;分,是把一张宽表按 3NF 拆到多个主题实体;升,是把明细数据按维度归属统一到企业维度。
加工顺序上,有一个铁律:先维表,后事实表。维表是关联的基准,事实表是度量。如果事实表先加工,再回头补维表,关联时会出现大量找不到维度的孤儿数据,质量校验时要花很多功夫返工。
SCD2 是 EDW 层最常写的逻辑。以客户产品订购关系为例,订购状态会变,客户星级会变,每次变更都要保留历史版本。Hive 里实现 SCD2 我会用“拉链 + 分区”的做法,每天基于当天快照和历史拉链结果做比对,把新增、变更、未变三类数据区分出来,再写进目标表:
INSERT OVERWRITE TABLE edw_cust_cust_prod_relation PARTITION (dt) SELECT t.cust_id, t.prod_id, t.star_level, t.effective_date, CASE WHEN t.is_latest = 'Y' AND u.cust_id IS NOT NULL THEN DATE_SUB('${biz_date}', 1) ELSE t.expired_date END AS expired_date, t.is_latest, CURRENT_TIMESTAMP() AS etl_time, t.biz_date AS dt FROM ( SELECT cust_id, prod_id, star_level, effective_date, expired_date, is_latest, biz_date, ROW_NUMBER() OVER (PARTITION BY cust_id, prod_id ORDER BY effective_date DESC) AS rn FROM edw_cust_cust_prod_relation WHERE dt = DATE_SUB('${biz_date}', 1) ) t LEFT JOIN ( SELECT cust_id, prod_id, star_level FROM ods_order_cust_prod_relation WHERE dt = '${biz_date}' ) u ON t.cust_id = u.cust_id AND t.prod_id = u.prod_id WHERE t.rn = 1 UNION ALL SELECT u.cust_id, u.prod_id, u.star_level, '${biz_date}' AS effective_date, NULL AS expired_date, 'Y' AS is_latest, CURRENT_TIMESTAMP() AS etl_time, '${biz_date}' AS dt FROM ods_order_cust_prod_relation u LEFT JOIN ( SELECT DISTINCT cust_id, prod_id FROM edw_cust_cust_prod_relation WHERE dt = DATE_SUB('${biz_date}', 1) ) t ON u.cust_id = t.cust_id AND u.prod_id = t.prod_id WHERE t.cust_id IS NULL;这段 SQL 的逻辑分两段。第一段把昨天的历史版本拿出来,和今天 ODS 的增量做关联,如果今天没有这个订了,就把历史版本的失效日期更新为昨天、is_latest 置为 N;如果今天有关联但属性没变,则保持不失效。第二段把今天 ODS 里新增的订购关系直接插入,effective_date 为今天、expired_date 为空、is_latest 为 Y。
这里有个必须注意的参数:ROW_NUMBER() OVER 的分区键选 cust_id + prod_id 的组合,不能只按客户分。一个客户可能同时订购宽带和语音两个产品,属性变化互相独立。只按客户分区会把两条不同产品的记录误判为重复,导致历史版本被错误关闭。
EDW 层加工完以后,建议立刻做一次“维表完备性检查”,即将事实表里所有外键与对应维表主键做 LEFT JOIN,控制 in 匹配不上的比率。如果超过万分之一的阈值,先别急着往下游集市送,优先回去排查源系统数据缺失。
4.3 数据质量校验:比对记录数、主键唯一性和空值率三张底牌
数据质量校验是 EDM 3.0 落地中不能省的一环。我一般会在任务链末尾挂一组标准检查,用一张运营监控表来记录结果。校验维度有六个:源表与目标表的记录数差、主键唯一性、外键完备性、必填字段空值率、枚举字段合法值占比、加工时间是否落在批窗口内。
SQL 层面的三个典型检查脚本如下:
-- 检查1: 记录数比对 SELECT 'ods_crm_customer_base' AS tbl_name, COUNT(*) AS src_cnt FROM ods_crm_customer_base WHERE dt = '${biz_date}'; -- 检查2: 主键唯一性 SELECT cust_id, COUNT(*) AS dup_cnt FROM edw_cust_customer_info WHERE dt = '${biz_date}' GROUP BY cust_id HAVING COUNT(*) > 1; -- 检查3: 必填字段空值率 SELECT COUNT(*) AS total_cnt, SUM(CASE WHEN cust_name IS NULL OR cust_name = '' THEN 1 ELSE 0 END) AS name_null_cnt, ROUND(SUM(CASE WHEN cust_name IS NULL OR cust_name = '' THEN 1 ELSE 0 END) / COUNT(*), 4) AS name_null_ratio FROM edw_cust_customer_info WHERE dt = '${biz_date}';记录数检查要设定一个合理的容差阈值,比如 ODS 到 EDW 因为去重、无效数据过滤,允许 0.5% 以内的偏差;超过这个值就必须自动阻断下游任务。主键唯一性检查直接关注 HAVING 的返回结果,正常应为空集,若出现重复,基本是上游增量抽取逻辑在某个字段变更时重复拉数,或 EDW 合并时关联键选错了。空值率检查的阈值需要分字段设置,比如客户姓名这类必填字段是 0%,客户证件号码是 5%,客户联系这个非必填扩展字段可以放宽到 20%。
这套检查建议统一固化到调度平台里,失败自动发告警,而不是靠人肉盯报表。EDM 3.0 本身是模型规范,不提供监控体系,但落地时如果少了这一层,模型定义得再漂亮也是空中楼阁。
5. 避坑与常见问题:EDM 3.0落地中的七个翻车点
5.1 现象:模型评审时被问“这表到底该放ODS还是EDW?”
经常出现的情况是:某张表结构复杂、字段很多,评审时有人说是贴源层,有人说是整合层,谁也说不服谁。我最早也纠结过,后来定了一个判据——表里一个业务主键对应的记录数,跟源系统里是否一致。如果该表与源系统一一对应、一行对一行,它就是 ODS;如果主键进行了跨系统合并、属性经过了统一编码,它就是 EDW。判定语言从“感觉”变成“主键对齐和字段口径做没做过转换”,评审就立刻有抓手了。
原因在于 EDM 3.0 的分层定义没有给每张具体表预置归属,只给了判断原则。落地时一旦缺少判据,就会反复横跳。解决的办法是把它固化成评审检查项:ODS 层表字段个数差应小于 5,EDW 层表必须有模型编码和主题域归属说明,两张表都不允许既带贴源字段又带汇总字段。
5.2 现象:字段命名不规范导致数据字典失去管理意义
数据字典里同一字段出现 cust_no、customer_num、user_id、id_card 四种叫法,开发时各写各的,到数据集成时才发现关联不了。字典表查出来几十条疑似重复字段定义,却不敢轻易删,因为不知道谁在用。
原因不是员工不懂规范,而是 EDW 建模时没把命名登记环节嵌进开发流程。解决方法是把命名规范落到工具层面:在模型设计平台或元数据管理工具里建立公共字段池,新增字段必须先检索字段池,能复用就不允许新建;必须新造的字段要做业务含义说明。从那以后字段膨胀速度至少降了一大半,回到“看到字段名大概能猜到含义”的可用状态。
5.3 现象:调用EDM接口层数据时数据还没就绪
下游按模型规范加工数据,跑的时候发现接口层的分区数据是昨天甚至前天的,上游系统当天文件还没推送,或者抽取任务失败了。结果下游集市层产出一堆旧数,业务报表口径错乱,追责时才发现链路里的依赖关系没建立。
原因是对 ODS 层任务和 EDW 层任务之间的依赖只做了“表级依赖”,没做到“分区级依赖”。解决方法是把调度依赖从“日任务”细化为“分区就绪事件驱动”。上游 ODS 某个表当天分区写完后,通过调度平台发送分区就绪通知,EDW 任务收到通知才开始跑,而不是拍脑袋定一个任务起跑时间。对关键系统,我还会加一个“数据日期一致性”校验,即交易日与业务日的交叉比对,防止非交易日跑出来的空增量被当成正常数据。
5.4 现象:拆分的原子表太多引发大量关联
遵循 3NF 建模后,EDW 层实体表数量可能涨到上百张。有人按规范把客户信息拆到八个实体,客户基本信息、信用、联系、证件、等级、状态、标签、偏好各一张。结果下游取一个客户 360 度画像,要关联七张表,查询耗时从几十毫秒级别涨到几十秒。业务方抱怨模型太重。
原因不是 3NF 本身有问题,而是制度上没有做“模型与应用的边界”管理。解决方法是:EDW 层拆粒度,集市层做组合。在 ADS/DM 落地之前增加一层“客户主视图”,只在数据服务需要时按需生成宽表,且宽表字段在 EDW 层登记来源表字段,保证血缘清晰。从那以后每做一个宽表请求,都强制先回答“宽表字段来源是哪张模型表”,来源不明的一律不下发。
5.5 现象:给的CDL文件同步Hive后数据类型对不上
从 EDM 规范落地到 Hive 环境时最典型的问题:规范里字段类型是 DATE 或 DECIMAL(18,2),到 Hive 里直接按 STRING 建,或者 DECIMAL 精度被截断。结果日期无法直接做日期函数,金额算出来精度错位,报表汇总差几分钱都找不出原因。
原因主要是没有做规范的方言转换映射。解决方法是建表前先确认平台方言规则,比如 Oracle 的 DATE 对应 Hive 的 STRING 或 TIMESTAMP 需要业务侧确认粒度,DECIMAL 统一按 DECIMAL(18,2) 建,VARCHAR2 按 STRING 建但长度校验保留在加工逻辑里。另外建议建立“类型映射对照表”并在唯一的技术文档里维护,后续新增表都对照此表执行,不要靠灵光一现。
5.6 现象:模型规范更新后历史数据没有回流
EDM 3.0 出了修订版,字段口径调整、编码变更,新任务都按新规范跑,但历史分区里还是旧口径。结果同一张报表里“本月”和“上月”的口径不一致,业务方质疑数据不可信。
根源是没有建立“规范变更与数据回溯”的联动机制。解决方式是把模型版本挂在表注释里,并在每次规范变更时生成一批回溯任务,对受影响的历史分区按新口径重刷。如果数据量太大导致回溯成本高,那就至少保证“自然月连续”,即当月开始日到当月底的数据都按同一口径,并在模型文档里标注不同版本的切换日期,便于解释趋势类报表的口径断层。
5.7 现象:ODS层数据能取到数,EDW却配不齐外部键
集成测试时发现 EDW 的事实表里很多外部键关联不上维表,比如订购关系表里的产品编码在维表里查不到,或者出现客户维度主键重复。这种情况在调度完成刚闪绿的时候最迷惑,数据能抽出、能落表,为什么关联匹配不上。
根源往往是源系统之间同步时差,增量数据先到了事实表,维表数据还没到。解决方法是给这类关联加“迟到数据补偿机制”,即允许关联失败的数据先落地并打上质量标记,次日调度时再尝试回补;回补仍然失败的,自动进入异常池供排查。EDM 给了模型结构,补偿策略是落地时自己要补的一课,建议在数据质量规则设计时留一个“未匹配异常表”的出口。
6. 从模型到资产:用EDM 3.0做数据资产盘点与自助取数的进阶玩法
模型规范最大的价值不在建表的当下,而在建完之后能不能持续被消费。EDM 3.0 拿过来不只是一摞表结构定义,它背后是一套数据资产的目录框架。我建议做三件事把它盘活。
第一件事:把模型清单转成数据资产目录。模型清单里的主题域、实体、属性的定义,天然就是数据资产目录的骨架。落地时把每个实体映射到资产目录里的“数据对象”,加上负责人、业务含义、分级分类信息,自动形成一张资产地图。以后业务方想找“客户星级”数据,先查目录,再定位到具体表和字段,不用再猜测某张表里哪个字段能代表这个口径。
第二件事:用模型反向梳理取数链路。经常有业务方问“这个指标到底取自哪张表”,如果只靠人工回答,根本答不过来。更好的做法是从模型出发,将 ODS、EDW、ADS 三层的表血缘关系维护起来,取数链路像洋葱一样一层层剥开。这样当某张 ADS 表指标口径要变更时,能准确找到它对应的 EDW 表和 ODS 源表,避免改了下游却漏了上游。
第三件事:把模型规范变成一个自助取数入口。很多一线分析人员需要的不是原始明细,而是已经按模型逻辑加工好的指标和维度组合。可以在模型之上按已定义的指标口径构建数据集市,把常用的核心指标固化为预计算表,同时将维度、度量的定义开放给查询终端。这样报表开发减少重复建数,业务自己查起来也能保证口径不走样。
| 使用方式 | 适用人群 | 落地要点 | | 模型清单转资产目录 | 数据治理团队 | 需要冻结模型版本、登记负责人 | | 反查取数链路 | 数据工程团队 | 需要维护三层血缘并定期稽核 | | 模型自助取数入口 | 业务分析人员 | 需要先定义指标口径,再开放查询 |
最后说一个我的教训:早年间做第一个 EDM 落地项目时,我拿到模型文档先埋头建表,建了大半个月才回头补映射关系和命名登记表,结果返工了差不多一半。从那以后,我拿到任何一套模型规范,都强制先跑一遍“实体清单 → 表关系 → 资产目录”的映射,再谈建表。这份中国电信企业数据模型3.0 里面的资产框架和公共代码体系,是值得花时间完整走一遍这个流程的。希望帮到你。
本文还有配套的精品资源,点击获取