首页/数据/数据工程与 ETL 速查/数仓表分区与分桶设计

数仓表分区与分桶设计

分区按日期(dt/ds)切分便于增量覆盖与裁剪,分桶按高基数列散列便于采样与连接优化;分区字段要能用等值或范围条件过滤,否则起不到裁剪作用。

分区与分桶设计是什么

分区(partition)把表数据按目录切分,常见按日期 dt 做一级分区,必要时加二级(region、hour);分桶(bucket)按高基数列做哈希切分,用于提升连接效率与采样精度。分区解决「少读数据」,分桶解决「读得快、连得动」。前提是查询能命中分区条件——用函数包装分区字段的写法会让裁剪完全失效,分区设计等于白做。

基本信息

适用平台Apache Hive、Spark SQL、以及采用 Hive 目录结构的数仓引擎
分区字段多为 STRING 类型(dt='2026-10-11'),也可用 INT
分区层次一级分区(dt)最常见,二级如 dt + region、dt + hour
分桶CLUSTERED BY (user_id) INTO N BUCKETS,桶数常取 2 的幂
安装方式静态指定分区,或动态分区一次写入多个分区
生命周期按天归档与清理,控制分区总数与元数据规模

典型使用场景

  • 增量表按天分区:每天一个分区,重跑时覆盖写单天分区即可
  • 大表按月分区:历史久、查询以月为单位的表,减少分区数量
  • 高基数列分桶:事实表按 user_id 分桶,与大表连接时可走桶连接
  • 二级分区:地域或小时差异明显、查询常带该维度时使用
  • 数据生命周期:按分区归档历史数据并在元数据中下线,控制存储成本

分区分桶建表与写入

分区分桶建表与写入
CREATE TABLE dwd_trade_order_detail_di (
  order_id BIGINT, user_id BIGINT, pay_amount DECIMAL(18,2)
)
PARTITIONED BY (dt STRING)
CLUSTERED BY (user_id) INTO 64 BUCKETS
STORED AS ORC;

-- 指定分区写入:重跑同一天只覆盖该分区
INSERT OVERWRITE TABLE dwd_trade_order_detail_di PARTITION (dt = '2026-10-11')
SELECT order_id, user_id, pay_amount, etl_time FROM ods_trade_order WHERE dt = '2026-10-11';

-- 分区元数据维护与查看
ALTER TABLE dwd_trade_order_detail_di ADD IF NOT EXISTS PARTITION (dt = '2026-10-12');
SHOW PARTITIONS dwd_trade_order_detail_di;

确认分区裁剪是否生效

确认分区裁剪是否生效
-- 好:分区字段直接比较,可裁剪,只扫一天数据
SELECT COUNT(1) FROM dwd_trade_order_detail_di WHERE dt = '2026-10-11';

-- 好:范围条件同样可以裁剪
SELECT COUNT(1) FROM dwd_trade_order_detail_di WHERE dt BETWEEN '2026-10-01' AND '2026-10-11';

-- 差:分区字段被函数包装,无法裁剪,退化为全表扫描
SELECT COUNT(1) FROM dwd_trade_order_detail_di WHERE SUBSTR(dt, 1, 7) = '2026-10';

设计选择对照

选择好处代价
一级 dt 分区结构简单、写入与清理方便数据量大时单分区依旧很大
二级分区按地域或小时裁剪更细分区总数成倍增加,元数据与小文件压力上升
按高基数列分桶连接与采样效率高写入需桶对齐,改桶数要重建表
粒度过细的分区裁剪面小小文件多,读取时打开文件的开销反超收益
分区字段建议用字符串存日期:字符比较可读、便于人工排查,写入时用格式化字符串,避免时区与时间戳转换带来的偏差。
分区数失控(按小时再按渠道再按省份)会让元数据膨胀、小文件遍地,查询规划时间显著变长;分区的第一目标是让常用过滤条件能裁剪,不是切得越细越好。

易错点

  • 分区字段被函数包装(如 SUBSTR(dt,1,7))导致无法裁剪,退化为全表扫描
  • 分区粒度过细造成海量小文件,读取开销反超收益,任务越跑越慢
  • 只写数据目录不注册分区元数据,查询看不到数据却查不出原因
  • 动态分区一次写入过多分区,触发文件数与分区数上限而失败
  • 分桶数改了但表未重建,同一表内桶数不一致,连接与采样结果不可靠

数据来源与参考

  • Apache Hive 官方文档:Partitioned 与 Bucketed Tables
  • 行业数仓表设计实践
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌