业务库为什么不能直接拿来分析
业务库(OLTP)是为“一笔笔交易能正确写入”设计的,表结构高度规范化、拆得很碎,为的是少冗余、快写入。而分析(OLAP)要的是“按各种维度聚合大量数据”:比如按地区、按品类、按天统计销售额。直接在业务库上跑这种分析,多表 join 复杂、扫描行数巨大、还会和在线交易抢资源。
数据仓库的价值,就是把业务数据抽出来、清洗、重新组织成适合分析的结构,让分析查询跑得快、口径统一。其中最经典的方法就是 Kimball 提出的维度建模:围绕业务过程,用“事实 + 维度”的方式组织表,让分析师像在一个立方体上切来切去。
- 分层ODS 贴源、DWD 明细、DWS 汇总,逐层加工。
- 事实表存业务过程的度量,如一笔销售的金额、数量。
- 维度表存从哪个角度看,如时间、地区、商品。
- 星型模型事实表居中,维度表围绕,简单直观。
数仓分层:ODS、DWD、DWS
现代数仓不是一张大表,而是分层加工:
- ODS(贴源层):几乎原样同步业务库的数据,只做格式对齐,保留历史。
- DWD(明细层):把 ODS 清洗、去重、规范化,形成干净的业务明细,一行就是一笔业务事实。
- DWS(汇总层):按主题把明细预聚合,如“每天每地区每品类的销售额”,供报表直接查询。
- ADS(应用层):面向具体报表或指标集市的最终结果表。
分层的意义是解耦与复用:业务库变了只影响 ODS,口径统一在 DWD,DWS 把高频聚合预计算好。不要一步到位从业务库直接出报表,那样口径乱、重复加工、改一次牵一发动全身。
事实表与维度表
维度建模的两个主角:
- 事实表:记录一次业务事件,一行是一条事实,里面放外键(指向各维度)和可度量的数值(数量、金额、次数)。比如“2026-10-21,上海,苹果手机,卖出 2 台,金额 11998 元”。
- 维度表:描述事实从哪个角度看,存放这个角度的各种描述属性。时间维度表有年月日、星期、是否节假日;地区维度表有省市区;商品维度表有品类、品牌。
设计时先问“业务要度量什么过程”(下单、支付、退款),那就是事实表;再问“想从哪些角度切它”(时间、地区、用户、商品),那些就是维度表。事实表通常很宽但行多,维度表行数少但属性丰富。
星型模型与雪花模型
把事实表放中间、维度表围绕在周围,就是星型模型:事实表的外键直接指向维度表的主键,不做进一步拆分。好处是 join 少、直观、查询快,是分析场景的首选。
如果把维度表本身也规范化拆成多层(比如地区再拆成省、市、区三张表),就成了雪花模型。它冗余更少,但 join 更深、查询更慢、理解更难。数仓里通常主动接受维度表的冗余(地区维度表里直接写上省市区全名),换取查询简单——这叫“反规范化”,是维度建模的有意选择。
# 星型模型示意
fact_sales( date_key, region_key, product_key,
quantity, amount )
dim_date( date_key, year, month, is_holiday )
dim_region( region_key, province, city, district )
dim_product( product_key, name, category, brand )
怎么设计维度
设计维度有几个要点:维度表要尽量宽,把分析时会用到的描述属性都放进去,别让分析师为了一个“商品品牌”还要多 join 一张表。常见维度包括时间、地点、人员、商品、渠道,它们在不同事实表之间应尽量复用(同一套 dim_date 服务所有事实表)。
日维度尤其常用:把日期预生成成一张维度表,带上年、季、月、周、星期、是否节假日、是否周末,分析时直接关联,避免每次写一大堆日期函数。退化维度(如订单类型这种只有几个值的小属性)可以直接塞进事实表,不必单独建表。
缓慢变化维
现实里维度的属性会变:一个用户换了手机号、一个商品改了所属品类。分析时往往要回答“按当时的品类统计”和“按当前品类统计”两个不同口径。这就是缓慢变化维(SCD)要解决的问题。
- 直接覆盖(SCD1):属性变了就更新成新值,不保留历史。适合“换了就按新的算”的场景。
- 加新行(SCD2):给维度表加有效期起止,属性变了就插一条新行,老行标记为失效。历史事实关联哪条行,就用哪期的属性,能还原当时的口径。
要按历史口径还原时,用 SCD2;不关心历史、只要当前最新值时,用 SCD1。别对所有维度都上 SCD2,否则维度表膨胀、关联复杂。
一致性与治理
数仓最大的坑不是技术,是口径不一致:不同报表的“销售额”差几个点,最后没人信。维度建模的核心武器是一致性维度——时间、地区、商品这些公共维度全公司共用同一张表,任何事实表都关联同一套 dim_date、dim_region,这样“按月统计销售额”在任何报表里口径都一样。
治理上要建指标体系:核心指标统一定义、统一在 DWS 预计算,应用层只引用不重算。数据仓库不是堆一堆表,而是一套“让所有分析说同一种语言”的秩序。可结合本站《数据仓库与 OLAP 实战:ClickHouse 入门》了解列式存储怎么承载这些建模结果。
实战清单
落地清单:
- 别在业务库上直接跑分析,先抽数据进数仓分层。
- 按 ODS、DWD、DWS、ADS 逐层加工,解耦复用。
- 先定业务过程(事实表),再定分析角度(维度表)。
- 优先用星型模型,维度表反规范化换查询简单。
- 公共维度全公司复用,保证指标口径一致。
- 维度属性会变时,按需要选 SCD1 覆盖或 SCD2 留痕。
- 核心指标在 DWS 预聚合,应用层只引用。
维度建模的精髓,是把杂乱的业务明细,组织成“事实居中、维度环绕”的可分析结构。一旦公共维度和指标口径统一,数据仓库就从一堆表,变成了整个公司都能用来提问、而且答案彼此一致的分析资产。