数据治理-维度建模
1.哪个阶段进行维度建模
面向分析侧的数据仓库建模,它发生在数据已经采集清洗完成之后,为了报表、多维统计、BI 分析而开展。
在 DWD → DIM 这个环节
- 识别事实:哪些是业务事件(检验、入库、试验、工单)
- 识别维度:分析角度(物料、项目、组织、人员、设备、时间)
- 设计事实表、维度表;确定星型 / 雪花;确定缓慢变化维 SCD 策略;
- DWD 输出事实明细;DIM 输出维度表
2.维度建模核心概念--事实表、维度表
事实表:记录发生的业务事件,存数字度量指标;每一行 = 一次检验事件
维度表:描述这件事件的各个分析对象(物料、型号项目、检验人员、组织机构、时间),用来做过滤、分组统计
举例:
1)事实表:fact_quality_inspect(质量检验事实表,DWD 层明细事实)
粒度:单条零部件检验记录,一次检验一行 字段分为两类:维度代理外键(关联维度表) + 度量指标(可统计的数字)
| 字段 | 说明 |
|---|---|
| inspect_fact_id | 事实唯一主键 |
| material_sk | 物料维度代理主键(关联 dim_material,SCD2 必须存代理键,不存业务物料编码) |
| project_sk | 型号项目维度代理主键(关联 dim_project) |
| person_sk | 检验人员维度代理主键(关联 dim_person) |
| org_sk | 组织机构维度代理主键(关联 dim_org) |
| date_sk | 时间维度代理主键(关联 dim_date) |
| inspect_total_num | 度量:送检总数量 |
| inspect_qualified_num | 度量:合格数量 |
| inspect_unqualified_num | 度量:不合格数量 |
✅解读: 本表不存物料名称、项目名称、人员名字,这些描述全部放到维度表。 只存事件:谁、什么物料、哪个型号项目、哪天做的检验,以及送检 / 合格 / 不合格这些数字。
2)维度表示例(DIM 层,4 张核心维度,全部来自 MDM 主数据加工)
① dim_material 物料维度表(SCD2 缓慢变化维)
物料是主数据,物料编码业务主键不变;
| 字段 | 说明 |
|---|---|
| material_sk | 代理主键(维度表唯一主键,事实表引用这个) |
| material_code | 业务主键:物料编码(如 YQ‑00123),业务系统不变编码 |
| material_name | 物料名称:滤波电容 |
| material_type | 物料大类:电子元器件 |
| material_sub_type | 物料小类:电容电阻 |
| secret_level | 密级:内部 / 秘密 / 机密 |
| spec_model | 规格型号 |
| valid_start_date | 生效开始时间(SCD2) |
| valid_end_date | 生效失效时间(SCD2,9999‑12‑31 代表当前有效) |
| is_current | 是否当前有效 1/0 |
②dim_project 型号项目维度表(SCD2)
业务主键:项目型号编号;项目主管、归属分系统会发生变更,SCD2 保存历史
|project_sk | 代理主键 | |project_code | 型号项目编号(业务主键)| |project_name|XX 卫星研制项目 | |sub_system | 所属分系统 | |project_owner | 项目主管 | |valid_start_date | 生效时间 | |valid_end_date | 失效时间 | |is_current | 是否当前 |
③ dim_person 检验人员维度(SCD2)
人员工号不变;人员调动科室、岗位变化,SCD2 记录历史
| |person_sk | 代理主键 | |emp_code | 工号(业务主键)| |emp_name | 姓名 | |post | 岗位:检验工程师 | |dept_name | 所属科室 | |valid_start_date | 生效时间 | |valid_end_date | 失效时间 | |is_current | 是否当前 |
④ dim_date 时间维度(特殊维度,无 SCD,固定静态表)
表格
| 字段 | 说明 |
|---|---|
| date_sk | 时间代理键 20260215 |
| dt | 日期 2026‑02‑15 |
| year | 2026 |
| month | 2 |
| quarter | Q1 |
| is_workday | 是否工作日 |
3)整体模型结构:星型模型
中心:fact_quality_inspect 检验事实表 向外直接关联 4 张扁平化维度表:dim_material、dim_project、dim_person、dim_org、dim_date。
维度表不做二次拆分,全部属性放在一张维度表,减少 join,查询性能好,业务人员容易看懂。

3.缓慢变化维 SCD 策略
SCD 一共有 6 种策略,项目实际只用 SCD1、SCD2,SCD3 少量使用,SCD4‑SCD6 几乎不用。
1)SCD1:直接覆盖(重写)
逻辑:属性发生变化,直接 UPDATE 维度表那一行,把旧值覆盖成新值。
- 优点:最简单,表结构不用加额外字段;存储量小。
- ❌致命缺点:丢失历史状态。
2)SCD2:新增历史版本行(生产最常用)
逻辑:属性变更,不修改旧行,新增一条维度记录,增加时间字段标记生命周期:生效开始时间、生效结束时间、是否当前有效。
- 优点:完整保留历史状态,历史报表不会错乱,满足科研、质量追溯对历史数据还原的要求。
- 缺点:维度表行数膨胀;ETL 逻辑复杂;事实表必须存储维度代理键,不能直接存业务主键。
4.维度建模怎么建
维度建模完整实操步骤
前置前提:已经完成需求调研、数据源梳理、ODS 层落地、DWD 完成清洗与编码标准化。
输出产物:业务粒度定义、事实表、维度表、模型类型(星型 / 雪花)、SCD 策略、代理键规划、物理表设计。 以【零部件入所质量检验】业务主题作为完整案例。
整体分为 5 大步骤:
- 选择业务主题,确定事实表粒度(最关键第一步)
- 识别事实:确定事实表、度量指标
- 识别维度:确定所有维度表
- 模型选型(星型 or 雪花)+ 确定每个维度 SCD 策略
- 设计物理表(代理键、字段、拉链字段、主键外键),输出建表伪代码
步骤 1:选定业务主题,定义事实表粒度
粒度 = 事实表每一行代表业务的哪一件事。粒度一旦定错,整个模型全部作废。 粒度分三类:
- 事务粒度(最细:一次检验、一条工单、一次试验)
- 周期快照粒度(每天快照:库存每日快照)
- 累积快照粒度(业务流程:检验‑评审‑入库完整流程)
案例:质量检验主题 业务主题:零部件入所检验 ✅选定粒度:每一次零部件检验记录,一行代表一次检验事件(事务粒度,DWD 明细事实)
禁止:一行存 “某物料某月汇总”,汇总放到 DWS 层,DWD 事实必须保留最细粒度。
粒度文档要写清楚: 事实表粒度:一条检验记录;一条记录对应一个物料、一次送检检验业务动作。
步骤 2:识别事实,设计事实表
- 明确业务事件是什么:零部件送检检验事件。
- 找出度量指标(可求和、统计的数字):送检数量、合格数量、不合格数量、不合格件数。
❌不要把文本描述(物料名称、人员姓名)放到事实表。文本属性归维度表。
- 事实表字段固定分为两部分:
- 各个维度的代理主键 SK(外键),用来关联维度表
- 业务度量指标(数字)
- 不要直接使用业务编码(物料编码、工号)做外键;SCD2 场景必须使用代理键。
案例事实表:fact_quality_inspect | 字段 | 说明 | |---|---| |inspect_fact_id | 事实表主键 | |material_sk | 物料维度代理键 | |project_sk | 型号项目维度代理键 | |person_sk | 检验人员维度代理键 | |org_sk | 组织机构维度代理键 | |date_sk | 时间维度代理键 | |inspect_total_num | 送检总数【度量】| |inspect_qualified_num | 合格数【度量】| |inspect_unqualified_num | 不合格数【度量】|
注意:事实表没有 SCD。事实记录一旦生成,代表已经发生的业务事件,一般不修改,只追加写入。
步骤 3:识别维度,设计维度表
思考:业务会从哪些角度分析这份事实数据? 业务问题:按什么分组、过滤、下钻? “按什么看数据,什么就是维度”。
案例检验业务分析角度:
- 看什么物料 → 物料维度 dim_material(来自 MDM 主数据)
- 哪个型号项目 → 项目维度 dim_project
- 谁检验的 → 人员维度 dim_person
- 哪个检验科室 → 组织机构维度 dim_org
- 什么时间检验 → 时间维度 dim_date(静态维度)
每个维度要区分:
- 业务主键:业务系统原始编码(物料编码、项目编号、工号,业务侧不变)
- 代理主键 SK:维度表内部唯一主键,事实表引用它
- 一堆业务属性(名称、分类、密级、岗位、归属分系统)
- 如果是 SCD2,增加拉链字段:
valid_start_date、valid_end_date、is_current
重点:主数据(物料、项目、人员、组织)直接加工生成维度表,不要直接拷贝源系统表,完成编码标准化。
步骤 4:选定模型形态 + 逐个维度确定 SCD 策略
4.1 选择星型 / 雪花模型
航天数仓绝大多数场景:星型模型优先
- 星型:事实表直接关联全部维度表;维度表所有属性放在一张表里,不拆分。
- 雪花:维度表再拆分子表,维度内部再 JOIN。层级极多才考虑,一般不使用。
案例:质量检验主题,采用星型模型。 中心事实表 fact_quality_inspect,直接关联 5 张维度表。
4.2 逐个维度评估 SCD 策略(这是建模必须输出文档)
逐个维度看:维度的属性会不会变更?变更之后历史统计是否需要保留?
表格
| 维度 | 会变化的属性 | SCD 策略选择 | 说明 |
|---|---|---|---|
| dim_material 物料维度 | 物料分类、密级 | SCD2 | 分类变更,质量追溯需要历史,拉链表 |
| dim_project 项目维度 | 分系统归属、项目主管 | SCD2 | 项目信息变更,需要历史统计 |
| dim_person 人员维度 | 所属科室、岗位 | SCD2 | 人员调动,保留历史归属 |
| dim_org 组织机构 | 部门名称、上级部门 | SCD2 | 机构调整 |
| dim_date 时间维度 | 无变更 | 无 SCD | 静态维表,一次性生成 |
个别不重要属性(备注、联系人电话),即使 SCD2 维度内,这类字段变更可以采用 SCD1 直接覆盖。
文档必须记录: 物料维度:物料分类、密级采用 SCD2;备注字段采用 SCD1。
步骤 5:物理模型设计(代理键、SCD 拉链字段、建表)
5.1 代理键 SK 是什么
- 代理键(Surrogate Key,sk):数仓内部生成无业务含义数字 ID。
- 业务主键:业务系统编码,业务含义,会重复(SCD2 多条记录共用同一个业务编码)。
- SCD2 场景,事实表只能存代理键 sk,不能存业务编码。
5.2 SCD2 维度表固定必带拉链字段
material_sk bigint 代理主键
material_code varchar 业务主键(物料编码)
……业务属性……
valid_start_date date 版本生效时间
valid_end_date date 版本失效时间,当前有效写9999‑12‑31
is_current tinyint 是否当前版本1/0
5.3 时间维度特殊处理
时间维度 dim_date,独立生成,不要用事实表里的日期字符串代替;包含年、季度、月、周、工作日标记。没有 SCD。
步骤 6:ETL 加工逻辑设计(建模不是只画表,要写加工逻辑)
- 事实表 ETL(DWD 层) 从 ODS 清洗后明细,转换输出事实;关联维度,匹配到正确版本的代理 SK 写入事实。
⚠️重点:一条检验发生在 2026‑02‑15,要根据检验发生时间匹配维度表里该时间区间生效的那一条 SK。
- SCD2 维度 ETL(DIM 层)
- 从 MDM/ODS 取最新业务数据;
- 和维度表中当前有效版本做对比;
- 属性发生变化:关闭旧版本(更新 valid_end_date,is_current=0);新增一条新版本行,生效时间为变更日期。
步骤 7:模型评审
评审点:
- 事实粒度是否清晰统一;
- 度量是否全部为数字,文本属性是否下沉到维度;
- SCD 策略选择是否合理,历史追溯是否满足军工业务;
- 是否滥用雪花模型;
- 外键是否全部使用代理键 SK;
- 维度是否复用主数据标准;
- 是否存在维度重复建设(物料维度多处重复建)。
步骤 8:DWS 汇总层(基于维度模型之上)
DWD 明细事实 + DIM 维度表已经建好,DWS 做预聚合宽表。
DWS 依旧引用同样的事实与维度,只是把指标按项目‑月、物料分类‑月做汇总,用于报表提升性能。
整体流程一句话总结
- 定业务主题,定事实粒度;
- 确定业务事件、度量指标,设计事实表;
- 梳理分析角度,识别全部维度;
- 确定星型 / 雪花;逐个维度定 SCD 策略;
- 设计物理表,定义代理键、SCD 拉链字段;
- 编写 ETL 加工逻辑;
- 评审落地;DWS 做上层汇总。
常见踩坑清单
- 粒度混乱:DWD 事实直接做月度汇总,丢失明细;
- 事实表放大量文本字段;
- SCD2 维度,事实表存业务编码,不用代理键,SCD 完全失效;
- 全部无脑 SCD2,维度数据爆炸;不重要属性用 SCD1;
- 直接拷贝业务库表当维度,不对接 MDM 主数据;
- 过度雪花,多层嵌套维度,查询性能差。
浙公网安备 33010602011771号