四层数仓 ODS→DWD→DWS→ADS,一套能落地的分层规范

数仓不分层,等于花钱建了一个数据沼泽。这篇给你一套能直接抄的分层规范。

做过数仓的人都知道ODS、DWD、DWS、ADS这四个词。但我在好几个项目里看到的情况是,分层写在文档里,实际跑起来全是跨层引用、ODS直连报表、DWD层堆着没清洗的原始数据。

分层不是画个架构图就完事,是要落到每一张表的命名、职责边界、数据流转规则上。这篇我把V企数据中台项目里实际用的分层规范整理出来,能直接拿去改。

先说清楚一件事,这套规范不是我自己发明的,底层逻辑来自Kimball维度建模理论。但理论到落地中间差着十万八千里,我补的就是这段距离。

为什么非要分层

我见过最极端的案例是G企的一个数据分析需求。业务要一张「各区域月度销售额」的报表,数据团队查了一下,发现同一个销售额指标在三个系统里有三个口径。销售系统按下单时间算,财务系统按开票时间算,物流系统按发运时间算。三边各跑各的,报表对不上,开会能吵一小时。

这个问题的根子不在计算,在数据源没有统一加工。如果有一个层把原始数据清洗标准化了,后面所有人用同一份数据,口径自然就统一了。这就是分层的意义。

说直白点,分层解决三件事。

第一,避免数据烟囱。 不分层的时候,每个需求都从源头抽数据自己加工,加工逻辑各写各的。十个人写十个ETL,逻辑有差异,结果就对不上。分层之后,公共加工逻辑下沉到DWD和DWS层,大家共用,烟囱自然就没了。

第二,控制数据质量。 原始数据从业务系统过来,脏数据是常态。手机号少一位、金额字段存了中文、日期格式不统一。如果直接拿去算报表,结果一定是错的。分层之后,ODS层保持原始不动,DWD层负责清洗,质量问题在DWD层就拦住了。

第三,性能和成本。 不分层意味着每次查数据都要从源系统全量拉,源系统扛不住,查询也慢。分层之后DWS层预先聚合好了,查的时候直接读汇总结果,速度快几个数量级。

四层各自干什么

一层一层说,每层我都用一句话定位,再展开细节。

ODS层,贴源层

ODS全称Operational Data Store,操作数据存储层。一句话定位,业务系统数据的原样副本

这层的规则很简单。

数据从业务系统通过CDC或者离线同步过来,存到ODS层,不做任何业务逻辑加工。字段名跟源系统保持一致,数据类型尽量保持一致(类型不兼容的做最小转换)。表结构跟源表一一对应,一张源表对应一张ODS表。

这块容易踩坑,ODS层不做清洗。哪怕源系统的数据脏得不行,ODS层也原样保留。原因是ODS层是数据的「存证」,万一后面清洗出了问题,你得能回溯到原始值。清洗是DWD层的事。

ODS层的数据保留周期建议至少90天,最好是180天以上。我见过有的团队ODS只保留7天,出了数据问题想回溯,原始数据已经被覆盖了,查都没地方查。

DWD层,明细数据层

DWD全称Data Warehouse Detail,明细数据层。一句话定位,清洗标准化后的明细数据

这层是整个数仓最累的一层,干的活最多。

数据从ODS层过来,在DWD层做这几件事。

字段清洗。空值处理(填充默认值或者标记为未知)、格式标准化(日期统一成yyyy-MM-dd、手机号统一11位)、异常值剔除(金额为负数的记录打标)。

维度退化。把源系统里的编码翻译成人能看懂的值。比如性别字段源系统存的是0和1,DWD层转成「男」和「女」。区域编码转成区域名称。

数据标准化。统一计量单位,统一枚举值。这是W1文章里说的那个「上海」问题的解决层,销售系统的「上海市」、物流系统的「沪」、财务系统的「SH」,在DWD层统一成标准编码。

维度建模。DWD层通常采用星型模型,事实表加维度表。事实表存业务过程数据,维度表存描述信息。比如销售事实表关联时间维度、区域维度、产品维度、经销商维度。

DWD层的数据是整个数仓的「single source of truth」,后面所有层都从DWD层取数据,不允许再回ODS层取。

DWS层,汇总数据层

DWS全称Data Warehouse Summary,汇总数据层。一句话定位,按主题预先聚合好的数据

这层的逻辑是,把DWD层的明细数据按常用的分析维度预先聚合好,存成汇总表。比如「各区域月度销售额」「各经销商年度维修台次」「各车型周度线索量」。

为什么要预先聚合?因为ADS层的报表查询如果每次都从DWD层全量扫描明细数据,性能扛不住。DWS层提前算好,ADS层直接读汇总结果,查询从分钟级降到秒级。

DWS层的设计原则是面向主题。一个主题建一张或者几张宽表,把相关的汇总指标放在一起。比如客户主题的DWS表可能包含客户的累计消费金额、最近一次购买时间、购买频次、客单价这些指标。

DWS层的粒度选择有讲究。太细了跟DWD层重复,太粗了ADS层不够用。我的经验是,DWS层通常按天或者按月做粒度,具体看业务查询频率。V企项目里我们大部分DWS表是按天的,少部分高频查询的按月。

ADS层,应用数据层

ADS全称Application Data Store,应用数据层。一句话定位,直接给报表和BI看的最终结果

这层最贴近业务端。数据从DWS层过来,做最后的加工,比如同环比计算、目标达成率、排行榜、Top N这些。表结构按报表需求设计,不追求通用,追求好用。

ADS层的表通常不多,但每张表都直接对应一个具体的报表或者看板。一张ADS表可能服务一个BI大屏、一个周报模板、或者一个数据API。

先立条规矩,ADS层不允许直接引用ODS层。如果ADS层需要某个ODS层的字段,说明DWD和DWS层漏了这个字段,应该回去补DWD和DWS,而不是绕过去直连ODS。

V企项目怎么落地的

V企数据中台项目是我做过分层规范落地最完整的一个。说说实际过程。

第一步是数据调研。花了两周把V企的十几个业务系统摸了一遍,每个系统有多少张表、数据量多大、更新频率、数据质量怎么样。输出了一张数据源清单和一张数据流向图。这一步别省,后面所有分层设计的基础都在这张清单上。

第二步是定分层规范。参考了Kimball理论和阿里数据中台规范,结合V企实际情况做了裁剪。定了几条硬规则。

ODS层表名格式 ods_源系统名_源表名_di(di表示日增量)或者 ods_源系统名_源表名_df(df表示日全量)。

DWD层表名格式 dwd_业务域_事实表名_di。业务域比如销售、售后、线索、财务。事实表名用业务过程命名,比如 dwd_sal_order_di(销售订单日增量)。

DWS层表名格式 dws_业务域_汇总粒度_统计周期。比如 dws_sal_region_d(销售域区域粒度日汇总)。

ADS层表名格式 ads_应用场景_表名。比如 ads_dashboard_region_sales_d(大屏区域销售日报)。

第三步是开发。先做ODS层,把数据接进来。再做DWD层,清洗和标准化。然后DWS层,按主题建汇总表。最后ADS层,对接报表。

开发过程中遇到一个典型问题。DWD层做维度退化的时候,发现源系统的区域编码跟标准维度表对不上。V企有自己的一套区域编码,跟国标不完全一致。解决方案是在DWD层加了一张映射表,做编码转换。这种映射表也是DWD层的一部分,叫桥接表。

还有一个坑是数据回溯。DWD层改了清洗逻辑之后,历史数据怎么办?我们的做法是每次改逻辑都记录版本,用版本号区分。回溯的时候指定版本号重新跑。这个机制在V企项目里跑了大半年,迭代了十几个版本,没出过数据丢失的问题。

表命名规范速查表

把命名规范整理成一张表,直接拿去改。

层缀命名规则

前缀

示例

ODS

ods_

ods_crm_customer_di

DWD

dwd_

dwd_sal_order_di

DWS

dws_

dws_sal_region_d

ADS

ads_

ads_dashboard_sales_d

后缀含义

后缀

含义

适用场景

_di

日增量

ODS层和DWD层,每天同步新增和变更数据

_df

日全量

ODS层,每天全量覆盖(适用于数据量小的表)

_d

日粒度汇总

DWS层和ADS层,按天聚合

_m

月粒度汇总

DWS层和ADS层,按月聚合

_y

年粒度汇总

DWS层和ADS层,按年聚合

业务域缩写

业务域

缩写

示例表名

销售

sal

dwd_sal_order_di

售后

svc

dwd_svc_repair_di

线索

led

dwd_lead_clue_di

财务

fin

dwd_fin_invoice_di

客户

cus

dws_cus_profile_m

产品

prd

dim_prd_vehicle

维度表的命名单独说一下。维度表用 dim_ 前缀,不分层。比如 dim_prd_vehicle(产品维度-车型)、dim_org_dealer(组织维度-经销商)、dim_geo_region(地理维度-区域)。维度表通常在DWD层和DWS层之间,被多层引用。

常见错误

做了这么多年,分层规范落地最容易出问题的就这几个。

错误一,ODS层做清洗。 有团队觉得ODS层直接清洗了省事,DWD层就不用再做了。问题是清洗逻辑改了之后,ODS层的原始数据已经被污染了,没法回溯。ODS层必须保持原始,清洗一律放DWD层。这条线不能破。

错误二,跨层引用。 DWS层直接读ODS层,或者ADS层直接读DWD层绕过DWS。每次跨层引用都是在挖坑,后期排查数据问题的时候根本追不到血缘。V企项目里我定了一条规则,DWS层只允许引用DWD层和维度表,ADS层只允许引用DWS层。代码review的时候卡这条。

错误三,DWD层不做维度建模。 有的团队DWD层就是把ODS层的数据原样复制一份改个表名,没做事实表和维度表的拆分。这样DWS层做聚合的时候,每次都要join一堆维表,性能差且逻辑重复。DWD层一定要做维度建模,把事实表和维度表分开。

错误四,命名不规范。 表名一会驼峰一会下划线,一会中文一会英文。数仓到后面几百张表的时候,没有规范就是灾难。所有表名统一小写下划线,用业务域缩写,不要用中文。字段名也是同理。

错误五,DWS层过度设计。 有些团队DWS层建了几百张表,大部分根本没人用。DWS层的表应该按实际查询需求来建,有报表需求才建DWS表。先建高频的,低频的后面再补。别一上来就想覆盖所有场景,不现实。

错误六,没有数据血缘。 分层做完之后不记录血缘关系,出了问题不知道数据从哪来到哪去。V企项目里我们用华为云DataArts做血缘管理,每张表的上下游关系自动记录。没有云平台的可以用开源工具比如Apache Atlas,或者最简单的,维护一张Excel登记表级别血缘。

写在最后

数仓分层这事,理论不难,难在执行。规范定好了,能不能守住是关键。代码review的时候卡不卡命名规范,跨层引用能不能拦住,新需求来了是走分层还是走捷径。这些细节决定了数仓最终是资产还是负债。

我的经验是,前三个月最难。团队不习惯规范,觉得麻烦,总想抄近路。但坚持三个月之后,大家都尝到甜头了。查数据快了,口径统一了,排查问题有血缘可追了。后面就是惯性维护的事。

如果你正在搭数仓或者重构数仓,建议先把分层规范定下来,包括每层职责、表命名规则、跨层引用红线。然后从最核心的业务域开始做,跑通一个闭环再铺开。别一上来就想全覆盖,会把自己累死。


作者,凌波,18年汽车行业数字化老兵,CDGP数据治理专家。

博客园「凌波微数」,持续分享数据治理、数据架构、企业数字化的实战经验。如果对你有用,点个推荐吧~~

下一篇,《数据质量这事,甲方和乙方想的完全不一样》

posted @ 2026-08-12 20:49  凌波微数  阅读(59)  评论(0)    收藏  举报