【数据中台·3】数仓分了五层,三层在越权,分层分了个寂寞
【数据中台·3】数仓分了五层,三层在越权,分层分了个寂寞
这是【数据中台】系列第3篇。上篇讲指标体系踩坑,这篇讲分层越权。
架构文档一摞摞,ODS、DW、DWD、DWS、ST,每层职责写得清清楚楚。实际跑起来呢?ODS开始写CASE WHEN做业务映射,DW开始JOIN维度表,DWS把DWD整张表COPY过来改个名——五层架构,三层在干别人的活,分层分了个寂寞。
这篇用一张运单的真实流转,讲清楚越权是怎么发生的,以及怎么守住边界。
ODS层:一个CASE WHEN,口径锁死三个月
ODS层最常见的越权:写CASE WHEN做业务映射。
我见过一个项目,ODS层这么写:
-- ODS层直接做了产品类型映射
case
when product_type_code = 'RETURN' then '退件'
when temperature_range_code = 'COLD' then '冷链'
...
end as product_type_name
三个月后,业务改了映射规则:冷链要拆成"冷藏"和"冷冻"。下游DW、DWD、DWS全依赖ODS这份数据,ODS已经覆盖写入了,历史数据改不回来。
结果:要么重刷三个月全量,要么口径从此锁死在ODS层。
ODS层只做一件事:异构数据源接入,原样保留。 格式标准化可以做(字段类型统一、时区转换、JSON解析),业务判断不能做。映射留给DWD,ODS只存原值。这是最便宜的防线——ODS不动业务逻辑,后面就不会连锁越权。
DW层:两层其实可以合并成一层
DW层干两件事:去重 + 时间轴重建。
去重是因为ODS层同一主键可能有多条记录(业务系统变更导致),DW层按主键保留最新版本。时间轴重建是因为ODS按modified_time拉增量,分析需要按waybill_time切分区。
最常见的越权:在DW层做维度JOIN。
-- ❌ DW层越权:开始JOIN维度表
select
a.waybill_no,
b.site_name as send_site_name -- 不该在这做
from dw.dw_waybill_detail_inc a
left join dim.dim_org b on a.send_org_code = b.site_code
后果:DWD层只剩"复制DW+改字段名"的活,两层合并。
但我更想说的是:ODS和DW做的事情其实很近,可以考虑合并。
- ODS:异构数据源接入,原样保留,15天增量窗口
- DW:去重+时间轴重建
两层之间没有业务逻辑差异,只是清洗程度不同。ODS就是个增量缓冲区,DW才是真正的贴源层。很多团队把两层合并成一层叫"贴源层",DW直接做接入+去重+标准化,一步到位。
能少一层就少一层,前提是合并后的DW守住边界:只做去重和标准化,不做维度JOIN,不做业务映射。
连锁反应:DWD顺手一聚合,后面全乱套了
分层最怕的不是一层越权,是连锁反应。
DWD层的本职是维度JOIN——把业务编码替换成维度表的名称、层级。但DWD发现上游DW已经把维度JOIN做了,自己没活干,就顺手加了COUNT/SUM:
-- DWD层顺手做了聚合
select send_site_code, count(waybill_no) as ewb_count
from dwd.dwd_ewb_basic_detail_inc
group by send_site_code
DWS层一看,DWD已经聚合了,自己还聚合个啥?直接COPY:
-- DWS层COPY DWD整表
insert overwrite table dws.dws_ewb_site_cargo_volume_basic_info
select * from dwd.dwd_ewb_basic_detail_inc -- 没有聚合逻辑
ST层一看,DWS跟DWD一模一样,我还费劲从DWS拉干嘛?直接查DWD:
-- ST层绕过DWS,直接查DWD
select province_area_code, count(waybill_no) ewb_count
from dwd.dwd_ewb_basic_detail_inc -- 不该查DWD
group by province_area_code
然后问题来了:DWS过滤了退件和作废,ST查DWD时忘了过滤,报表数字跟DWS出来的对不上。对数对到凌晨,最后发现是ST绕过了DWS。
连锁反应的根因:ODS做了映射→DW跟着做JOIN→DWD没活干就顺手聚合→DWS看到DWD已经聚合了就COPY→ST看到DWS跟DWD一样就直接查DWD。每一层的越权都是上一层逼出来的。守住一层,后面就不会连锁崩。
守住边界:三条禁令就够了
不需要厚厚的规范文档。三条禁令够了:
1. ODS层禁止CASE WHEN — 业务映射全部放DWD,ODS只存原值
2. DWD层禁止GROUP BY — 聚合全部放DWS,DWD只做维度JOIN
3. ST层禁止FROM DWD — ST只读DWS,需要明细查DWD,不需要绕过DWS
运单的完整流转就是守住这三条的结果:
每层干自己的事,下游不回头,上游不越权。分层才有意义。
写在最后
分层这个词,听起来像架构师才操心的事。但分层出问题的时候,疼的不是架构师,是每天对数的你。
ODS写了业务逻辑,改口径要重刷全量;DW做了维度JOIN,DWD层变成空壳;DWS直接COPY DWD,ST回头查DWD——每一层的越权都在给下一层挖坑,最后坑全堆在你身上,对数对到凌晨。
守住边界不需要厚厚的规范文档,三条禁令就行:ODS禁止CASE WHEN,DWD禁止GROUP BY,ST禁止FROM DWD。能少一层就少一层,能少一条规则就少一条规则。
分层不是分五个schema就完了,是每层都在干自己的事。
更多推荐
所有评论(0)