
电商数仓实战5张核心表与3层架构的维度建模全解析从业务需求到数据落地的完整实践路径在电商行业的数据驱动决策中一个设计良好的数据仓库Data Warehouse能够将分散的业务数据转化为可分析的黄金资产。与传统的理论讲解不同我们将通过一个真实的电商案例展示如何从零开始构建符合Kimball维度建模理论的数仓体系。这个实战过程将产出5张核心数据表用户维度表、商品维度表、下单事实表、支付事实表、订单累计快照事实表并严格遵循ODS/DWD/DWS三层规范的分层架构。电商业务的核心分析场景通常围绕人货场展开哪些用户人在什么时间场购买了哪些商品货他们的购买频次、客单价如何哪些商品组合经常被一起购买要回答这些问题我们需要将业务过程中产生的零散数据通过维度建模的方法重新组织。维度建模的本质是将业务活动抽象为可度量的事实并将事实发生的环境描述为维度通过星型或雪花模型将两者关联起来。提示在电商数仓中事务事实表记录下单、支付等离散事件周期快照表捕捉库存等状态变化而累计快照表则跟踪订单全生命周期1. 业务梳理与数据域划分1.1 电商核心业务流程解构电商业务虽然复杂但其核心流程可以抽象为几个关键业务过程用户旅程注册 → 浏览 → 加购 → 下单 → 支付 → 收货 → 售后商品流转上架 → 展示 → 交易 → 配送 → 签收资金流动支付 → 结算 → 退款 → 佣金计提通过与企业业务专家访谈我们绘制出以下电商简化业务矩阵业务过程日期维度用户维度商品维度商家维度地区维度支付方式维度用户注册✓✓✓商品浏览✓✓✓✓购物车操作✓✓✓订单创建✓✓✓✓✓支付完成✓✓✓物流配送✓✓1.2 数据域划分原则与实践根据业务矩阵我们将电商数据划分为以下数据域用户域用户基础属性、等级、行为标签等商品域类目、SPU、SKU、价格、库存等交易域订单、购物车、优惠券、支付等物流域仓库、配送、签收等售后域退货、退款、投诉等每个数据域包含多个业务过程例如交易域包含下单、支付、退款等过程。划分数据域的主要价值在于明确团队分工边界构建一致性维度如统一用户ID定义避免重复计算和口径不一致-- 示例用户域与交易域的关联关系 SELECT u.user_id, u.register_date, COUNT(DISTINCT o.order_id) AS order_count FROM dim_user u LEFT JOIN fact_order o ON u.user_id o.user_id GROUP BY u.user_id, u.register_date;2. 维度表设计与实现2.1 用户维度表dim_user用户维度是电商分析的核心视角之一包含用户静态属性和缓慢变化的动态属性CREATE TABLE dim_user ( user_sk BIGINT COMMENT 代理键, user_id BIGINT COMMENT 业务主键, username STRING COMMENT 用户名, gender STRING COMMENT 性别, birth_date DATE COMMENT 出生日期, register_date DATE COMMENT 注册日期, register_platform STRING COMMENT 注册平台, vip_level INT COMMENT 会员等级, is_active BOOLEAN COMMENT 是否活跃, current_address STRING COMMENT 当前地址, start_date DATE COMMENT 记录生效日期, end_date DATE COMMENT 记录失效日期, current_flag BOOLEAN COMMENT 当前有效标志 ) COMMENT 用户维度表 PARTITIONED BY (dt STRING COMMENT 分区日期);SCD缓慢变化维处理方案Type 1覆盖原值适用于不关心历史的情况如用户昵称修改Type 2新增记录保留历史版本如会员等级变化Type 3添加字段仅保留上一个版本如当前和上一次居住地2.2 商品维度表dim_product商品维度需要处理多级类目和品牌信息CREATE TABLE dim_product ( product_sk BIGINT, product_id BIGINT, product_name STRING, category_id INT, category_name STRING, brand_id INT, brand_name STRING, price DECIMAL(10,2), cost DECIMAL(10,2), status TINYINT, online_time TIMESTAMP, offline_time TIMESTAMP, attributes MAPSTRING,STRING COMMENT 商品扩展属性 ) COMMENT 商品维度表 PARTITIONED BY (dt STRING);反规范化设计将商品类目层级一级类目、二级类目等平铺到单表中避免关联查询带来的性能损耗。3. 事实表设计与实现3.1 下单事务事实表fact_order_create记录每个订单创建事件采用事务事实表设计CREATE TABLE fact_order_create ( order_id BIGINT, user_sk BIGINT COMMENT 用户代理键, product_sk BIGINT COMMENT 商品代理键, date_sk INT COMMENT 日期代理键, merchant_sk BIGINT COMMENT 商家代理键, quantity INT COMMENT 购买数量, amount DECIMAL(12,2) COMMENT 订单金额, discount DECIMAL(12,2) COMMENT 优惠金额, payment_type STRING COMMENT 支付方式, shipping_address STRING COMMENT 收货地址, order_time TIMESTAMP COMMENT 下单时间 ) COMMENT 订单事实表 PARTITIONED BY (dt STRING COMMENT 订单日期);事务事实表特点每行代表一个业务事件数据一旦插入不会修改包含可加性度量数量、金额等3.2 支付成功事实表fact_payment记录支付成功事件与订单表形成事实星座CREATE TABLE fact_payment ( payment_id BIGINT, order_id BIGINT, user_sk BIGINT, date_sk INT, payment_amount DECIMAL(12,2), payment_method STRING, payment_time TIMESTAMP, is_first_payment BOOLEAN ) COMMENT 支付事实表 PARTITIONED BY (dt STRING);3.3 订单累计快照事实表fact_order_snapshot跟踪订单全生命周期状态变化CREATE TABLE fact_order_snapshot ( order_id BIGINT, user_sk BIGINT, product_sk BIGINT, create_date_sk INT COMMENT 创建日期代理键, pay_date_sk INT COMMENT 支付日期代理键, deliver_date_sk INT COMMENT 发货日期代理键, receive_date_sk INT COMMENT 签收日期代理键, cancel_date_sk INT COMMENT 取消日期代理键, order_amount DECIMAL(12,2), payment_amount DECIMAL(12,2), shipping_fee DECIMAL(10,2), status STRING COMMENT 当前状态, time_to_pay INT COMMENT 下单到支付间隔(分钟), time_to_deliver INT COMMENT 支付到发货间隔(小时) ) COMMENT 订单累计快照表 PARTITIONED BY (dt STRING);累计快照表特点每行代表一个业务实体如一个订单包含多个关键时间点的日期维度会随着业务流程更新记录4. 数仓分层与数据流转4.1 ODS层原始数据保留区ODSOperation Data Store层保持源系统数据原貌不做清洗转换CREATE TABLE ods_order_mysql ( order_id BIGINT, user_id BIGINT, product_id BIGINT, quantity INT, price DECIMAL(10,2), total_amount DECIMAL(12,2), create_time TIMESTAMP, update_time TIMESTAMP ) COMMENT 订单原始表 PARTITIONED BY (dt STRING);4.2 DWD层明细数据层DWDData Warehouse Detail层对ODS数据进行清洗、转换、维度关联CREATE TABLE dwd_order_detail ( order_id BIGINT, user_sk BIGINT, product_sk BIGINT, date_sk INT, quantity INT, amount DECIMAL(12,2), discount DECIMAL(10,2), payment_type STRING, order_time TIMESTAMP, source_comment STRING COMMENT 数据来源标记 ) COMMENT 订单明细表 PARTITIONED BY (dt STRING);4.3 DWS层汇总数据层DWSData Warehouse Summary层基于DWD层数据进行轻度汇总CREATE TABLE dws_user_order_d ( user_sk BIGINT, date_sk INT, order_count INT COMMENT 当日订单数, order_amount DECIMAL(16,2) COMMENT 当日订单金额, avg_order_amount DECIMAL(12,2) COMMENT 客单价, product_distinct_count INT COMMENT 购买商品种类数 ) COMMENT 用户日粒度订单汇总表 PARTITIONED BY (dt STRING);5. 模型优化与扩展实践5.1 聚合事实表设计为提高常用查询性能设计预聚合表CREATE TABLE agg_sales_category_d ( date_sk INT, category_id INT, category_name STRING, order_count INT, user_count INT, sales_amount DECIMAL(16,2), refund_amount DECIMAL(16,2), gmv DECIMAL(16,2) ) COMMENT 类目日粒度销售聚合表 PARTITIONED BY (dt STRING);5.2 维度整合技巧杂项维度将多个低基数标志字段组合到一个维度中CREATE TABLE dim_order_flag ( flag_sk INT, is_first_order BOOLEAN, is_mobile BOOLEAN, is_promotion BOOLEAN, is_urgent BOOLEAN, flag_desc STRING ) COMMENT 订单标志杂项维度;5.3 实时与离线一体化设计随着实时分析需求增加可采用Lambda架构离线层Hive 实时层Kafka │ │ └───── 服务层 ─────┘ (Doris)在实际电商数仓项目中我曾遇到商品类目频繁调整导致的历史数据分析难题。通过采用Type 2缓慢变化维技术我们完整保留了每个类目调整时间点的状态使得历史报表能够真实反映当时的业务情况。这种设计虽然增加了存储成本但为业务提供了准确的历史视角。