订阅更新

宽表设计

数仓建模手册 第 5 题 约 3 分钟读完

本文目录
  1. 总结
  2. 宽表是什么?
  3. 什么时候该建宽表?
  4. 宽表设计三原则

总结

记忆点内容
宽表本质提前JOIN,用冗余换性能
适合场景查询固定、频繁、性能要求高
不适合场景维度频繁变、需求不稳定
设计原则粒度单一、字段可控、处理好维度变化
推荐位置DWS层建主题宽表,DWD层保持范式化

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

进阶 | 大数据面试 · 数仓建模系列

面试真题
你们数仓有没有用宽表?宽表是怎么设计的?有什么优缺点?

宽表是什么?

一句话:把多张表的字段提前JOIN好,合并成一张大而全的表。比如原来查一个订单的完整信息,需要JOIN 4张表(fact_order → dim_user → dim_product → dim_channel),建宽表之后一张dws_order_wide就全有了。下游查询直接SELECT不用再JOIN。

核心取舍就一句话:用存储和维护成本换查询性能和易用性。

什么时候该建宽表?

不是所有场景都适合宽表。我总结了一个判断框架:

适合建宽表:下游查询频繁且固定,每次都要JOIN同样的表;查询性能要求高(秒级响应的报表);业务方直接查(降低使用门槛);维度相对稳定不会天天改结构。

不适合建宽表:维度变化频繁(比如价格一天改好几次);分析需求经常变(今天加这个字段明天加那个);维度表很大(两张大表做宽表 = 存储爆炸);团队有能力自己写JOIN(技术团队内部使用)。

Wood的实战经验
我的经验:DWS层适合建主题宽表,DWD层尽量保持范式化。宽表主要服务固定报表和业务方自助查询,探索性分析还是用规范的事实表+维度表更灵活。
我们DWS层有一张用户行为宽表,大概60个字段。遇到过一个问题:产品加了新行为事件,需要在宽表里新增3个字段,但历史数据需要回刷30天,跑了4个小时。后来做了优化,把高频变动的字段拆到一张轻量副表里,主宽表只保留稳定字段,新增需求加在副表上,主表不用重跑。

宽表设计三原则

原则一:明确粒度,不要混。一张宽表只有一个粒度。千万不要把订单粒度和用户粒度的字段混在一起。错误做法是一张表里既有订单明细又有用户汇总,正确做法是拆成dws_order_wide和dws_user_wide两张表。

原则二:控制字段数量。宽表不是越宽越好。我见过有人建了200+字段的宽表,大部分字段使用率不到5%。建议核心字段+高频使用字段控制在50-80个以内,低频字段用的时候再JOIN。

原则三:处理好维度变化。宽表里的维度字段用的是建表时的维度值。如果用户后来改了城市,历史宽表里的城市不会自动更新。大多数场景接受不一致(历史数据反映当时的状态),需要刷新时用拉链表的当前值重跑。

面试加分提示
面试官问「宽表的缺点」时,不要只说「存储大」。要体现你踩过坑:
「我们DWS层有一张用户行为宽表,大概60个字段。遇到过一个问题:产品加了新行为事件,需要新增3个字段,历史数据需要回刷30天,跑了4个小时。后来把高频变动的字段拆到副表里,主表只保留稳定字段,新增需求加在副表上,主表不用重跑。」
这种「遇到问题→分析原因→设计方案」的回答,比干巴巴背优缺点强太多了。
刷题进度保存在当前浏览器