数仓建模速查
维度建模与缓慢变化维、事实表设计、指标体系、分层规范、湖仓与 OLAP 选型、数据治理:数仓建设速查。
建模基础
维度建模流程与总线矩阵
Kimball 与 Inmon 方法论对比
Inmon 主张先建企业级规范化模型(CIF)再衍生集市;Kimball 主张以维度模型自下而上快速交付;现代实践多为两者融合。
Data Vault 模型基础
Data Vault 用 Hub(业务键)、Link(关系)、Satellite(描述属性)三类对象组织数据,强调可审计、可并行加载与源系统可追溯。
总线矩阵 Bus Matrix
总线矩阵行为业务过程、列为一致性维度,交叉标记使用关系;它是数仓全局规划看板,保证不同事实表可以按同一套维度下钻。
桥接表 Bridge Table
处理事实与维度多对多关系(一订单多促销、一文章多标签)时,用桥接表保存关系及其权重,避免事实表行数虚增。
雪花模型 Snowflake Schema
雪花模型把维度进一步范式化拆分为多层子维;存储更省、层次更清晰,但 join 变多、查询复杂度上升。
星型与雪花的取舍清单
取舍维度:下游工具能力、join 性能、维度变更频率、团队约定;分析型场景通常倾向星型,维度高度共享且变化频繁时局部雪花化。
Hub/Link/Satellite 设计要点
Hub 只存业务键去重与加载信息,Link 只存关系,属性全部放 Satellite;变更检测用 hashdiff,多源属性用多 Satellite 隔离。
一致性维度 Conformed Dimension
一致性维度是在多个事实表间共享、定义与取值一致的维度;它让不同业务过程能在同一维度上对齐汇总与对比。
角色扮演维度 Role-Playing Dimension
同一维度在事实表中承担多个角色(下单日期/支付日期/发货日期都指向日期维度),物理上共用一张维度表。
多值维度的处理方式
多值维度三种处理:事实表存分隔串(不可取)、桥接表(可分摊)、反向事实表(一对多反转);按查询与分摊需求选择。
代理键设计 Surrogate Key
维度表用无业务含义的自增/序列代理键做主键,事实表存代理键关联;代理键隔离业务键变化,支持同一业务键多个版本。
事实表外键与外键约束
数仓事实表保留维度外键但通常不建数据库级外键约束(影响加载性能);引用完整性靠 ETL 校验与对账保障。
示例:交易域订单事实建模
订单过程常见两粒度:订单头(一笔订单一行)与订单明细行;两者分别建事实表并通过退化维度订单号关联,避免粒度混杂。
维度建模四步法 Kimball Process
维度建模按固定顺序推进:选择业务过程 → 声明粒度 → 确认维度 → 确认事实,四步顺序不可倒置,粒度声明决定后续一切。
一致性事实 Conformed Fact
一致性事实是在多个事实表间定义一致、可直接比较或合并的度量;金额、数量类度量都要明确币种、单位与口径版本。
星型模型 Star Schema
星型模型由中心事实表与外围维度表组成,维度直接连事实、不做多级范式拆分;查询 join 层数少,对 BI 与分析引擎友好。
Data Vault 与维度建模的取舍
取舍视角:接入敏捷与可审计选 Data Vault,分析体验与交付速度选维度模型;两者常组合为「Vault 做集成层、维度模型做集市层」。
杂项维度 Junk Dimension
把多个低基数的标志位(是否首单、是否含赠品等)合并成一张杂项维度,避免事实表字段膨胀与维度表碎片化。
缩小维度 Shrunken Dimension
从大维度中裁剪出事实表只需要用到的属性子集(如商品维度只取类目层级),减少 join 宽度与聚合开销。
支架维度 Outrigger Dimension
支架维度是被其他维度引用的维度(雪花化的产物),如商品维度引用类目维度;星型中应尽量控制其数量。
递归层次:树形结构建模
组织、类目等树形结构在维度中可用 parent_key 自关联递归;固定深度场景可物化层级路径列(l1/l2/l3)便于分析。
粒度声明:模型的地基
粒度声明用一句话回答「一行代表什么」;粒度越细灵活性越高但存储越大,粒度越粗则无法下钻,声明后写进表注释与文档。
未知成员与默认维度行
为处理无法匹配的维度引用,维表预制未知成员行(如 -1/unknown),事实表匹配失败时落默认键,保证事实不丢且可追查。
维度引用完整性检查
加载后校验事实外键在维度中均有对应;发现孤儿键先隔离再定位来源(新编码、同步延迟、维度过滤)。
事实表命名与度量字段规范
事实表以 fact_ 前缀 + 过程命名(fact_order),粒度后缀(_d/_di/_df)区分增量与快照;度量字段带单位语义(amount/amt_qty)。
示例:财务域账单事实建模
账单过程关注账期、应收、实收与状态流转;金额度量区分应收/实收/退款,时间维度区分账期日与到账日。
示例:流量域会话事实建模
流量域以会话(session)为粒度记录访问行为:来源渠道、设备、落地页维度,配合页面事件事实表支撑漏斗分析。
模型文档要素清单
每张模型表文档包含:粒度声明、维度含义、度量口径、更新频率、Owner、上下游血缘、示例查询;缺项不得上线。
总线矩阵的填写颗粒度
矩阵交叉格建议标注使用状态:强依赖(必然使用)、可选(可能使用)、不使用;新业务过程先对齐已有维度列再考虑扩列。
星座模型 Galaxy Schema
星座模型(事实星座)是多个事实表共享若干一致性维度的组合形态,是总线架构下的常态而非特殊模式。
码表与字典维度 Lookup Dimension
编码类字段(状态码、渠道码)统一下沉为码表维度,事实表存编码,展示时 join 翻译;避免编码含义散落在 SQL 常量里。
均衡层次与不规则层次
均衡层次深度一致(年月日),可直接物化列;不规则层次深度不一(类目深浅不一),需要路径列或桥接表表达。
区间层次 Ragged Hierarchy
成员深度不齐且允许同层跳级时,用最低公共祖先与深度列配合区间表达;常见于类目与组织混合管理场景。
主题域划分方法
主题域按业务对象聚类(用户域、商品域、交易域、履约域等),边界以业务过程归属为准,跨域交互通过一致性维度连接。
业务过程的选择标准
业务过程是业务可观测的事件或状态(下单、支付、收货);选择标准:有分析价值、有稳定粒度、可获取数据。
数仓中的三类键
区分业务键(源系统主键)、代理键(维表主键)、技术键(加载批次/哈希);三类键在模型文档中分别声明用途。
维度表命名与字段规范
维度表以 dim_ 前缀 + 主题命名(dim_user),主键 *_sk,业务键 *_id,描述字段用业务术语;规范统一后跨表自解释。
ER 模型到维度模型的转换
从 ER 图出发:识别业务过程 → 把实体按角色归为维度/事实 → 多对多关系用桥接或事实处理 → 合并重复维度成一致性维度。
物理模型设计要点
物理设计关注:类型与精度、分区键、排序/聚簇键、冗余列、压缩编码;以查询模式驱动设计并压测验证。
排序键与聚簇键的选择
排序/聚簇键按高频过滤与 join 列选择(日期、用户、商品),高基数等值列优于低基数枚举;变更需重写数据要有成本预案。
模型演进与重构策略
模型演进遵循兼容优先:新增字段先行、新旧并行、灰度切换、下线旧路径;重构要有迁移计划与对账方案。
模型下线流程
下线前评估引用范围(血缘 + 查询审计)、通知使用方、设置只读冻结期、确认无引用后归档删除;归档保留恢复能力。
建模评审清单
评审项:业务过程与粒度、维度一致性、事实可加性、命名规范、分区与排序、引用完整性方案、文档完整度、下游影响评估。
迟绑定视图 Late-Binding Views
迟绑定视图把物理表映射与查询逻辑解耦:视图在运行时绑定当前有效表(如最新分区/版本),支持无缝切换。
反模式:事实表无边界堆列
把各种场景字段都塞进一张事实表(上百列),导致稀疏、难维护、口径混乱;应按业务过程拆表,密度优先。
反模式:维度承载指标
把累计消费、活跃度这类指标放进维度表,导致维度高频更新与体积膨胀;指标属于事实或指标层,维度只放描述属性。
反模式:用空值表达未知
维度外键均为空、属性用 NULL 表达未知,会让 join 丢行、聚合失真;用未知成员行与语义化默认值显式表达。
退化维度 Degenerate Dimension
订单号、发票号这类无独立属性的业务编号,直接存在事实表上作为退化维度,不单独建维度表。
主题域建模的推进节奏
单域建模先做核心业务过程(交易/库存),再补周边过程;域内先保证事实粒度清晰,再沉淀一致性维度到公共层。
逻辑模型与物理模型映射
逻辑模型描述实体关系与业务规则,物理模型描述表、分区、类型与索引;两者用字段映射表维护,变更同步更新。
分区策略与模型联动
事实表分区以业务时间为主(按天/月),与查询过滤与生命周期对齐;维度表通常不分区(小表)或按更新时间轻分区。
模型版本与变更记录
模型变更记录包含:变更类型(加列/改语义/改粒度)、影响范围、生效时间、回滚方式;与代码库同源管理。
建模治理:流程与门禁
建模治理三件套:设计规范(模板)、评审门禁(上表前)、巡检机制(存量稽核);治理目标是一致性与可维护性。
维度建模实施顺序
落地顺序:访谈梳理过程 → 画总线矩阵 → 选先行业务过程 → 设计维度与事实 → 评审 → 开发与校验 → 沉淀公共维度。
维度与事实设计
缓慢变化维与事实表类型选择
缓慢变化维 SCD 总览
维度属性随时间变化的处理方式按 Kimball 划分为 0/1/2/3/4/6 等类型;选型取决于是否需要历史、变更频率与查询模式,同一维度不同属性可混用不同策略。
SCD 类型 2:新增版本行
每次属性变更插入新行并维护起止日期与当前标志,是保留历史的主流方案;依赖代理键、版本区间与幂等合并逻辑。
拉链维度:起止日期设计
用 start_date / end_date 描述每个版本的生效区间;建议闭开区间 [start, end),当前行 end 取远期极大值而非 NULL。
拉链合并的执行顺序与幂等
典型流程:取源增量→算 hashdiff→与当前版本对比→关闭旧行→插入新行→质量校验,全程在单事务内保证读写一致。
迷你维度(Mini-dimension)
把等级、年龄段等高频变化的离散属性拆成小维表,事实表同时挂基础维键与迷你维键,控制主维表行数增长。
生效日期:业务时间与系统时间的选择
拉链版本生效时间可用业务变更时间(来源提供)或数仓写入时间;业务时间更贴合分析口径,但依赖来源变更时间的可靠性。
累积快照事实表
跟踪有终态流程(下单→支付→发货→签收)的生命周期:各里程碑时间戳同处一行,随流程推进原地更新,用于漏斗与时效分析。
用时间戳行替代状态标签
订单状态不要存一列 state 原地覆盖,而是按里程碑追加带时间戳的事实行;取最新状态用最新时间戳行,历史演进可分析。
跨过程事实表的关联口径
不同业务过程的事实表不能按明细直接 join 求和(多对多放大);应先按一致性维度分别聚合,再按维度对齐合并。
拉链维度关联的性能约束
事实关联拉链维度时必须带业务时间区间条件,禁止只按自然键 join;为 (自然键, start_date, end_date) 建联合索引。
CDC 变更流到 SCD 的落地
用 CDC(binlog 等)捕获维度变更后,仍要按 SCD 规则落维表:CDC 只提供变更时机与前后镜像,保留策略由 SCD 类型决定。
事实表去重与幂等写入
上游重复投递与任务重跑都会产生重复事实行;用业务主键唯一约束或写前去重(row_number 按更新时间取最新)保证幂等。
SCD 类型 4:主表与历史表分离
主表保存最新值供高频查询,历史变更写入独立历史表;适合大部分查询只用最新、少数场景才看历史的情况。
SCD 类型 6:混合方案
类型6 组合类型1、2、3:保留历史版本行,同时维护当前值列与前值列;同一属性可分列满足「历史当时」与「当前回溯」两种口径。
当前标志与最新版本定位
用 is_current 或远期 end_date 标识当前行;查询最新维度先过滤当前标志,避免按自然键 group by 取最大版本的昂贵写法。
hashdiff 变更检测
把需跟踪的属性按固定顺序拼接后取哈希作为 hashdiff 列,比较新旧哈希即可判断是否变更,免去逐列比较。
迟到维度(Late-arriving dimension)
事实先到、维度成员后到:先挂未知成员占位,等维度数据到达后回刷(backfill)历史事实的维度键。
迟到事实(Late-arriving fact)
事实晚于业务时间到达;若按到达时间分区会破坏时间序列对齐,应按业务时间分区,并把迟到量纳入监控与补跑流程。
周期快照事实表
按固定周期(日/月)对状态拍摄快照,如每日账户余额、每日库存;行数等于实体数×周期数,适合时点状态型度量。
无事实事实表
只记录维度键的组合(可带计数或权重常量),描述「发生过的关系」,如促销覆盖记录、用户订阅关系。
聚合事实表
对明细事实按高频维度组合预聚合(日×渠道×品类),换取查询性能;需与明细口径一致并声明可上卷范围。
半可加度量
部分维度可加、部分不可加:余额、库存、人数在账户/商品维上可加,在时间维上不可加,跨时间需取期末、期初或平均口径。
不可加度量
任何维度上求和都无意义的度量(比率、单价、毛利率);应存储分子与分母等可加基础度量,由查询端计算目标指标。
分摊权重与分配事实表
把总账金额按权重分摊到明细(如运费按订单金额比例),分摊系数保留在事实表中便于重算与审计追查。
负向事实与冲正
退款或更正不删除原行,而是插入负向度量行,流水保持可审计,日终汇总时正负自然抵消。
事实表粒度声明
每张事实表必须声明一行代表什么(一订单一行还是一订单商品一行);粒度决定主键、分区方式与可用维度组合。
度量存储类型与单位
存储基础可加度量并统一单位(如金额用分或固定小数位 decimal);比率类指标由上层计算,不在事实表存最终比率。
一致性维度的落地方式
一致性维度作为独立 DIM 层资产构建并共享,而不是每张事实各自 join 临时维表;总线矩阵的交叉点就是共享契约。
维度瘦身:拆分与合并
属性过多且更新频率差异大时,可拆分为核心维与扩展维按需关联;低基数长文本走编码表引用,控制维表宽度。
维度拉平与非规范化
星型模型维度按查询友好拉平:把雪花化码表 join 进维度或建层内视图,用适度冗余换取查询简洁与 join 次数减少。
日期维度表设计
预生成日期维度(含节假日、财季、周口径标记),事实表统一按日期键关联,避免在各处手写日期函数与口径。
维度数据来源标记
多系统共用同一实体时,维度保留来源标记与合并优先级规则;冲突时按规则裁决,并保留原始来源值便于核对。
多源维度合并
同一客户在主数据与业务系统各有编码时,以主数据为基准建交叉引用表(xref),维度行保留各源编码列供下游关联。
拉链历史回刷
首次入仓或逻辑变更后需回刷历史版本:按变更流水重演生成历史行;回刷过程必须幂等并支持断点续跑。
维度字段类型与枚举规范
维度属性类型全库统一:枚举值用固定编码(0/1 而非 yes/no 混用)、字符串去空格统一大小写、布尔统一 tinyint。
SCD 类型 0:保留原值
属性首次入库后永不变化,如身份证号、开户日期;后续变更被忽略,必要时走人工校正流程。
SCD 类型 1:直接覆盖
只保留最新值,变更时原地覆盖旧值;适合纠错型属性(名称写错、编码补全),不承担历史分析需求。
SCD 类型 3:增加前值列
保留当前值与上一值两列(如 current_tier / previous_tier),历史深度只有一跳,表宽固定不随变更增长。
事务事实表
每行对应一个业务事件,粒度细、可加性好,是事实表的默认形态;一般只插入不更新,可上卷到任意维度组合。
可加度量与可加性判断
跨所有维度都能求和的度量(金额、数量)为可加度量;事实表设计优先选择可加度量,便于任意维度上卷。
合并事实表
同一粒度的多源事实(多渠道订单、多系统流水)合并为一张表,用来源维度区分,减少 union 查询与指标口径分叉。
日内时间维度
分析订单时段分布、配送时长等场景时,使用分钟级时间维(含时段标签:早高峰/午间/晚高峰),与日期维可分可合。
维表技术字段规范
维表统一携带审计列:dw_create_time、dw_update_time、etl_batch、src_system;排障时能定位到批次与来源。