杂项维度

杂项维度把事实表中若干低基数、彼此无关的标志位(是否新客、是否加急、来源渠道标记)合并成一张维度表,用组合编码压缩事实表宽度,避免为每个标志单独建维度。

杂项维度是什么

杂项维度(junk dimension)把事实表里若干低基数、彼此无关的标志位(是否新客、是否加急、是否首单、来源渠道标记)合并成一张维度表,行是这些标志的笛卡尔组合,事实表只保留一个代理键。好处是事实表变窄、查询可读:不必为每个标志单独建维度,也不用在事实表里堆一排布尔列。前提是组合数可控——两三个二值标志加一个三值标志就是十几种组合,但如果标志继续增加,组合会指数膨胀,这时更合适的是把可归类的标志做成正式维度属性。

基本信息

适用多个低基数、彼此独立的标志位
做法笛卡尔组合生成一行一组合,事实表存组合代理键
收益事实表变窄、查询可读、维度表数量受控
注意组合数要可控,过量则得不偿失
维护要求新增标志要同步扩展组合表并回填历史

典型使用场景

  • 订单事实表里的新客标记、加急标记、预约标记等多个布尔位
  • 事实表里有若干取值只有两三个的渠道与类型标记
  • 把散落在宽表里的标志位收敛成唯一维度,减少宽表列数
  • 统一标志口径:多个团队对同一标志的理解通过维度表取值固定下来
  • 配合 BI 工具:让业务方按“组合”直接筛选,不必写多个条件

组合维度示意

组合维度示意
-- 组合表:一行一种标志组合
CREATE TABLE dim_order_junk (
  junk_sk INT,
  is_new_user  STRING,  -- Y/N
  is_urgent    STRING,  -- Y/N
  order_source STRING   -- app/h5/mini
);

-- 事实表只存 junk_sk,替代三个标志字段
CREATE TABLE fact_order (
  order_id BIGINT, junk_sk INT, pay_amount DECIMAL(18,2)
) PARTITIONED BY (dt STRING);

-- 查询:加急新客的 App 订单
SELECT COUNT(1) FROM fact_order f JOIN dim_order_junk j ON f.junk_sk = j.junk_sk
WHERE j.is_urgent = 'Y' AND j.is_new_user = 'Y' AND j.order_source = 'app';

组合规模估算

标志数取值数示例组合数是否适合杂项维度
3 个二值标志2×2×28适合
4 个二值标志2×2×2×216适合
3 个二值加 1 个五值2×2×2×540可接受,需评估
6 个以上多值标志组合继续相乘数百以上建议拆成正式维度
标志位已经很多且组合爆炸时,优先把可归类的标志做成正式维度属性,而不是硬塞进杂项维度:组合表本身也会成为维护负担。
标志位新增时忘记扩展杂项维度表,事实写入会因为找不到对应组合而失败或落成空值,且往往在大批量写入时才暴露。
组合表要随业务增长维护并回填历史:新增一种渠道后,旧数据的组合键要么补齐,要么明确按未知处理,不能留成查不到的代理键。

易错点

  • 标志位新增时忘记扩展杂项维度表,事实写入失败或落空值,下游连接丢失行
  • 组合表未随业务增长维护,出现查不到的 junk_sk,报表数字少于实际
  • 把高基数、彼此相关的属性也塞进杂项维度,组合数爆炸且语义混乱
  • 用标志位字符串直接连接而非代理键,事实表仍然很宽,失去杂项维度的意义

数据来源与参考

  • Kimball《The Data Warehouse Toolkit》杂项维度(Junk Dimension)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌