
《新兴数据湖仓设计与实践手册·从分层架构到数据湖仓架构设计(2025 年)》 系列文章将聚焦从数据仓库分层到数据湖仓架构的设计与实践。手册将阐述数据仓库分层的核心价值、常见分层类型,详解分层下的 ETL 架构及数据转换环节,介绍数据仓库分层对应的技术架构,并以贴源层(ODS)、数据仓库层(DW)、数据服务层(DWS)为例,深入剖析数湖仓分层设计,最后探讨数据仓库技术趋势并进行小结。
本文为系列文章第三篇,详细剖析了数据仓库分层下的贴源层和数据仓库层设计。
👉上文回顾:《(一)从分层架构到数据湖仓架构:数据仓库分层的概念与设计》
(二)从分层架构到数据湖仓架构:数据仓库分层下的技术架构与举例
贴源层(ODS, Operational Data Store)

数据引入层(ODS,Operational Data Store),也称为数据基础层。
这一层主要存放从源系统引入的原始数据,几乎不做任何加工处理,目的是将基础数据直接同步到数据仓库中,便于后续的数据处理工作。在结构上,ODS层的数据与源系统保持高度一致,是数据仓库的数据准备区。
在现代数据架构中,ODS层的数据获取方式逐步向CDC(Change Data Capture,变更数据捕获)模式转变,尤其在数据湖和实时数据仓库的场景中。新型的ETL工具已经可以支持源系统的DDL(数据定义语言)变更,这意味着当源系统的字段发生变化时,ODS层可以自动更新表结构,无需手动调整。例如,WhaleTunnel这样的工具支持多种系统的DDL变更捕获,保证了ODS层数据在数据仓库、数据湖或实时数据仓库中的一致性,不会因为源系统的改变而中断ETL流程。
ODS层的数据通常分为当前数据和历史数据两部分:
- 当前数据表:用于存储最近需要处理的数据,保持最新的数据状态。
- 历史数据表:保存已处理完的数据以备后续使用,一般保留3-6个月后清理,具体时间视项目需求而定。如果源系统的数据量较小,也可以选择更长时间的保存,甚至全量保存。
ODS层的作用:数据清洗和规范化
尽管ODS层主要作用在于数据引入,但并非完全不做处理。此层通常会进行基本的数据清洗,例如:
- 处理异常字段、规范化字段命名、统一时间格式
- 确保数据一致性,为后续数据处理和特征工程奠定基础
一些公司会选择在ODS层就进行初步的清洗和过滤,而另一些则将更多的数据加工留在DWD层。选择在哪里进行清洗取决于企业的技术规范和需求。在实际开发中,大多数企业会在将数据存入ODS时进行基本处理,以减少后续工作量。
数据来源
- 业务数据库:公司各业务系统生成的结构化数据。
- 日志数据:包括用户行为日志和系统后台日志。埋点数据首先经由Nginx上报,再由Flume收集并存储在Kafka等消息队列中,随后由SeaTunnel或WhaleTunnel拉取至离线数据仓库(如HDFS)。
外部数据:包括合作伙伴提供的数据或爬虫采集的数据,整合后用于补充业务分析。
存储策略设计
按时间划分
数据来源可按时间进行分区存储,通常以日为粒度,也有公司采用年、月、日三级分区以优化存储效率。数据在进入数据仓库前进行基础清洗,如格式错误数据的剔除、关键信息缺失的过滤等,以保证数据质量。数据可分为实时和离线两种处理模式。
离线数据处理
离线数据通常通过定时任务(如每日批量任务)从业务系统或数据库中抽取。典型的日计算任务会在凌晨执行,通过SeaTunnel、DataX或WhaleTunnel从业务数据库提取数据,计算前一天的业务指标,并生成报表。Hive、Spark常用于批量计算,计算结果存储于Hive、HBase、MySQL、Elasticsearch或Redis等系统中,供后续分析使用。
实时数据处理
实时数据源主要来自日志埋点数据或业务数据库,常用于实时推荐、用户画像等业务需求。Spark Streaming和Flink负责实时计算,结果通常写入Elasticsearch、HBase或Redis。实时数据源可利用WhaleTunnel监控MySQL的Binlog变化,将数据实时写入Kafka或HDFS。
按方式划分
在实际应用中,可根据需求选择增量、全量或拉链存储方式。
增量存储
增量存储通常按天分区,以业务日期为分区字段,每日存储新增的业务数据。例如,用户A在1月1日访问了店铺B,生成记录t1,并于1月2日访问店铺C,生成记录t2。增量存储会将t1存入1月1日的分区,将t2存入1月2日的分区。如果用户A在1月1日购买商品B(生成t1记录)并在1月2日退货(更新t1记录),增量存储会将初始购买记录存于1月1日分区,退货更新后的记录则存于1月2日分区。
对于交易日志和行为日志等高频变更的数据表,增量存储能减少存储成本和数据冗余。下游分析需求一般只需聚合后的汇总数据,因此不需要长期保存全量的历史数据。
全量存储
全量存储以日为分区,每个分区记录当天的完整业务数据快照。例如,1月1日,卖家A发布了商品B和C,生成记录t1和t2。1月2日,卖家A下架商品B并上架商品D,此时商品B记录t1会更新,商品D生成新记录t3。全量存储会在1月1日分区保存t1和t2,在1月2日分区保存更新后的t1、t2和t3。
对于数据量较小、变化缓慢的维度数据(如商品分类),全量存储能够保证数据完整性和易用性。
拉链存储
拉链存储通过在表中增加开始时间(start_dt)和结束时间(end_dt)两个时间戳字段,记录每次数据变更,并以时间为分区字段。这种方式适用于记录所有变更数据的历史快照,为分析数据演变过程提供支持。
目前WhaleTunnel已经支持了CDC、增量和全量数据抽取模式,也支持自定义插入规则,是用户使用的快速工具。
缓冲层
概念介绍
缓冲层(也称接口层或Stage层)用于存储每天的增量和变更数据。该层暂存从源系统采集的原始数据,以便后续数据处理和ETL流程的使用。
数据生成方式
数据通常通过Kafka直接接入缓冲层,对于包含update、delete和insert操作的业务表,会每日生成变更日志;而仅有insert操作的业务表,则直接将数据进入明细层。
- 建议方案:Apache SeaTunnel或WhaleTunnel生成的CDC日志直接进入缓冲层。如果业务涉及拉链数据,同样将其存放于缓冲层,以确保数据变更的准确记录。
日志存储方式
缓冲层的日志数据以Impala外部表形式存储,采用Parquet文件格式。这种方式不仅提高了存储效率,还便于MapReduce等处理引擎对数据的快速访问和处理。
日志清理策略
对于日志数据,通常只保留最近几天的数据以节省存储空间。
- 建议方案:考虑长期存储重要日志数据,以便于历史数据回溯和审计。
表的Schema和分区策略
通常按天分区数据,以partitioned by时间字段进行存储。这样不仅简化了数据管理,还能提升查询效率。表的Schema设计遵循源系统的结构,以确保数据的一致性和完整性。
库和表的命名规范
- 库名:ods,表示数据的贴源层。
- 表名:格式建议为ods_日期_业务表名,例如ods_2024_10_sales,便于管理和查询。
Hive表类型
在缓冲层中使用Hive的外部表管理数据,外部表的文件可以存储在非默认的HDFS路径中,这样当删除表定义时,实际存储文件不会被删除,保障数据安全。
业务表使用Hive的内部表,当删除表定义时,关联的HDFS文件也会被删除。此方式适合临时或不重要的数据存储,避免重要数据的误删。
数据仓库层设计(DW,Data Warehouse)
数据仓库层(DW层)是数据仓库设计的核心层,负责对来自贴源层(ODS层)的数据进行主题化建模,以支持高效的业务分析和决策。DW层根据业务主题划分领域,为各主题构建清晰的数据视图,过滤掉无关决策的数据,专注于支持企业关键分析。在该层,通常会存储业务系统的所有历史数据,例如保存10年以上的数据,为BI系统提供全面的历史数据支持。
数据内容和结构
在DW层中,主要存储三类数据:
- 明细事实数据:基于ODS层的原始数据加工而成,包含业务过程中的细节信息。
- 维表数据:描述性数据(如客户信息、产品分类等),同样从ODS层加工生成。
- 公共指标汇总数据:基于维表和明细数据汇总而成,为业务分析提供标准化的核心指标。
DW层的细分
DW层通常进一步划分为三个子层:维度层(DIM)、明细数据层(DWD)和汇总数据层(DWS),并使用维度建模方法为数据设计结构,以确保高效的数据管理和访问:
- 维度层(DIM):定义维度数据,如用户、产品等,用于描述事实表中的相关业务数据,帮助业务数据的理解和查询。
- 明细数据层(DWD):存储经过整理的细粒度数据,保持原始数据的完整性,但格式已适合进一步分析和使用。DWD层中的数据从ODS层数据加工而来,精细化了原始数据,确保高可用性。
- 汇总数据层(DWS):通过汇总维度和明细数据,生成更宽表结构的公共指标,便于多场景复用。这一层根据特定的统计需求,对明细数据进行聚合,减少数据的重复加工,提升查询和计算的效率。
数据模型设计
DW层采用维度建模,将维度表和事实表建立外键关联关系,以减少数据冗余、提高数据的组织效率。维度模型不仅简化了业务分析的复杂性,还提升了DW层的数据易用性。在汇总数据层中,通过宽表设计将不同统计维度关联,建立高度复用的公共指标数据层,从而减少下游数据开发的重复劳动。
维度层(DIM,Dimension)
维度层以业务维度为建模核心,根据每个维度的业务语义,定义维度属性和关联关系,形成标准化的数据分析维表。此层通过为各维度添加属性、定义关联关系等,明确计算逻辑,实现一致性的数据描述。为了避免在维度模型中出现冗余数据,维度表通常采用雪花模型结构,通过拆分属性表来减少数据重复,实现更加规范的维度建模。
明细数据层(DWD,Data Warehouse Detail)
明细数据层以具体的业务过程为核心进行建模,旨在捕捉业务活动的最细粒度信息,构建详细的事实表。这些事实表保留了业务过程的每一个细节,确保数据的完整性和精准性。在实际设计中,对于一些关键的属性字段,可以适当进行冗余处理,即采用宽表化设计,以提升查询效率,减少多表关联带来的性能开销。这种做法在确保数据精细化的同时,兼顾了系统的易用性和高效性。
汇总数据层(DWS,Data Warehouse Summary)
汇总数据层(DWS)以分析主题为核心进行建模,围绕业务指标需求,构建标准化的汇总表,为上层应用提供一致的公共指标。这一层基于宽表设计,将统计逻辑物理化,确保数据的命名规范和口径一致,从而支持高效的分析查询。汇总数据层包含多种主题的宽表和明细事实表,为业务提供统一的统计视角。
- 主题域:以业务过程为视角,将业务活动进行抽象和分类。例如,下单、支付、退款等事件可归类为不同的业务主题域,主要针对公共明细层(DWD)进行主题划分。
- 数据域:以分析需求为导向,将业务过程和维度进一步抽象,形成数据域。数据域划分在公共汇总层(DWS)中进行,用于满足各类业务分析需求。
层次结构与数据处理
- DWD(Data Warehouse Details,数据明细层):以业务过程为驱动,主要从ODS数据层抽取原始数据并进行清洗和规范化处理,确保数据的完整性和一致性。清洗内容包括去除空值、转换脏数据、枚举值统一、以及异常值过滤等。
- DWS(Data Warehouse Base,数据基础层):该层存储客观数据,主要作为中间层,为DWS层提供基础指标支持。可以视为大量中间指标的存储区,聚焦客观的业务事实。
- DWS(Data Warehouse Summary数据服务层):基于DWB中的基础数据,DWS层整合并汇总成以主题域为中心的宽表数据,用于OLAP分析、业务查询和数据分发。DWS的宽表设计适用于高效查询和聚合分析,满足各种业务部门的统计需求。
数据汇总和轻度聚合
汇总数据层在数据服务和分析场景中发挥关键作用。主要对ODS和DWD层的数据进行轻度聚合和汇总,确保数据粒度适用于业务需求,支持复杂分析和快速响应上层查询需求。
1)公共维度层(DIM,Dimension)
公共维度层(DIM)通过维度建模来构建企业的一致性维度,以确保在数据分析和计算过程中口径统一,避免因算法或指标不一致而引发的偏差。维度层的主要目的是定义和标准化数据分析的基本属性,例如国家代码、地理位置、产品分类等。通过为所有业务共享的维表建立统一的结构和命名规范,DIM层成为业务数据的标准参照层。
公共维度层的构成
- 维表:维表是逻辑维度的物理实现,将每个维度及其属性具体化。为了提高查询效率和降低数据冗余,维表通常采用宽表设计原则。高基数的维表(如用户、商品等)可能包含数百万甚至数亿条记录,而低基数的维表(如枚举配置、日期等)则记录数相对较少。
维度层的设计要点
- 维表设计原则
在设计维表时,建议将单表的数据量控制在1000万条以内。对于高基数表,可采用Map Join操作优化查询性能。同时,避免频繁更新维表,针对缓慢变化的维度(如商品分类)可采用拉链表方式记录变更历史。 - 维表命名规范
公共维度表命名通常以dim_开头,表示与具体业务无关、可以在各个业务模块中复用的维度。例如,公共区域表命名为dim_pub_area,商品表命名为dim_asale_item。这种命名规范便于识别表用途和主题,提高数据管理的清晰度。 - 粒度定义
维度表中的数据粒度是业务过程的最小描述单位。例如,一条订单记录的粒度可能为“每次下单”。粒度可通过维度属性组合来描述,如“国家-城市-区县”组合用于表示地理位置的细节。粒度定义需精细,以满足后续分析需求。
维度建模步骤
- 选择业务过程
选择业务系统中的关键业务过程(如下单、支付、物流等)进行建模。中小企业通常会选取所有业务过程,而大企业则聚焦于分析需求的主要业务线,以减少数据冗余和维护成本。 - 声明粒度
粒度定义明确数据的细化程度。建议选择最小粒度,以支持更细粒度的指标计算。例如,在订单数据中,每个商品项代表一行数据记录,粒度为“每次下单”。保持细粒度可以灵活支持不同的统计需求,避免数据粒度过粗导致的信息丢失。 - 确定维度
维度用来描述业务中的“谁、何处、何时”等信息,帮助分析不同维度的指标变化。例如,为支持订单量按时间、区域或用户的统计分析,需定义时间、地区和用户维度。维度表设计遵循星型模型原则,在必要时进行维度退化。 - 确定事实
事实是业务中的度量数据,如订单金额、购买次数等。事实表中的每条记录反映某一业务活动的度量结果。通过宽表设计适当冗余重要字段,以提高查询效率。DWD层(数据明细层)以业务过程为驱动,而DWS层(汇总层)则是以需求为导向,与维度建模无直接关联。
主题、主题域与维度模型
- 主题
数据仓库中的数据组织围绕不同的主题(如财务、销售、客户)展开。主题定义了数据仓库的主要分析方向,每个主题对应一个业务分析领域。例如,“财务分析”是一个主题,涵盖收入、支出、盈利等指标。 - 主题域
主题域是多个相关主题的集合,便于数据的分层组织和分类管理。主题域的划分应由业务部门与数据仓库设计人员共同决定,考虑业务的关联性和分析需求。例如,销售主题域可包含订单分析、客户行为、广告投放等主题。
主题域划分原则
主题域的划分逻辑可以基于不同的业务需求或部门需求:
- 按业务过程:如电商平台可设立“广告域”、“客户域”等主题域,进一步分为“库存管理”、“销售分析”等具体主题。
- 按需求方:如财务部门的主题域可能包含“工资分析”、“投资回报分析”等内容。
- 按功能或应用:如“朋友圈域”可包含用户动态、广告数据等,适用于社交平台数据的主题划分。
- 按部门:如运营域、技术域,分别涵盖与各部门工作相关的主题(如运营域中的“活动效果分析”)。
主题域划分不必一次性完成,可采用迭代方式,从确定的主题开始逐步扩展,最终形成符合行业标准的主题模型。
2)数据明细层(DWD,Data Warehouse Detail)

数据明细层(DWD)是数据仓库和业务系统间的隔离层,主要用于提升数据的质量和一致性,确保存储的数据符合分析需求。DWD层接收并清洗来自ODS层的原始数据,通过去噪、去重、脱敏等处理后,生成干净、准确的明细数据表,以支持业务分析。该层还会适度进行维度退化处理,将一些必要的维度字段直接存储在事实表中,以减少表关联,提高查询性能。
数据清洗与处理
DWD层的数据需要符合严格的数据质量标准,数据在装入前进行多种处理:
- 数据清洗
- 去除空值、脏数据:例如丢失关键字段(如订单ID为空)的记录、格式错误的数据。
- 敏感数据脱敏:对手机号、身份证等敏感信息进行加密或脱敏处理。
- 去除无效数据:如无时间戳的数据(视业务需求)。
- 会话切割:如针对App日志数据的场景,将用户进入后台再返回前台的操作分割为新的会话,方便后续行为分析。
- 数据映射与转换
- 地理位置映射:将GPS经纬度转换为省市区地址,采用geohash或IP地址转换库(如ip2region)进行快速定位,也可借助高德、百度地图API。
- 时间标准化:将时间戳转换为年、月、日、周、季度等信息。
- 数据规范化:对来自不同来源的数据进行格式统一,例如布尔值(0/1转换为true/false)、空值(统一为null)、日期格式(标准化为YYYY-MM-dd HH:mm:ss)。
- 维度退化
对于一些高基数的维度字段(如订单ID),直接存储在事实表中而不创建单独的维度表。这些退化维度可以简化数据结构,减少关联,提升数据查询的效率。
明细粒度事实表设计
DWD层以业务过程为核心进行建模,根据每个业务过程(如下单、支付、退款等)的特点,构建最细粒度的事实表。这些明细事实表保留了业务过程的全部细节,且一般会将一些常用的维度字段冗余存储,采用宽表设计以提升性能。这些事实表也被称为“逻辑事实表”。
数据质量控制
DWD层的数据粒度与ODS层保持一致,但在此基础上提供更严格的数据质量保证。DWD层还会适度进行维度退化,例如将商品类别的多级维度(如一级、二级、三级类别)或时间、地域等常用维度直接存储在事实表中,简化关联,提高数据的使用效率。
- 清洗比例:对于大数据量的数据,建议清洗掉低于0.01%的数据,如每万条记录中去除一条不合规数据。
- 表数量优化:通过合并相似数据,合理控制表数量,将过多的表精简为更易管理的结构。例如,将上万张表优化为三千张或一千张表,以便于后续的维护和扩展。
总结来说,DWD层在保持细粒度的前提下,提供规范化、清洗后的明细数据,为上层的业务应用和分析提供了干净、标准化的数据支撑。这一层的优化和处理不仅提升了数据仓库的性能,还显著降低了数据冗余,提高了数据的可用性和易用性。
明细粒度事实表设计原则
- 单维度关联:每个明细粒度事实表只应与一个核心维度关联,保持数据模型简单、清晰。
- 业务过程相关性:仅包含与业务过程直接相关的事实数据,确保每个事实表准确反映其特定业务过程。
- 声明粒度:在定义维度和事实之前,必须先明确数据粒度,即一行数据代表的具体业务意义。
- 一致性和可加性:确保事实的单位一致,且尽量将不可加的事实分解为可加性组件,以支持更广泛的统计需求。
- 统一粒度:一个事实表中仅能包含单一粒度的事实数据,避免混合不同粒度的事实。
- 处理Null值:对Null值进行合理处理,以避免数据分析过程中产生意外结果。
- 退化维度应用:使用退化维度(如订单ID等高频维度)直接冗余存储在事实表中,以简化数据表关联,提升查询效率。
数据处理与存储方案
- 数据合成:采用全量合成策略,每天合并前天的全量数据和昨天的新增数据,生成一个新的数据表,覆盖旧表。同时,使用历史镜像按周、月或年存储快照。
- 日志存储方式:使用Impala的外部表和Parquet文件格式存储日志数据。建议在DWD层和下层数据均使用Impala内表,以实现更高效的静态或动态分区管理。
- 分区设计:默认按天创建分区。如果数据没有时间属性,可根据业务需求选择合适的分区字段。
- 库与表命名规范:库名为dwd,表名格式建议为dwd_日期_业务表名。对于增量表和全量表,用i表示增量,f表示全量。例如:
- odwd_asale_trd_ordcrt_trip_di:表示A电商公司航旅机票订单下单的增量事实表,按日更新。
- odwd_asale_itm_item_df:表示A电商公司商品快照的全量事实表,按日刷新。
明细粒度事实表设计示例
- 以交易商品信息事实表(dwd_asale_trd_itm_di)为例:

(item_id BIGINT COMMENT '商品ID',item_title STRING COMMENT '商品名称',item_price DOUBLE COMMENT '商品价格',item_stuff_status BIGINT COMMENT '商品新旧程度_0全新1闲置2二手',item_prov STRING COMMENT '商品省份',item_city STRING COMMENT '商品城市',cate_id BIGINT COMMENT '商品类目ID',cate_name STRING COMMENT '商品类目名称',commodity_id BIGINT COMMENT '品类ID',commodity_name STRING COMMENT '品类名称',buyer_id BIGINT COMMENT '买家ID'
)
COMMENT '交易商品信息事实表'
PARTITIONED BY (ds STRING COMMENT '日期')
LIFECYCLE 400;

此表设计为按天分区,数据存储生命周期为400天,用于存储每日更新的商品交易信息。通过ds字段管理数据的时间分区,便于查询和管理。