范式建模 维度建模
范式建模(Inmon) 维度建模(Kimball)
数仓如何选择 建模方案
为什么现在明细层数仓也用维度建模
以前用传统数据库(Oracle/DB2),存储很贵,所以要用3NF精打细算消除冗余。现在用云数仓(如Snowflake、MaxCompute、Hologres),存储成本极低。很多公司直接在明细层(DWD)就用维度建模的宽表(大宽表),把冗余字段带进去,用空间换时间
ddl角度对比 范式建模 维度建模
维度建模 ddl对比
以“业务分析”为中心,把“谁、什么、何时”做成维度表(Dimension),把“度量值”做成事实表(Fact)。允许冗余,目的是查询极快
范式建模 ddl对比
像做“乐高零件”一样,按业务实体(人、货、单)拆得干干净净,零冗余。你要看完整订单,必须把零件拼起来(多表Join)。
Data Vault建模 ddl对比
Data Vault 把任何业务数据强行拆成三种表:
Hub(中心表):只存业务主键(如
customer_id,order_id)。就相当于一个“纯ID索引目录”,不存任何描述性文字。Link(链接表):只存业务关系(如“这个订单_包含了_哪个商品”)。就是多对多关系的纯ID组合。
Satellite(卫星表):存属性的变化历史(如客户改名、订单状态变更为已发货)。它是拉链表(SCD Type 2)的极致形态,记录每个属性的起止时间。
Data Vault 会拆成 5 张表(注意观察字段):
gmv为例 对比sql
范式建模
维度建模
Data Vault
-- Data Vault 查询:需要处理时态(Temporal)+ 关系(Link)+ 哈希键(Hash Key) WITH -- 1. 找出 2026年8月 期间有效的“手机”类商品(处理拉链历史) valid_product_hk AS ( SELECT product_hk FROM sat_product sp WHERE sp.category = '手机' -- 品类过滤 AND sp.load_dts <= '2026-08-31 23:59:59' -- 拉链开始时间 <= 查询日期 AND sp.load_end_dts > '2026-08-01 00:00:00' -- 拉链结束时间 > 查询日期 AND sp.rec_src = 'mysql_binlog' -- 防重(有些DV实现会有重复) GROUP BY product_hk -- 因为拉链表可能有多条记录,去重取最新或有效的那条 ), -- 2. 通过 Link 表,找出这些手机对应的所有订单 ID(关系解耦) order_hk_with_phones AS ( SELECT lop.order_hk FROM link_order_product lop INNER JOIN valid_product_hk vp ON lop.product_hk = vp.product_hk ), -- 3. 查询订单明细卫星表,捞取 8月份 已完成 的订单金额(再次处理时态) valid_order_gmv AS ( SELECT sod.order_hk, SUM(sod.amount) AS gmv -- 金额已在卫星表冗余 FROM sat_order_detail sod INNER JOIN order_hk_with_phones owp ON sod.order_hk = owp.order_hk WHERE sod.order_status = '已完成' AND sod.load_dts <= '2026-08-31 23:59:59' AND sod.load_end_dts > '2026-08-01 00:00:00' -- 关键:下单时间通常也记录在卫星表的属性里,这里必须再加一道时间过滤 AND sod.order_dt >= '2026-08-01' AND sod.order_dt < '2026-09-01' GROUP BY sod.order_hk ) -- 4. 最终汇总 SELECT SUM(gmv) AS total_gmv FROM valid_order_gmv;