type
Post
status
Published
date
Apr 4, 2020 15:42
slug
summary
本文梳理了数据仓库、数据集市与数据湖的核心概念与差异,并从工程视角总结了构建数仓的关键步骤。随后对比了 Inmon(自顶向下)与 Kimball(自底向上)两种数仓方法论,说明各自的适用场景与取舍。文章还给出了常见数仓分层(ODS/DWD/DWS/DM)的落地视图,并进一步解释事实表、维度表、缓慢变化维、退化维等关键建模概念,最后用星型、雪花、星座模型帮助读者建立更直观的建模框架。
tags
Data Warehouse
推荐
category
Data Engineering
icon
password
wordCount
2699
数据仓库的价值不在“把数据搬到一起”,而在“把数据变成可复用的决策能力”。如果把数仓当成一个更大的数据库,后面一定会在口径、性能、治理、迭代速度上反复踩坑。
阅读方式建议:
- 先看「数据仓库 vs 数据集市 vs 数据湖」把概念对齐。
- 再看「Inmon vs Kimball」理解两套方法论的取舍。
- 最后看「分层 + 事实维度 + 建模」把落地路径串起来。
数据仓库(Data Warehouse)
数据仓库是一个面向主题(Subject Oriented)、集成(Integrated)、相对稳定(Non-Volatile)、反映历史变化(Time Variant)的数据集合,用于支持企业或组织的决策分析。
核心要点:数据仓库面向分析(OLAP),区别于业务系统的操作型数据库(OLTP)。
- 面向主题:按“业务分析主题”组织数据,比如“销售”“库存”“用户增长”。在建模上经常落到事实表主题。
- 集成:数据源可能来自业务库、文件系统、消息中间件等。抽取与清洗时要消除口径不一致,保证仓内信息是全局一致的。
- 相对稳定:进入数仓后的数据以查询为主。历史数据通常不会被原地更新,而是通过 insert 或分区替换等方式体现变化。
- 反映历史变化:为支撑趋势分析、回溯与审计,数仓会保留不同时间点的数据快照。
数据集市(Data Mart)
数据集市是面向特定部门或场景的子集,通常按多维方式组织,常见结构是星型:一张事实表 + 多张维度表。
常见误区:“先做很多独立集市,最后自然长成企业级数仓”。
现实里,多个独立集市往往会形成新的信息孤岛,口径难统一。是否先建集市还是先建企业级仓,被戏称为数据仓库领域的“宗教之争”。
数据湖(Data Lake)
数据湖是一种“先存下来再说”的存储理念,强调用自然格式保留数据。
- 覆盖结构化(关系表)、半结构化(CSV、日志、JSON、XML)、非结构化(文档、邮件)、二进制(图片、音视频)等多类型数据。
- 你可以把它理解为:更靠近原始数据、更宽松的存储容器。
构建数仓的一般步骤(从需求到模型)
- 确定主题:例如“某年某月某地区的商品销售情况”。主题要包含分析角度(维度)与统计值(量度)。
- 确定量度(指标):如销售额、订单数、活跃用户等。量度可能需要求和、求次数、去重次数、最大最小等。
- 确定粒度:量度在什么粒度被记录与汇总。
- 遵循“最小粒度原则”:尽量保留未来可能需要的最细粒度。
- 但也要平衡成本:如果未来分析只需要按天,ETL 中可以按天汇总。
- 确定维度:维度是分析的角度,比如时间、地区、渠道、商品。
- 确定事实表:事实表通常由维度外键 + 数值型度量组成(以及可选的退化维、日期时间戳等)。
Inmon vs Kimball:两种方法论的取舍
这部分可以用一句话概括:
- Inmon:更偏“先把企业级的统一模型建好”。
- Kimball:更偏“围绕可交付的业务主题快速建起来”。
Inmon(自顶向下)
Inmon 更像瀑布式:数据源 → 数据仓库(DW,偏实体-关系)→ 数据集市(DM)。
开发流程(概念)
- 先探索数据源并定义清洗规则。
- 经由 ETL,把数据清洗后以实体-关系模型进入 DW。
- 在 DW 做治理与一致性。
- 再从 DW 输出到各个 DM,服务 BI 与分析。

Kimball(自底向上)
Kimball 更像敏捷:围绕业务主题先落地集市(维度-事实),再逐步扩展形成更大范围的一致模型。
开发流程(概念)
- 围绕最终分析目标拆解需求。
- 明确依赖后,以维度表 + 事实表形式先在 DM 层交付。
- 随着主题增多,通过一致性维度等方式逐步扩大覆盖面。

Inmon vs Kimball:特性对比
特性
特性 | Kimball | Inmon |
数据摄取 | Yes | Yes |
Stage(缓冲区) | Yes | Yes |
ETL | Yes | Yes |
数据集市(DM) | Yes | Yes |
需求驱动 | Yes | 更偏数据/模型驱动 |
数据仓库优先 | No | Yes |
事实维度拆分 | Yes | 不一定 |
关系表维护 | 少 | 多 |
建模泛化 | 较少 | 较多 |
优劣对比(更贴近工程感受)
维度 | Kimball | Inmon | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ |
交付速度 | 快 | 慢 | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ |
开发难度 | 相对低 | 相对高 | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ |
维护难度 | 随主题变多会变高 | 模型统一后可能更可控 | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ |
技能要求 | 入门到中级可上手 | 更需要资深建模经验 | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ |
适用场景 | 业务变化快、强调快交付 | 强调一致性、治理优先 | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ |
用一个例子把差异讲透(股票交易简化场景)
(OLTP)原始事务表(简化)
交易记录ID | 用户ID |
1 | 1 |
2 | 1 |
成交日志表(记录成交)
成交日志ID | 用户ID |
1 | 1 |
Inmon 模式会怎么拆
会更偏向把实体拆细,并显式维护关系:用户实体、成交实体、关系表等。
用户实体表(示意)
用户ID | 姓名 | 联系方式 | 风险评级 | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ |
1 | 张三 | 1234567890 | 高 | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ |
成交关系表(示意)
成交ID | 用户ID |
1 | 1 |
Kimball 模式会怎么做
会更偏向围绕分析主题落地维度与事实:用户维度表、成交事实表、资产事实表等。
直观差异:Inmon 更像先把“世界的实体与关系”建清楚;Kimball 更像先把“问题要怎么分析”跑通。
数据仓库分层(一个可落地的工程视图)
不同公司会有不同层数与命名,但常见思路如下。
ODS(原始接入层)
- 功能:数仓准备区,为后续明细层提供原始数据,减少对业务系统影响。
- 原则:尽量贴近业务库结构,不做或少做清洗,支持增量抽取与周期存储。
DWD(明细层)
- 功能:沉淀业务明细,支撑长期历史分析。
- 原则:在贴近源的基础上做轻度清洗、统一字段与口径,通常按天/月分区。
DWS(汇总/服务层)
- 功能:面向分析主题的汇总与宽表,直接服务上层使用。
- 原则:在 DWD 基础上做脱敏、清洗、衍生指标与公共维度对齐。
DM(应用层)
- 功能:面向具体应用或报表的最终数据。
- 原则:数据量更小、查询更快、口径更稳定,并支持回溯与重算。
名词对照
名词 | 简称 | 解释 |
Data Warehouse | DW | 数据仓库主体 |
Operational Data Store | ODS | 原始接入层,贴近源系统,支持增量抽取 |
Data Warehouse Detail | DWD | 明细层,沉淀长期历史明细 |
Data Warehouse Service | DWS | 服务/汇总层,主题宽表与公共指标输出 |
Data Mart | DM | 应用层或集市层,面向特定业务/报表 |
Enterprise Data Warehouse | EDW | 企业级统一数仓,强调一致性与治理 |
代理键与自然键
- 自然键:现实世界中天然存在且有业务意义的唯一标识,比如身份证号。
- 代理键:无业务意义的技术键,比如自增 ID 或 UUID。
事实表(Fact)
事实表以“业务过程”为中心。除了数值度量外,事实表通常包含连接维度的外键,也可能包含退化维与时间戳。
事实表的三种常见类型
- 事务事实表(Transaction Fact):原子粒度,记录业务事件。数据通常只插入不更新。
- 周期快照事实表(Periodic Snapshot Fact):按固定周期(天、月)记录快照,例如日库存快照。
- 累积快照事实表(Accumulating Snapshot Fact):记录过程生命周期多个关键节点,随着过程推进持续更新。
周期快照 vs 累积快照(对比示例)
周期快照(每天一行)
日期 | 订单ID | 下单时间 | 支付日期 | 确认收货日期 |
20200401 | 1 | 2020/04/01 11:00 | NULL | NULL |
20200402 | 1 | 2020/04/01 11:00 | 2020/04/02 12:00 | NULL |
累积快照(过程一行)
订单ID | 下单时间 | 支付日期 | 确认收货日期 | ㅤ |
1 | 2020/04/01 11:00 | 2020/04/02 12:00 | 2020/04/03 13:00 | ㅤ |
事实表中的空值
- 度量(数值字段)可以为空。
- 外键一般不建议为空,否则会影响参照完整性与维度对齐。
维度表(Dimension)
维度用于描述事实发生的环境,用来约束查询、分类汇总与排序。
缓慢变化维(SCD)常见处理
- 重写维度值:直接更新维度,历史不可追溯。
- 插入新行:保留历史版本,通过版本号、生效/失效时间区分。
- 添加新列:用新列保存新值,适用于少量变化字段。
退化维度(Degenerate Dimension)
退化维是事实表里的一列“像维度一样可筛选、可 group by”的字段,但没有对应维表。
- 常见:订单号、发票号、流水号。
- 优点:ETL 简化、分组更快、仍能支持切片与下钻。
杂项维度(Junk Dimension)
把一堆低基数标识与指示器合并成一张维表,避免为每个小字段单独建维。
上卷(Roll-up)与下钻(Drill-down)
- 上卷:沿维度层级向上聚合,例如从“天”汇总到“月”。
- 下钻:沿维度层级向下细分,例如从“月”细到“天”。
数据建模:星型、雪花、星座
星型模型
所有维表直接连接到事实表,结构像星星。

优点
- 查询效率高(少 join)
- ETL 相对简单
缺点
- 维表会有冗余(反范式)
雪花模型
星型的进一步规范化,维表再拆分层级,join 变多。

优点
- 冗余更低,更接近范式
缺点
- 查询更复杂,性能通常不如星型
- ETL 逻辑更复杂
星座模型
多个事实表共享公共维度,是数仓里很常见的形态。

三种模型对比图

总结
- 数仓/集市/湖的差异,本质是“组织数据的目的”不同:湖偏存储,仓偏一致性与分析,集市偏交付与场景。
- Inmon 与 Kimball 没有绝对对错,取决于组织规模、治理成熟度与交付节奏。
- 工程落地时,分层与事实维度建模是最常见的抓手。
- 很多团队的真实情况是:大多数时间在数据治理、口径对齐、调度与清洗,真正做挖掘的时间反而更少。
