Arch Day 90: 零售数据仓库设计
Arch Day 90: 零售数据仓库设计
日期: 2026-06-28 (Day 90) 阶段: 第三阶段 - 零售域深度 标签: #数据仓库 #维度建模 #指标中台 #ETL #零售数据
核心概念
一句话定义
数据仓库是零售数字化的"大脑"——它将散落在各业务系统中的数据(订单、库存、会员、营销、供应链),按照统一的分层模型(ODS→DWD→DWS→ADS)组织起来,通过维度建模构建可分析的数据集市,最终通过指标中台向全公司提供统一口径的数据服务。
为什么关注
数据仓库是所有数据能力的基础——没有它,前面学的CDP、营销中台、需求预测都无从谈起:
- 数据是零售的"石油":但原油需要炼化才能使用,数仓就是"炼油厂"
- 指标口径不一致:销售部门说GMV 10亿,财务说8亿——因为口径不同
- 报表开发低效:每个需求都从头写SQL,没有复用,重复开发率>60%
- 数据质量差:源系统数据缺失/错误/不一致,不经过清洗无法直接分析
- 实时化需求:传统T+1的数仓无法满足实时决策需求,湖仓一体成为趋势
误区与反模式
| 误区 | 现实 |
|---|---|
| "把所有数据堆一起就是数仓" | 数仓的核心是"建模"而非"堆数据",分层+维度建模是灵魂 |
| "维度建模不重要,直接写SQL就行" | 没有好的模型,SQL复杂度爆炸,性能差,维护困难 |
| "一步到位建最终的ADS层" | 必须自底向上,ODS→DWD→DWS→ADS逐层构建 |
| "数仓建好就不用管了" | 数据质量、模型演进、性能优化是持续工作 |
| "指标口径随便定" | 指标口径不一致是数据混乱的最大根源,必须统一管理 |
知识点详解
一、数仓分层模型
1.1 四层架构详解
┌─────────────────────────────────────────────────────────────┐
│ 数仓分层架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ ADS (Application Data Store) - 应用数据层 │ │
│ │ │ │
│ │ 面向应用的数据集: │ │
│ │ ├── 经营日报/周报/月报 │ │
│ │ ├── 管理驾驶舱 │ │
│ │ ├── 用户画像宽表 │ │
│ │ ├── 推荐特征表 │ │
│ │ └── 预测模型特征表 │ │
│ │ │ │
│ │ 特点:直接服务于应用/报表,高度定制化 │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↑ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ DWS (Data Warehouse Summary) - 数据汇总层 │ │
│ │ │ │
│ │ 公共汇总指标: │ │
│ │ ├── 每日用户汇总(DAU/MAU/新增/留存) │ │
│ │ ├── 每日交易汇总(GMV/订单量/客单价/转化率) │ │
│ │ ├── 每日库存汇总(周转天数/缺货率/过期率) │ │
│ │ ├── 每日营销汇总(触达量/打开率/转化率/ROI) │ │
│ │ └── 每日供应链汇总(到货率/配送时效/物流成本) │ │
│ │ │ │
│ │ 特点:公共复用,以"主题+粒度+时间"为核心 │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↑ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ DWD (Data Warehouse Detail) - 数据明细层 │ │
│ │ │ │
│ │ 清洗后的明细数据: │ │
│ │ ├── 交易明细(一行=一笔交易) │ │
│ │ ├── 用户行为明细(一行=一次行为事件) │ │
│ │ ├── 库存变动明细(一行=一次出入库) │ │
│ │ ├── 营销触达明细(一行=一次触达记录) │ │
│ │ └── 物流轨迹明细(一行=一个物流节点) │ │
│ │ │ │
│ │ 处理:数据清洗/脱敏/标准化/维度关联 │ │
│ │ 特点:最细粒度的"干净数据",按业务主题建模 │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↑ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ ODS (Operational Data Store) - 操作数据层 │ │
│ │ │ │
│ │ 原始数据的"镜像": │ │
│ │ ├── 订单系统表(1:1同步) │ │
│ │ ├── 会员系统表(1:1同步) │ │
│ │ ├── 库存系统表(1:1同步) │ │
│ │ ├── 行为埋点日志 │ │
│ │ └── 第三方数据 │ │
│ │ │ │
│ │ 原则:保持原样,不做业务逻辑处理 │ │
│ │ 价值:数据溯源/问题排查/历史数据保留 │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↑ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 数据源 │ │
│ │ ├── 业务数据库 (MySQL/PostgreSQL) │ │
│ │ ├── 日志数据 (Kafka/文件) │ │
│ │ ├── 第三方API │ │
│ │ └── 离线文件 (Excel/CSV) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
1.2 各层的命名规范
ODS层:ods_{源系统}_{源表名}
例:ods_order_order_master -- 订单系统.订单主表
ods_member_member_info -- 会员系统.会员信息表
ods_inventory_stock_record -- 库存系统.库存记录表
DWD层:dwd_{主题域}_{业务过程}_{粒度}
例:dwd_trade_order_detail_di -- 交易域.订单明细.天增量
dwd_user_behavior_event_di -- 用户域.行为事件.天增量
dwd_inventory_stock_change_di -- 库存域.库存变动.天增量
DWS层:dws_{主题域}_{维度}_{统计周期}
例:dws_trade_user_1d -- 交易域.用户粒度.1天汇总
dws_trade_shop_1d -- 交易域.门店粒度.1天汇总
dws_user_behavior_sku_7d -- 用户域.SKU粒度.7天汇总
ADS层:ads_{应用场景}_{具体指标}
例:ads_report_daily_dashboard -- 日报看板
ads_user_rfm_profile -- 用户RFM画像
ads_forecast_demand_feature -- 需求预测特征表
DIM层(维度表):dim_{维度名}
例:dim_product -- 商品维度
dim_store -- 门店维度
dim_date -- 日期维度
dim_geography -- 地理维度
二、零售核心指标体系
2.1 指标分类框架
零售核心指标体系(按业务域):
┌─────────────────────────────────────────────────────────────┐
│ 零售指标金字塔 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 第一层:北极星指标 │
│ ├── GMV(总交易额) │
│ └── 利润率 │
│ │
│ 第二层:核心经营指标 │
│ ├── 流量指标:UV/PV/DAU/MAU │
│ ├── 转化指标:转化率/加购率/支付率 │
│ ├── 客单价:GMV/付费用户数 │
│ ├── 复购率:重复购买用户数/总购买用户数 │
│ └── 毛利率:(收入-成本)/收入 │
│ │
│ 第三层:业务过程指标 │
│ ├── 用户域:注册量/登录量/活跃天数/留存率/流失率 │
│ ├── 商品域:动销率/滞销率/售罄率/上新数/下架数 │
│ ├── 交易域:订单量/退货率/完成率/平均配送时长 │
│ ├── 库存域:库存周转天数/缺货率/过期率/库销比 │
│ ├── 营销域:ROI/CPC/CPM/CTR/CVR/CAC/LTV │
│ └── 供应链域:到货率/退货率/供应商评分/采购成本 │
│ │
│ 第四层:效率指标 │
│ ├── 坪效:GMV/门店面积 │
│ ├── 人效:GMV/员工数 │
│ ├── 品效:GMV/SKU数 │
│ └── 时效:平均配送时长/接单到发货时长 │
│ │
└─────────────────────────────────────────────────────────────┘
2.2 指标口径定义(示例)
指标名称:GMV(Gross Merchandise Volume)
├── 中文名:商品交易总额
├── 定义:统计周期内所有已下单订单的商品金额之和(含未支付和退款)
├── 计算公式:SUM(order_amount) WHERE order_status != 'CANCELLED'
├── 统计口径:
│ ├── 包含:已支付+待支付+已退款
│ ├── 不包含:已取消的订单
│ ├── 时间口径:订单创建时间
│ └── 金额口径:商品原价×数量(不含运费、不含优惠减免)
├── 数据来源:dwd_trade_order_detail_di
├── 更新频率:T+1 / 实时(两个版本)
├── 相关指标:
│ ├── 实际收入 = GMV - 退款金额 - 优惠减免 - 运费补贴
│ ├── 净GMV = GMV - 退款GMV
│ └── 支付GMV = 仅统计已支付订单
└── 负责人:数据团队 @xxx
指标名称:转化率
├── 中文名:交易转化率
├── 定义:统计周期内完成支付的用户数/访问用户数
├── 计算公式:COUNT(DISTINCT pay_user_id) / COUNT(DISTINCT visitor_id)
├── 统计口径:
│ ├── 分子:当日完成支付的去重用户数
│ ├── 分母:当日访问站点的去重用户数(UV)
│ └── 时间口径:自然天
├── 相关指标:
│ ├── 浏览→加购转化率
│ ├── 加购→下单转化率
│ ├── 下单→支付转化率
│ └── 全链路转化漏斗
└── 负责人:数据团队 @xxx
三、维度建模
3.1 星型模型 vs 雪花模型
星型模型(Star Schema):
├── 中心:事实表(fact_order)
├── 周围:维度表(dim_product, dim_store, dim_date, dim_user)
├── 维度表不再关联其他表(扁平化)
├── 优点:查询简单,JOIN少,性能好
├── 缺点:维度表冗余大
└── 推荐:大多数OLAP场景首选
dim_date
│
dim_product ─── fact_order ─── dim_store
│
dim_user
雪花模型(Snowflake Schema):
├── 维度表进一步规范化(dim_product → dim_brand → dim_category)
├── 减少冗余,但增加JOIN
├── 优点:数据冗余小,维护方便
├── 缺点:查询复杂,性能差
└── 适用:维度变化频繁的场景
星座模型(Constellation):
├── 多个事实表共享维度表
├── 实际数仓最常见的形态
└── 如:fact_order和fact_inventory共享dim_product
推荐策略:
├── DWD层:尽量星型模型(性能优先)
├── DWS层:宽表(所有维度打平到一行)
└── ADS层:完全打平的应用表
3.2 零售核心事实表设计
-- 交易事实表(最核心)
CREATE TABLE fact_order (
order_id BIGINT, -- 订单ID
order_item_id BIGINT, -- 订单项ID
order_date_key INT, -- 日期维度键 (YYYYMMDD)
user_key BIGINT, -- 用户维度键
product_key BIGINT, -- 商品维度键
store_key INT, -- 门店维度键
channel_key INT, -- 渠道维度键
promotion_key INT, -- 促销维度键
-- 度量值(Measures)
quantity INT, -- 数量
unit_price DECIMAL(12,2), -- 单价
discount_amount DECIMAL(12,2), -- 优惠金额
actual_amount DECIMAL(12,2), -- 实付金额
cost_amount DECIMAL(12,2), -- 成本
gross_profit DECIMAL(12,2), -- 毛利
shipping_fee DECIMAL(12,2), -- 运费
-- 状态
order_status VARCHAR(20), -- 订单状态
payment_status VARCHAR(20), -- 支付状态
delivery_status VARCHAR(20), -- 配送状态
-- ETL元数据
etl_time TIMESTAMP, -- ETL处理时间
data_source VARCHAR(20) -- 数据源
)
PARTITIONED BY (dt STRING) -- 按天分区
STORED AS PARQUET; -- 列式存储
-- 库存事实表
CREATE TABLE fact_inventory_snapshot (
snapshot_date_key INT, -- 快照日期
product_key BIGINT, -- 商品维度键
warehouse_key INT, -- 仓库维度键
-- 库存度量
on_hand_qty INT, -- 在手库存
available_qty INT, -- 可用库存
in_transit_qty INT, -- 在途库存
reserved_qty INT, -- 预留库存
damaged_qty INT, -- 损坏库存
-- 成本度量
inventory_value DECIMAL(14,2), -- 库存金额
avg_cost DECIMAL(12,2), -- 平均成本
-- 指标
days_of_supply INT, -- 库存天数
stockout_flag BOOLEAN, -- 是否缺货
overstock_flag BOOLEAN -- 是否过量
)
PARTITIONED BY (dt STRING)
STORED AS PARQUET;
-- 用户行为事实表
CREATE TABLE fact_user_behavior (
event_id BIGINT, -- 事件ID
event_date_key INT, -- 日期维度键
user_key BIGINT, -- 用户维度键
product_key BIGINT, -- 商品维度键(可选)
event_type VARCHAR(30), -- 事件类型
session_id VARCHAR(64), -- 会话ID
-- 度量
page_stay_duration INT, -- 页面停留秒数
search_keyword VARCHAR(200), -- 搜索关键词
event_properties STRING, -- 事件属性JSON
-- 上下文
platform VARCHAR(10), -- ios/android/web
channel_source VARCHAR(30), -- 来源渠道
city VARCHAR(20) -- 城市
)
PARTITIONED BY (dt STRING)
STORED AS PARQUET;
3.3 核心维度表设计
-- 商品维度表
CREATE TABLE dim_product (
product_key BIGINT PRIMARY KEY, -- 代理键
product_id VARCHAR(32), -- 商品ID(自然键)
sku_id VARCHAR(32), -- SKU ID
product_name VARCHAR(200), -- 商品名称
category_l1 VARCHAR(50), -- 一级品类
category_l2 VARCHAR(50), -- 二级品类
category_l3 VARCHAR(50), -- 三级品类
brand_name VARCHAR(50), -- 品牌
supplier_id VARCHAR(32), -- 供应商ID
supplier_name VARCHAR(100), -- 供应商名称
unit_cost DECIMAL(12,2), -- 单位成本
list_price DECIMAL(12,2), -- 标价
weight_kg DECIMAL(8,3), -- 重量
is_fresh BOOLEAN, -- 是否生鲜
shelf_life_days INT, -- 保质期天数
abc_class CHAR(1), -- ABC分类
xyz_class CHAR(1), -- XYZ分类
status VARCHAR(10), -- ON_SALE/OFF_SALE
create_date DATE, -- 上架日期
-- SCD2缓慢变化维度
effective_date DATE, -- 生效日期
expiry_date DATE, -- 失效日期
is_current BOOLEAN -- 是否当前版本
);
-- 日期维度表
CREATE TABLE dim_date (
date_key INT PRIMARY KEY, -- YYYYMMDD
full_date DATE,
year INT,
quarter INT,
month INT,
week_of_year INT,
day_of_week INT, -- 1=Monday
day_of_month INT,
is_weekend BOOLEAN,
is_holiday BOOLEAN,
holiday_name VARCHAR(50),
is_workday BOOLEAN,
fiscal_year INT, -- 财年
fiscal_quarter INT, -- 财季
is_promotion_day BOOLEAN, -- 是否大促日
promotion_name VARCHAR(50) -- 大促名称(双11/618等)
);
-- 门店维度表
CREATE TABLE dim_store (
store_key INT PRIMARY KEY,
store_id VARCHAR(20),
store_name VARCHAR(100),
store_type VARCHAR(20), -- 旗舰/标准/社区/前置仓
region VARCHAR(20), -- 大区
province VARCHAR(20), -- 省份
city VARCHAR(20), -- 城市
district VARCHAR(30), -- 区县
address VARCHAR(200), -- 详细地址
area_sqm DECIMAL(8,2), -- 面积(m²)
open_date DATE, -- 开店日期
store_manager VARCHAR(50), -- 店长
staff_count INT, -- 员工数
status VARCHAR(10) -- OPEN/CLOSED/RENOVATING
);
四、增量与全量更新策略
4.1 数据同步策略
全量同步:
├── 每次全部覆盖
├── 适用:维度表(商品/门店/用户等,数据量小)
├── 优点:简单,数据一致性好
└── 缺点:数据量大时效率低
增量同步:
├── 只同步变更的数据
├── 适用:事实表(订单/行为/库存变动,数据量大)
├── 实现方式:
│ ├── 时间戳增量:WHERE update_time > last_sync_time
│ ├── CDC (Change Data Capture):监听binlog变更
│ └── 全量对比:对比新旧快照差异
└── 推荐:CDC(延迟低、对源库压力小)
CDC实现方案:
├── Debezium(最流行的开源CDC工具)
│ MySQL binlog → Debezium → Kafka → Flink/Spark → 数仓
├── Canal(阿里开源,国内常用)
│ MySQL binlog → Canal → Kafka → 数仓
└── Flink CDC(一站式CDC到数仓)
MySQL binlog → Flink CDC → 数仓
4.2 拉链表(SCD2)
拉链表用于记录维度的历史变化
场景:商品价格从199调到249,我们需要保留两个版本
product_key | product_id | price | effective_date | expiry_date | is_current
1001 | SKU_001 | 199.00 | 2025-01-01 | 2026-03-15 | false
1002 | SKU_001 | 249.00 | 2026-03-16 | 9999-12-31 | true
查询当前数据:WHERE is_current = true
查询历史数据:WHERE effective_date <= '2026-01-01' AND expiry_date > '2026-01-01'
拉链表更新流程:
1. 获取当日变更数据(CDC增量)
2. 对变更数据的旧版本:设置expiry_date=今天,is_current=false
3. 插入新版本:effective_date=今天,expiry_date=9999-12-31,is_current=true
4. 无变更的数据保持不动
优缺点:
├── 优点:完整保留历史,支持时间旅行查询
├── 缺点:数据量膨胀,查询需要加时间条件
└── 适用:需要分析历史变化的维度(价格/等级/状态等)
五、零售数仓主要主题域
零售数仓6大主题域:
┌─────────────────────────────────────────────────────────────┐
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 用户域 │ │ 商品域 │ │ 交易域 │ │
│ │ │ │ │ │ │ │
│ │ ·用户注册│ │ ·商品主数│ │ ·订单 │ │
│ │ ·登录行为│ │ 据 │ │ ·支付 │ │
│ │ ·浏览行为│ │ ·品类管理│ │ ·退款 │ │
│ │ ·搜索行为│ │ ·价格管理│ │ ·购物车 │ │
│ │ ·会员等级│ │ ·库存 │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 库存域 │ │ 营销域 │ │ 供应链域 │ │
│ │ │ │ │ │ │ │
│ │ ·库存快照│ │ ·活动 │ │ ·采购 │ │
│ │ ·出入库 │ │ ·优惠券 │ │ ·入库 │ │
│ │ ·调拨 │ │ ·触达 │ │ ·物流 │ │
│ │ ·盘点 │ │ ·ABTest │ │ ·供应商 │ │
│ │ ·补货 │ │ ·归因 │ │ ·退货 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
六、指标中台
6.1 指标中台架构
为什么需要指标中台?
问题:
├── 销售说"今天GMV 1亿"
├── 运营说"今天GMV 8000万"
├── 财务说"今天收入6000万"
└── 原因:三个人用的SQL不同,过滤条件不同,时间口径不同
指标中台的目标:
├── 统一口径:一个指标一个定义,全公司统一
├── 统一计算:一个指标一份计算逻辑,避免重复开发
├── 统一服务:一个入口查询所有指标
└── 指标治理:指标的创建/变更/废弃有流程管理
┌─────────────────────────────────────────────────────────────┐
│ 指标中台架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 指标定义层 │ │
│ │ │ │
│ │ 指标元数据: │ │
│ │ ├── 指标名称/英文名/别名 │ │
│ │ ├── 业务口径(自然语言描述) │ │
│ │ ├── 技术口径(SQL/计算公式) │ │
│ │ ├── 统计粒度(天/周/月) │ │
│ │ ├── 统计维度(用户/商品/门店/品类) │ │
│ │ ├── 数据来源(DWS层哪张表) │ │
│ │ ├── 更新频率 │ │
│ │ ├── 负责人/审核人 │ │
│ │ └── 状态(草稿/审核中/已发布/已废弃) │ │
│ │ │ │
│ │ 指标分类: │ │
│ │ ├── 原子指标:不可再分(如SUM(amount)) │ │
│ │ ├── 派生指标:原子指标+修饰词+统计周期 │ │
│ │ │ 例:近7天_上海_金卡会员_GMV │ │
│ │ └── 复合指标:多个原子指标的组合 │ │
│ │ 例:转化率 = 支付用户数 / 访问用户数 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 指标计算层 │ │
│ │ │ │
│ │ 离线计算(T+1): │ │
│ │ ├── Spark/Hive SQL任务 │ │
│ │ ├── 按指标定义自动生成SQL │ │
│ │ ├── Airflow调度,每日凌晨计算 │ │
│ │ └── 结果写入指标结果表 │ │
│ │ │ │
│ │ 实时计算(分钟级): │ │
│ │ ├── Flink实时聚合 │ │
│ │ ├── 核心指标实时刷新(GMV/订单量/UV) │ │
│ │ └── 结果写入Redis+ClickHouse │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 指标服务层 │ │
│ │ │ │
│ │ API服务: │ │
│ │ ├── 指标查询API(按维度/时间范围查询指标值) │ │
│ │ ├── 指标元数据API(查询指标定义/口径) │ │
│ │ └── 指标订阅API(指标变化通知) │ │
│ │ │ │
│ │ 自助查询: │ │
│ │ ├── 指标目录(搜索/浏览所有指标) │ │
│ │ ├── 自助取数(选维度+选指标→生成报表) │ │
│ │ └── 数据看板(拖拽式BI) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 指标治理层 │ │
│ │ │ │
│ │ ├── 指标审核流程(申请→审核→发布) │ │
│ │ ├── 指标血缘(指标依赖哪些表/字段) │ │
│ │ ├── 指标监控(指标异常波动告警) │ │
│ │ ├── 指标质量(准确性/及时性/完整性) │ │
│ │ └── 指标废弃流程(确认无引用后下线) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
6.2 指标口径一致性保障
保障口径一致的机制:
1. 口径注册制
├── 新指标必须在指标中台注册定义
├── 不允许"私自"写SQL计算指标
└── 所有报表/看板从指标中台取数
2. 口径审核制
├── 新建/修改指标需要数据owner审核
├── 业务方确认业务口径
├── 技术方确认技术实现
└── 审核通过后才能发布
3. 口径血缘追踪
├── 每个指标记录计算依赖的表/字段
├── 上游数据变更时自动通知受影响的指标
└── 防止上游变更导致指标计算错误
4. 口径监控告警
├── 指标波动超过阈值自动告警
│ 例:GMV日环比下降>30% → P0告警
├── 指标缺失/延迟告警
│ 例:上午10点前未产出 → 告警
└── 指标质量评分(准确性/及时性/完整性)
架构设计实操
零售数据仓库完整架构
┌─────────────────────────────────────────────────────────────────────┐
│ 零售数据仓库完整架构 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────── 数据源 ──────────────────────────────────────┐ │
│ │ MySQL(订单/会员/库存) │ Kafka(行为日志) │ API(第三方) │ 文件 │ │
│ └───────────┬───────────┴───────┬─────────┴───────┬────────┘ │
│ │ │ │ │
│ ┌───────────▼───────────────────▼─────────────────▼──────────┐ │
│ │ 数据集成层 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ CDC │ │ 日志采集 │ │ 文件导入 │ │ │
│ │ │ Debezium │ │ Kafka │ │ Airflow │ │ │
│ │ │ /Canal │ │ Connector│ │ │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └────────────────────────┬──────────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ ODS层 (Hive/Iceberg) │ │
│ │ ods_order_* │ ods_member_* │ ods_inventory_* │ ods_log_* │ │
│ └────────────────────────┬──────────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ DWD层 (Hive/Iceberg) │ │
│ │ dwd_trade_order_detail │ dwd_user_behavior │ dwd_inventory │ │
│ │ + dim_product │ dim_store │ dim_date │ dim_user │ │
│ └────────────────────────┬──────────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ DWS层 (Hive/ClickHouse) │ │
│ │ dws_trade_user_1d │ dws_trade_shop_1d │ dws_user_active │ │
│ └────────────────────────┬──────────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ ADS层 (ClickHouse/MySQL) │ │
│ │ ads_daily_report │ ads_user_profile │ ads_forecast_feature │ │
│ └────────────────────────┬──────────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ 数据消费层 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ BI报表 │ │ 指标中台 │ │ 数据API │ │ ML特征 │ │ │
│ │ │ Superset │ │ 统一口径 │ │ 对外服务 │ │ 训练数据 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────── 横切关注点 ────────────────────────────┐ │
│ │ ·数据质量(Great Expectations) ·数据血缘(Apache Atlas) │ │
│ │ ·任务调度(Airflow) ·数据安全(RBAC+加密) │ │
│ │ ·元数据管理(DataHub) ·成本治理(存储+计算) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
技术选型总结
存储层:
├── ODS/DWD/DWS:Hive on HDFS → 正在迁移到 Apache Iceberg/Hudi (湖仓一体)
├── ADS层:ClickHouse(OLAP查询)+ MySQL(小数据量应用表)
├── 实时层:Kafka(流数据)+ Redis(实时指标缓存)
└── 2026趋势:Lakehouse(数据湖+数据仓库合一,Iceberg/Delta Lake/Hudi)
计算层:
├── 离线批量:Spark SQL / Hive SQL
├── 实时流:Flink SQL
├── 转换层:dbt(SQL-based数据转换,越来越流行)
└── 调度:Apache Airflow
查询层:
├── OLAP引擎:ClickHouse / Apache Doris / StarRocks
├── 联邦查询:Trino(跨数据源查询)
└── BI工具:Superset / Metabase / Tableau
治理层:
├── 元数据:Apache Atlas / DataHub
├── 数据质量:Great Expectations / dbt tests
├── 数据血缘:Apache Atlas / DataHub Lineage
└── 数据安全:Apache Ranger / Sentry
AI增强
AI在数据仓库中的应用
1. Text-to-SQL(自然语言查数)
├── 用户输入:"上周上海地区女装品类的GMV是多少?"
├── LLM转化为SQL:SELECT SUM(actual_amount) FROM dws_trade_... WHERE ...
├── 2025-2026年技术已相当成熟
└── 核心挑战:指标口径映射、表名推断、多表关联
2. 自动数据质量检测
├── AI分析数据分布变化,自动发现异常
├── 例:"今天某SKU销量突然为0,而昨天是正常值"
└── 减少人工监控成本
3. 自动ETL生成
├── 根据源表结构和目标模型,AI自动生成ETL SQL
├── dbt模型自动推荐
└── 减少数据开发工作量
4. 智能指标洞察
├── AI自动分析指标波动原因
├── "GMV下降10%,主要原因是XX品类下降25%,
│ 其中XX品牌受竞品促销影响最大"
└── 从"发现问题"到"解释问题"的跨越
5. 数据血缘自动追踪
├── 解析SQL依赖关系,自动构建血缘图
├── 影响分析:某个字段变更,哪些指标受影响?
└── 工具:Apache Atlas + LLM增强
Web3关联
数据仓库与Web3的关联:
1. 链上数据作为数据源
├── 链上交易数据 → ODS层
├── 链上行为分析 → DWD/DWS层
└── 链上指标(TVL/DAU/Volume) → ADS层
└── 工具:Dune Analytics就是链上数据仓库
2. Dune Analytics = Web3数据仓库
├── 数据源:以太坊/Polygon/BSC等链上数据
├── 分层:decoded tables → spell → dashboard
├── 查询引擎:DuneSQL (Trino)
└── 本质上就是一个链上数据的数据仓库+BI
3. 数据主权与去中心化数仓
├── 传统数仓:企业集中存储控制
├── Web3理念:用户拥有自己的数据
└── 探索方向:加密数仓(FHE/MPC上做分析)
今日思考
数据仓库是零售数字化最"不性感"但最重要的基础设施。没有好的数仓,CDP没有干净的数据源、营销中台没有准确的人群标签、需求预测没有特征数据、管理层看到的数字互相矛盾。
分层模型(ODS→DWD→DWS→ADS)的价值在于:每一层解决一个问题。ODS解决"数据从哪来",DWD解决"数据干不干净",DWS解决"常用指标怎么算",ADS解决"业务系统怎么用"。跳过中间层直接从ODS到ADS,短期看很快,长期看维护成本爆炸。
指标口径不一致是我见过最常见也最严重的数据问题。解决方案不是技术问题而是治理问题——需要建立指标注册审核机制,需要全公司认可"一个指标一个口径"的原则。指标中台的价值不在于技术多先进,而在于流程是否执行到位。
Day 84-90这七天,我们从需求预测→供应链金融→京东案例→会员系统→营销中台→CDP→数据仓库,串起了零售域数字化的完整链路。每一个模块都不是孤立的——数仓为CDP提供数据,CDP为营销中台提供画像,营销中台为会员系统提供触达,需求预测为供应链提供决策。系统思维比单点深入更重要。
面试题
Q1: 数仓分层的价值是什么?
简短回答:分层实现了"数据复用"和"职责分离"——ODS保原始数据、DWD保干净明细、DWS保公共汇总、ADS保应用数据。每层只做一件事,减少重复开发,提高数据质量。
详细回答:
- ODS层:原始数据镜像,支持数据溯源和问题排查
- DWD层:清洗标准化的明细数据,建立统一的事实表和维度表
- DWS层:公共汇总指标,避免各团队重复计算同一指标
- ADS层:面向具体应用的数据集,直接服务于报表/API/ML
- 核心价值:
- 复用性:DWS层指标可被多个ADS复用
- 一致性:同一指标只在一个地方计算
- 可维护性:上游变更只影响当层,不穿透到应用
- 性能:预计算的汇总数据,查询速度快
Q2: 如何保证指标口径一致?
简短回答:建立指标中台——指标注册制+审核制+血缘追踪+监控告警。技术上统一计算逻辑,流程上要求所有指标在指标中台注册和审核。
详细回答:
- 指标注册制:所有指标必须在指标中台注册,定义业务口径和技术口径
- 审核制:新建/修改指标需要数据owner和业务方共同审核
- 统一计算:每个指标只有一份计算SQL,避免各团队"各算各的"
- 血缘追踪:自动追踪指标依赖的表和字段,上游变更时通知下游
- 监控告警:指标异常波动自动告警,及时发现口径偏差
- 文化建设:全公司认同"一个指标一个口径"的原则,不允许"私算"
Q3: 实时数仓和离线数仓如何共存?
答案:Lambda架构(批流分开)或Kappa架构(统一流处理),2026年主流是湖仓一体(Lakehouse)——用Iceberg/Hudi实现批流统一存储,用Flink实现实时计算,用Spark实现批量计算,两者写入同一张表。核心原则:只有需要实时的指标(如GMV/UV)才做实时,大部分指标T+1足够。
学习资源
- 数仓分层设计ODS-DWD-DWS-ADS
- 数据仓库分层详解
- 新兴数据仓库设计与实践手册
- 袋鼠云数据仓库详解
- 书籍推荐:《The Data Warehouse Toolkit》(Ralph Kimball,维度建模圣经)
- 书籍推荐:《数据仓库工具箱》(中文版)
- 书籍推荐:《大数据之路:阿里巴巴大数据实践》
阶段总结
Day 84-90完成了零售域深度的核心模块学习。回顾这七天的知识图谱:
Day 84: 需求预测与智能补货 → 供应链的"大脑"
Day 85: 供应链金融 → 金融×零售的交叉
Day 86: 京东供应链案例 → 业界标杆分析
Day 87: 会员系统设计 → 用户运营的基础
Day 88: 营销中台设计 → 精准触达的引擎
Day 89: CDP客户数据平台 → 数据驱动的核心
Day 90: 零售数据仓库 → 一切数据的底座
它们的关系:
数据仓库(Day90) → 为 CDP(Day89) 提供数据源
CDP(Day89) → 为 营销中台(Day88) 提供用户画像
营销中台(Day88) → 为 会员系统(Day87) 提供触达能力
会员系统(Day87) → 为 京东供应链(Day86) 提供用户洞察
需求预测(Day84) → 为 供应链金融(Day85) 提供业务基础
零售数字化不是单点突破,而是系统工程。作为架构师,最重要的能力是看到全局,理解每个模块如何协作,如何在整体最优的前提下做局部设计。