Hive ACID:事务表与行级增删改
Hive 事务表(ACID 表)支持行级的 UPDATE、DELETE 与 MERGE,底层用基础文件加增量(delta)文件实现,读取时把两类文件合并,后台 compactor 负责把增量合并回基础文件。建表时必须声明事务属性并使用 ORC 格式,通常还要求分桶,因此事务表更适合维表与需要少量行级修正的场景。
基本信息
| 能力 | 行级 UPDATE / DELETE / MERGE |
|---|---|
| 存储结构 | ORC 基础文件加 delta 文件 |
| 后台合并 | compactor 任务 |
| 建表要求 | TBLPROPERTIES transactional=true |
| 主要代价 | 读取合并开销与合并任务运维 |
典型使用场景
- 维表维护:少量行需要修正时用 UPDATE,而不是重写整个分区
- 批量修正:用 MERGE 按主键把修正后的记录并进目标表
- 合规删除:按用户维度删除明细行,满足删除请求
- 增量同步:用 MERGE 把上游变更落到目标表,避免全量重写
- 运维检查:确认合并任务正常运行,delta 文件数没有持续增长
事务表定义与更新
事务表定义与更新
CREATE TABLE dim_customer_acid (
customer_id STRING,
customer_name STRING,
update_time STRING
)
CLUSTERED BY (customer_id) INTO 8 BUCKETS
STORED AS ORC
TBLPROPERTIES ('transactional' = 'true');
UPDATE dim_customer_acid SET customer_name = 'new_name' WHERE customer_id = 'C001';按主键批量合并
按主键批量合并
MERGE INTO dim_customer_acid AS t
USING stg_customer AS s
ON t.customer_id = s.customer_id
WHEN MATCHED AND s.update_time > t.update_time THEN
UPDATE SET customer_name = s.customer_name
WHEN NOT MATCHED THEN
INSERT VALUES (s.customer_id, s.customer_name, s.update_time);
-- 条件必须写清时间或版本比较,否则同一条记录会被反复覆盖成旧值能力与限制
| 项目 | 说明 | 注意 |
|---|---|---|
| UPDATE / DELETE | 行级修改 | 需事务表,通常要求分桶 |
| MERGE | 按主键合并 | 条件要写清,避免旧值覆盖新值 |
| 读取 | 基础文件与增量合并 | 文件多时读取变慢 |
| 合并任务 | compactor 后台执行 | 需监控是否正常运行 |
delta 文件堆积会明显拖慢读取,事务表必须关注合并任务是否正常执行,必要时调整合并参数与调度频率;只建表不运维,性能会随时间持续下降。
事务表适合小批量高频修改;大批量全量重写用 INSERT OVERWRITE 更划算,两种方式不要盲目互换,否则会付出额外的合并开销。
上线前先在表说明里写清这张表为什么是事务表:多数使用方只关心「能不能改」,但运维关心的是合并任务、delta 增长与读取开销,这些信息缺一不可。