同一份订单在三个系统里——主数据采集口径怎么统一?
本文目录
先说结论
根因是"主数据未治理":各业务系统独立演进,对同一个业务对象(订单/用户/商品)有不同的字段、口径、状态机。
解决思路三层:① 确定权威源(Master);② 用统一ID映射(ID Mapping);③ 数仓层做"对齐+融合"(One ID)。
没有银弹:MDM是治理工程不是技术问题。数据团队推不动业务方,再好的技术方案也落地不了。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
数据团队最讨厌的事情之一就是"同一个业务对象,从不同系统采过来的数据对不上"。订单可能在交易系统、风控系统、CRM系统里都有,每家定义不一样,数仓接进来就是一锅粥。这道题面试官想看的不是"用一个系统当主",而是你有没有主数据管理(MDM)的体系化思维,能在采集环节把口径统一好。
业务场景:三个系统的订单数都不一样
做日订单大盘时,发现交易系统报50万、风控系统报48万、CRM报52万。三个系统都说自己"对"。仔细排查后发现:交易系统统计的是"创单成功",风控系统统计的是"通过风控"(拒了2万),CRM统计的是"包含线下订单"(多了4万)。每个系统在自己业务域内都对,但放在一起就错了。
三个系统的订单口径差异:
交易系统:
定义: 用户点击下单按钮成功的订单
范围: 包含未支付/已支付/已退款
时间: 用 create_time(下单时间)
风控系统:
定义: 通过风控的订单(拒单不计)
范围: 仅含通过风控的部分
时间: 用 risk_pass_time(风控通过时间)
CRM系统:
定义: 所有渠道的订单(线上+线下)
范围: 包含线下补录订单
时间: 用 record_time(录入CRM时间)
→ 同一指标三个值,业务方挑一个对自己有利的就吵起来
方案一:定义权威源(Source of Truth)
MDM的第一步是"确权"——每个业务对象只能有一个权威源,其他系统都是这个源的下游。这一步是治理工作,需要数据团队联合业务方拍板。
确权矩阵示例(订单业务):
字段 | 权威源 | 下游使用方
─────────────────┼────────────────┼─────────────────
order_id | 交易系统 | 风控/CRM/数仓
user_id | 用户中心 | 所有
amount | 交易系统 | 风控/数仓
status | 交易系统 | CRM/数仓
risk_score | 风控系统 | 数仓
channel | 交易系统 | CRM/数仓
customer_segment | CRM系统 | 数仓
原则:
- 每个字段只有一个权威源
- 下游系统读取时必须从权威源同步,不能自己改
- 同一字段在两个系统不一致时,以权威源为准
- 字段口径变更必须由权威源系统的Owner发起
落地难点:业务方往往不愿意承认"我不是权威源"。数据团队要带着业务诉求和数据证据去推,比如"上月差异导致大盘错了X次,建议交易系统作为订单权威源"。
方案二:ID Mapping打通
各系统的同一个业务对象往往用不同ID(交易系统的order_id、风控系统的risk_id、CRM的biz_no)。采集层必须建ID Mapping表把它们关联起来。
-- ID Mapping表(主数据核心)
CREATE TABLE id_mapping_order (
global_order_id BIGINT, -- 全局唯一ID(数仓自己生成)
trade_order_id BIGINT, -- 交易系统ID
risk_id STRING, -- 风控系统ID
crm_biz_no STRING, -- CRM业务编号
oms_id STRING, -- OMS订单ID
first_seen_ts BIGINT,
last_updated_ts BIGINT
);
-- 维护逻辑:用CDC采集各系统订单创建/更新事件
-- 通过共有字段(比如user_id+amount+create_time)做模糊匹配关联
MERGE INTO id_mapping_order t
USING (
SELECT trade_order_id, risk_id, crm_biz_no
FROM (
SELECT
tr.order_id AS trade_order_id,
rk.id AS risk_id,
cm.biz_no AS crm_biz_no,
ROW_NUMBER() OVER (PARTITION BY tr.order_id ORDER BY rk.create_time) AS rn
FROM ods_trade tr
LEFT JOIN ods_risk rk ON tr.user_id = rk.user_id
AND ABS(tr.amount - rk.amount) < 0.01
AND ABS(tr.create_time - rk.check_time) < 60 -- 1分钟内匹配
LEFT JOIN ods_crm cm ON tr.order_id = cm.ref_order_id
) WHERE rn = 1
) s ON t.trade_order_id = s.trade_order_id
WHEN MATCHED THEN UPDATE SET t.risk_id = s.risk_id, t.crm_biz_no = s.crm_biz_no
WHEN NOT MATCHED THEN INSERT (global_order_id, trade_order_id, risk_id, crm_biz_no, ...)
VALUES (NEXTVAL('seq_global_order'), s.trade_order_id, s.risk_id, s.crm_biz_no, ...);
适用场景:各系统ID不通用,但有可关联的公共字段(user_id+时间戳+金额等)。
方案三:One ID + 融合宽表
ID Mapping打通后,DWD层做"融合"——以权威源为骨干,其他系统补充字段,生成一张统一的订单宽表。下游所有报表只读这张表。
-- DWD融合宽表(单一事实表)
INSERT OVERWRITE TABLE dwd_order_unified PARTITION (ds='20240315')
SELECT
m.global_order_id,
-- 来自交易系统(权威源)
t.order_id, t.user_id, t.amount, t.status, t.create_time, t.channel,
-- 来自风控系统(补充)
r.risk_score, r.risk_decision, r.risk_check_time,
-- 来自CRM(补充)
c.customer_segment, c.assigned_sales,
-- 数据质量标记
CASE WHEN r.risk_id IS NULL THEN 'missing_risk' ELSE 'ok' END AS risk_status,
CASE WHEN c.crm_biz_no IS NULL THEN 'missing_crm' ELSE 'ok' END AS crm_status
FROM id_mapping_order m
JOIN dwd_trade_orders t ON m.trade_order_id = t.order_id
AND t.ds = '20240315'
LEFT JOIN dwd_risk_records r ON m.risk_id = r.id
AND r.ds BETWEEN '20240314' AND '20240316' -- 兼容跨日
LEFT JOIN dwd_crm_orders c ON m.crm_biz_no = c.biz_no
AND c.ds BETWEEN '20240314' AND '20240316';
MDM体系对比
| 阶段 | 做法 | 数据质量 | 落地难度 |
|---|---|---|---|
| 无治理 | 各系统独立采集 | 低(口径不一) | 0 |
| 指标统一 | 数仓加工时口径对齐 | 中 | 中(治理痛苦) |
| MDM初级 | 确权+ID Mapping | 高 | 中 |
| MDM完整 | +主数据平台+数据血缘 | 极高 | 高(平台投入) |
面试高频追问
追问一:业务方就是不愿意配合MDM治理怎么办?
常见困境,靠三招破局:① 用具体case打动决策层(一次大盘错算导致XX损失);② 找一个有强烈痛点的业务方做试点(比如财务对账老对不上的);③ 给业务方提供"治理收益"——比如打通后他们能直接复用其他系统的数据,不用重复开发。光讲规范没人听,要让业务方看到"自己也能受益"。
追问二:模糊匹配的ID Mapping怎么保证准确率?
分层置信度:① 强匹配——共同主键直接关联,置信度100%;② 中匹配——多字段(user_id+amount+time)联合匹配,置信度95%+,加阈值控制(金额误差<0.01、时间误差<60秒);③ 弱匹配——只有少量字段匹配,置信度<90%的标记为"待人工核对"。生产上强匹配能覆盖80%+,剩下的弱匹配每天产出一份报表给业务方人工修正。
追问三:权威源系统挂了怎么办?
两层兜底:① 数仓侧保留前一天快照,权威源挂了用T-1数据兜底;② 关键字段做"多源回填",比如交易系统挂了,用风控系统的amount临时顶上(标记数据来源标识),等权威源恢复后用真实值覆盖。这种降级方案要在SLA里写清楚,不能临时拍脑袋。
实战踩坑:ID Mapping因CDC延迟漏关联
有次发现日订单宽表里有大量"missing_risk"——风控字段为空。排查不是风控系统漏了,而是ID Mapping用T+1批做的,但风控CDC延迟了20分钟,凌晨0点跑Mapping时风控数据还没到,全没匹配上。后来把Mapping改成实时(Flink)+ T+1兜底(Spark),延迟到的数据后补,问题解决。
-- ❌ 反模式:纯T+1批跑Mapping
-- 凌晨2点跑,但风控CDC延迟到凌晨2:30才追平
INSERT INTO id_mapping_order ... -- 漏掉0:00-2:00产生但2:30才到的数据
-- ✓ 正确:实时Mapping + T+1兜底
-- 1) Flink实时关联(主链路)
SELECT t.order_id, r.risk_id
FROM trade_stream t
JOIN risk_stream r WITHIN INTERVAL '1' HOUR
ON t.user_id = r.user_id AND ABS(t.amount - r.amount) < 0.01
-- 2) T+2跑批兜底,补昨天延迟到的数据
MERGE INTO id_mapping_order m
USING (
SELECT t.order_id, r.id FROM ods_trade t
JOIN ods_risk r ON ...
WHERE t.ds = '${bizdate-1}' -- T-1数据,等所有CDC追平
AND NOT EXISTS (SELECT 1 FROM id_mapping_order WHERE trade_order_id = t.order_id AND risk_id IS NOT NULL)
) s ON m.trade_order_id = s.order_id
WHEN MATCHED THEN UPDATE SET m.risk_id = s.id;
解决方案:Lambda架构兜底——实时链路保证99%数据,T+1批兜底剩下的延迟数据。同时给"missing_xxx"字段加监控,比例超阈值就告警。这套机制让数据完整率稳定在99.95%+。
总结
主数据治理本质是"组织协同问题伪装成的技术问题"。核心三步:确权(每个字段一个权威源)、ID Mapping(打通各系统)、One ID融合(DWD一张表)。技术上不复杂,难在跨团队推动。面试时讲"治理思维+落地难点+实际收益",比讲技术细节分高得多。
下一篇聊CDC到Kafka的工具选型:Kafka Connect和Flink CDC到底用哪个更稳?
你们公司MDM做到什么程度了?最大的阻力是什么?评论区聊聊~
关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长