【离线数仓项目】——电商域DWD层开发实战
摘要
本文主要介绍了离线数仓项目中电商域DWD层的开发实战。DWD层是数据仓库架构中的明细数据层,对ODS层的原始数据进行清洗、规范、整合与业务建模。它具有数据清洗、标准化、业务建模、整合、维度挂载等作用,常见设计特征包括一致性、明细级建模、保留历史记录等。文中还给出了交易支付场景下的DWD层表示例,以及DWD层设计规范、采集策略、实战示例和数据思考等内容。
1. DWD数据层
1.1. DWD层简介
DWD(Data Warehouse Detail)层是数据仓库架构中的明细数据层,用于对ODS层的原始数据进行清洗、规范、整合与业务建模,使之具有较强的业务含义,成为构建数据中台的重要数据基础。它是从 ODS 层向上进行逻辑建模的第一步,常用于构建宽表、事件表、拉链表、状态记录表等。
1.2. DWD层作用
作用类别 | 说明 |
数据清洗 | 去除脏数据、空值、格式不规范等问题,提升数据质量 |
数据标准化 | 对字段含义、命名、编码值、时间格式、货币单位等做标准统一处理 |
业务建模 | 按业务实体(如用户、订单、交易)建模为宽表或事件表,为后续主题分析提供一致数据基础 |
数据整合 | 将来自多个源系统的同类业务数据进行统一抽取和整合(如多个支付通道的订单明细) |
维度挂载 | 挂载 DIM 层的维度表,形成维度丰富的明细宽表,支持多维分析 |
承上启下 | 是数据仓库的“中枢层”,为 DWS(主题层)、ADS(应用层)提供精细化、结构化的数据支撑 |
1.3. DWD层常见设计特征
特征类型 | 说明 |
一致性强 | 字段命名、口径定义、粒度统一(如时间统一到天、金额单位统一为元) |
明细级建模 | 表数据一般保留业务最原始的粒度(如一笔交易、一条订单、一条用户行为) |
保留历史记录 | 支持历史记录保留(如拉链表),便于审计和行为追溯 |
结构标准化 | 建议字段如:biz_date、update_time、create_time、source_id等标准字段 |
宽表设计 | 通过字段展开、维度挂载,构建宽表结构,减少多表 join 依赖 |
按业务实体划分 | 表通常以业务对象划分,如 dwd_user_info、dwd_order_detail、dwd_payment_result 等 |
1.4. 交易支付场景下的DWD层表示例
表名 | 表类型 | 粒度 | 说明 |
dwd_trade_order_detail | 明细表 | 订单号 | 交易订单明细(金额、支付方式、商品明细等) |
dwd_payment_result_event | 事件表 | 支付结果事件ID | 记录每次支付成功/失败通知事件 |
dwd_user_payment_zipper | 拉链表 | 用户维度 | 用户的支付偏好、支付等级等随时间变化的数据记录 |
dwd_refund_detail | 明细表 | 退款编号 | 每笔退款的明细数据(原订单、退款金额、原因等) |
dwd_payment_channel_daily | 聚合表 | 渠道+日期粒度 | 每日每支付渠道的汇总信息,用于运营监控等 |
1.4.1. ✅ dwd_trade_order_detail
(交易订单明细表)
字段名 | 类型 | 说明 | 备注 |
| STRING | 订单ID(主键) | 唯一标识一笔交易订单 |
| STRING | 用户ID | 可与用户维度挂接 |
| STRING | 商品ID | 可与商品维度挂接 |
| STRING | 商品名称 | 从维度表中冗余过来,便于查询 |
| DECIMAL(10,2) | 订单总金额 | 单位为“元”,统一精度 |
| DECIMAL(10,2) | 实际支付金额 | 包含优惠、红包等扣除 |
| DECIMAL(10,2) | 优惠金额(折扣/红包/优惠券) | |
| STRING | 支付方式(如:微信、支付宝、银行卡) | 可字典编码 |
| STRING | 订单状态(如:已支付、待支付、已取消) | 建议字典统一编码 |
| TIMESTAMP | 订单创建时间 | |
| TIMESTAMP | 支付完成时间 | |
| TIMESTAMP | 取消时间(如果有) | |
| DATE | 业务日期(冗余字段) | 用于分区,便于按天分区管理 |
| TIMESTAMP | 数据入仓时间 | 建议添加 |
1.4.2. ✅ dwd_payment_result_event
(支付结果事件表)
字段名 | 类型 | 说明 | 备注 |
| STRING | 支付事件ID(主键) | 如支付网关返回的一次支付回调事件 |
| STRING | 关联订单ID | 可与订单明细表关联 |
| STRING | 用户ID | |
| STRING | 支付渠道(微信、支付宝、银联等) | 可字典编码 |
| STRING | 支付状态(成功、失败、处理中等) | 建议字典编码 |
| TIMESTAMP | 实际支付时间 | |
| STRING | 支付失败码(如有) | 如第三方返回错误码 |
| STRING | 支付失败原因 | |
| INT | 重试次数(如有) | |
| DATE | 业务日期(分区字段) | |
| TIMESTAMP | 数据入仓时间 |
1.4.3. ✅ dwd_user_payment_zipper
(用户支付偏好拉链表)
字段名 | 类型 | 说明 | 备注 |
| STRING | 用户ID(主键) | |
| STRING | 用户默认支付方式 | 可字典编码 |
| DECIMAL(5,2) | 成功支付率 | 近30天等统计值 |
| TIMESTAMP | 最近一次支付时间 | |
| DATE | 生效开始日期(拉链开始) | 拉链策略核心字段 |
| DATE | 生效结束日期(拉链结束) | 当前生效记录为 |
| TIMESTAMP | 数据入仓时间 | 建议记录 |
1.4.4. ✅ dwd_refund_detail
(退款明细表)
字段名 | 类型 | 说明 | 备注 |
| STRING | 退款单ID | 主键 |
| STRING | 关联订单ID | 可与订单表关联 |
| STRING | 用户ID | |
| DECIMAL(10,2) | 退款金额 | 单位为“元” |
| STRING | 退款原因 | 建议字典统一 |
| STRING | 退款状态(处理中、完成、失败) | 建议标准编码 |
| TIMESTAMP | 发起退款时间 | |
| TIMESTAMP | 退款完成时间 | |
| DATE | 业务日期(分区字段) | |
| TIMESTAMP | 数据入仓时间 |
1.4.5. ✅ dwd_payment_channel_daily
(支付渠道日汇总表)
虽然偏向 DWS 粒度,但有些场景也会先在 DWD 构建日级宽表。
字段名 | 类型 | 说明 | 备注 |
| STRING | 渠道编码 | 如 wx、alipay、unionpay 等 |
| DATE | 日期 | 分区字段 |
| BIGINT | 订单总数 | |
| DECIMAL(18,2) | 总金额 | |
| DECIMAL(5,2) | 成功率 | |
| TIMESTAMP | 数据入仓时间 |
2. DWD层设计规范
2.1. ✅ DWD层设计定位
DWD 层是从 ODS 原始数据清洗和业务建模后的第一层核心标准数据层,其主要目标是:
- 还原业务事实(订单、交易、行为、事件)
- 统一字段命名与数据口径
- 按业务实体维度划分
- 支持多层衍生数据开发(如 DWS、ADS)
2.2. ✅ DWD层设计规范
分类 | 规范内容 |
1. 命名规范 | 统一以 |
2. 粒度规范 | 明确每张表的业务粒度,例如“订单粒度”、“支付事件粒度”、“用户行为粒度”等 |
3. 字段规范 | 字段必须包含主键、时间戳(create_time / update_time)、业务日期(biz_date)、来源标识、状态字段等。 |
4. 数据规范 | 金额单位统一为“元”,时间字段统一为“北京时间”,编码字段需挂接字典表,必须进行脱敏/加密处理 |
5. 时间处理规范 | 明确使用 |
6. 历史保留规范 | 是否采用拉链策略(SCD Type 2)、是否全量覆盖、是否仅保留新增,应在表模型中显式注明 |
7. 分区规范 | 建议使用 |
8. 错误容忍规范 | 保证脏数据隔离(如 null 主键、金额为负、无效时间等),需标记或写入错误表 |
9. 可追溯性规范 | 每条记录必须能追溯到来源系统与操作时间,需包含源系统标识(如 |
10. 表类型规范 | 明细表、事件表、拉链表等应明确结构和用途。维度信息应挂接 DIM 层,衍生指标不应在 DWD 中出现 |
2.3. ✅ DWD层表字段设计规范(推荐字段集)
字段名 | 类型 | 说明 |
| STRING | 表主键,唯一标识业务记录 |
| DATE | 业务发生日期,分区字段 |
| TIMESTAMP | 数据创建时间(业务发生时间) |
| TIMESTAMP | 数据最后更新时间 |
| TIMESTAMP | 数据入仓时间 |
| STRING | 来源系统标识 |
| TINYINT | 逻辑删除标志,0-正常 1-删除 |
| STRING | 业务状态字段,建议统一枚举值编码 |
| INT | 数据版本号(用于增量合并) |
| STRING | 业务链路追踪ID,用于问题排查和溯源 |
2.4. ✅ DWD常见表类型设计规范
表类型 | 说明 | 示例 |
明细表 | 每条记录为一笔业务,如订单、支付、退款等 |
|
事件表 | 表示系统发生的某个动作、状态,如点击事件、支付回调 |
|
拉链表 | 用于记录维度变更历史,如用户、产品、机构信息 |
|
快照表 | 每日或每小时采集一次全量快照 |
|
2.5. ✅ DWD拉链表设计规范(历史变更保留)
拉链表用于处理 Slowly Changing Dimension(SCD Type 2)场景:
字段 | 说明 |
| 当前版本生效开始时间 |
| 当前版本生效结束时间(如 |
| 是否为当前版本记录(1=当前,0=历史) |
| 版本号(可选) |
2.6. ✅ DWD层数据质量校验规范(建议集成DQ系统)
- 主键完整性校验(不能为 null 或重复)
- 时间字段合理性(不能超过当前时间、不能倒序)
- 枚举字段校验(需在合法值集合内)
- 金额非负/格式正确校验
- 维度字段可挂接(外键字段能 join 上 DIM 层)
2.7. ✅ 开发与维护规范
项目 | 说明 |
SQL模板规范 | 所有 DWD 开发需使用统一 SQL 模板(标准字段、错误处理、分区清理等) |
元数据注册规范 | DWD 表需注册到元数据中心,注明数据粒度、刷新频率、数据负责人 |
血缘追踪规范 | 建议使用工具记录 DWD 与 ODS、DIM、DWS 的依赖关系,方便影响分析与变更管理 |
自动化调度规范 | DWD 表每日调度应监控成功状态,并对空数据、数据量波动等异常报警 |
3. DWD层采集策略
DWD(Data Warehouse Detail)层是数据仓库建模中最贴近业务明细数据的核心层,通常是数据建模中的“宽表”或“明细表”层,用于承接 ODS 层(操作数据层)或 DIM(维度层)的数据,是构建 DWS(服务层)和 ADS(应用层)的基础。
3.1. ✅ DWD层采集策略
采集策略 | 说明 | 应用场景 |
拉链表(慢变维)策略 | 保留历史变更记录,每次变更都会生成一条新记录,并维护有效期字段(如 | 适用于维度数据变更需要保留历史记录的场景,如客户信息、产品信息等 |
覆盖更新策略 | 每次全量替换,不保留历史,仅保留最新状态的数据 | 适用于不需要保留历史的维度数据,如一些实时状态表、缓存表等 |
新增插入策略 | 每次采集只插入新增的数据(例如基于主键去重),历史数据不变 | 适用于只追加数据的业务,如交易明细、订单记录等 |
增量合并策略 | 只采集当天/最近的数据,合并到已有的宽表中(如根据主键合并更新) | 适用于中高频变更的宽表,如每日用户行为聚合表、设备状态表 |
事实拉链策略 | 针对事实表记录发生变化(如金额变更、状态变更)时,用拉链方式记录历史 | 如贷款审批流程、订单状态流转,适用于多状态记录流程型业务 |
T+1 全量快照策略 | 每天将整个源表快照一次,生成一个 DWD 层表 | 适用于追溯分析、数据抽样、审计场景 |
事件驱动策略(CDC) | 通过日志、binlog 等获取变更数据,实时/准实时写入 DWD 层 | 实时业务场景,如订单状态变更、支付状态通知等 |
3.2. 📌 DWD层采集示例
3.2.1. 示例一:订单明细表(新增插入策略)
源表:ods_order_detail
目标表:dwd_order_detail
策略:按主键去重后将新订单插入到 DWD 层,不做更新,保留历史
3.2.2. 示例二:客户信息表(拉链策略)
源表:ods_customer_info
目标表:dwd_customer_info_zipper
策略:客户信息发生变更时生成新记录,旧记录更新 end_date
3.2.3. 示例三:设备状态(增量合并策略)
源表:ods_device_status
目标表:dwd_device_status
策略:每日抽取变更记录,根据设备ID做合并更新
3.3. 📚 总结:DWD层采集策略设计关注点
- 是否保留历史(决定是否用拉链表)
- 数据是否频繁变更(决定是否用增量合并)
- 数据更新时是否可以容忍延迟(决定是否用 CDC)
- 是否只追加(决定是否用 append-only 策略)
- 是否为事实表或维度表(决定数据组织方式)
4. DWD层实战示例
4.1. DWD层建模实战
4.2. DWD层数据导入实战
4.3. DWD层任务调度实战
4.4. DWD层表关联管理实战
5. DWD层数据思考
在数据仓库建设中,DWD 层(明细数据层)是连接 ODS 原始数据与 DWS 主题数据之间最关键的桥梁,承担着标准化、规范化、业务建模的核心任务。在实际项目中,DWD 层扮演着极为重要的角色,下面是一些实践中典型的 DWD 应用场景,主要以金融、支付、电商、行为分析等为例。
5.1. ✅ DWD层典型应用场景分类
类型 | 场景说明 | 示例表名 |
交易明细建模 | 对接支付网关/订单系统,标准化交易数据 |
|
事件流建模 | 接入用户行为、支付回调、设备事件,形成事件事实表 |
|
用户行为建模 | 用户浏览、点击、搜索等行为沉淀为标准化明细 |
|
状态变更拉链表 | 对用户、商户、贷款等对象的状态/属性变更做拉链历史记录 |
|
多渠道统一建模 | 整合多支付渠道或多系统同一业务模型,抽象为统一宽表 |
|
退款/退货建模 | 记录订单退款、部分退款、退货明细 |
|
资金流向追踪 | 把资金从付款到清算的全过程建模,做穿透与链路分析 |
|
合规/审计建模 | 把敏感操作、审批记录、账户冻结解冻等写入可审计明细表 |
|
风控决策追溯 | 记录风控引擎每次命中规则、分值计算、最终决策的完整明细 |
|
快照与比对分析 | 存储每日快照用于横向对比、版本回溯 |
|
5.2. ✅ DWD层数据典型业务场景
5.2.1. 🌟 交易支付类系统
需求 | DWD建模实践 |
支持按用户、订单、支付方式统计 | 构建订单明细表(dwd_trade_order_detail) |
支持订单多状态变更跟踪 | 构建订单状态事件表或拉链表 |
支付成功/失败通知分析 | 支付结果事件表(dwd_payment_result_event) |
渠道对账、资金穿透追踪 | 支付/清算/结算明细表,资金流跟踪链路 |
5.2.2. 🌟 用户行为分析类系统
需求 | DWD建模实践 |
用户点击、搜索、下单路径分析 | 行为事件明细表(如 dwd_user_behavior_event) |
支持漏斗转化路径分析 | 明确事件时间、用户标识,标准化事件结构 |
构建用户画像和偏好分析 | 以用户为主键构建行为聚合或拉链表 |
5.2.3. 🌟 风控系统场景
需求 | DWD建模实践 |
决策引擎规则命中日志跟踪 | 记录风控每次命中的规则、评分卡、标签等 |
风控模型命中明细存档 | DWD 层记录模型输入、分数、变量明细等 |
规则演进、决策策略测试 | 可通过历史 DWD 明细进行策略回放与仿真测试 |
5.2.4. 🌟 多源异构系统整合
需求 | DWD建模实践 |
同类业务来自多个系统(如多个支付网关) | DWD 层统一标准字段、结构,形成统一宽表结构 |
订单、用户、交易等跨系统聚合 | 明确主键定义、时间戳一致性、来源字段记录等 |
5.2.5. 🌟 报表/统计前置准备
需求 | DWD建模实践 |
报表口径一致 | 所有指标来源于统一的 DWD 标准明细表 |
报表可追溯 | 可从报表跳转至原始明细,审计友好 |
报表需求频繁调整 | 明细层变化小,DWS/ADS 层灵活适配变化 |
5.3. ✅ 设计DWD时的建议总结
建议项 | 说明 |
统一命名 | 命名清晰,结构标准化(如 dwd_业务域_对象名) |
明确粒度 | 一张表必须粒度清晰:按订单、按事件、按用户行为等 |
加入来源标识 | source_system 字段便于回溯数据来源 |
时间字段标准 | create_time、update_time、biz_date、etl_time 必不可少 |
避免指标下沉 | DWD 层不要存 KPI 级指标,聚合逻辑应在 DWS 或 ADS 层实现 |
保持可追溯 | 每条记录能还原上下文:操作人、发生时间、业务事件、来源系统等信息 |
博文参考
- 《阿里巴巴大数据实战》
- 《大数据数仓实战》