问题描述
通过alter table 增加字段:
alter table dw.table_1 add columns (column_1 int COMMENT '列描述');
然后回溯数据,overwrite写到昨日分区,写完后查询发现昨日分区新增的字段中值为空。
原因
hive 官方文档相关说明:
The CASCADE|RESTRICT clause is available in Hive 1.1.0. ALTER TABLE ADD|REPLACE COLUMNS with CASCADE command changes the columns of a table’s metadata, and cascades the same change to all the partition metadata. RESTRICT is the default, limiting column changes only to table metadata.
翻译一下,在Hive版本中修改表结构语句(ALTER TABLE)中可以使用CASCADE和RESTRICT关键字,默认情况下是RESTRICT,RESTRICT只更新表的元数据(对于已经生成的分区则不作修改,从而出现回溯已有分区数据后新加字段值为空的情况);而使用CASCADE关键字能同时更新表的元数据已有分区元数据。即默认的RESTRICT语法对已有分区没有影响,所以导致上面问题描述中的“写完后查询发现昨日分区(修改表结构前已经存在的分区)新增的字段中值为空”现象.
解决方案
从业务角度出发,以是否需要维持已有分区可用且在不回溯数据的情况下保证列不错乱的角度,解决方案分为两种:
- 需维持已有分区的表结构不变,只须在特定分区和新分区中使用新的表结构:
直接执行:
alter table dw.table_1 add columns (column_1 int COMMENT '列描述') [RESTRICT];
然后删除需要修改的特定分区,
alter table dw.table_1 drop partition (dt='2022-03-02')
最后重新往目标表中写入数据即可
- 不需要维持已有分区表结构,修改语句中使用“CASCADE”关键字,修改表元数据的同时修改已有分区元数据:
alter table dw.table_1 add columns (column_1 int COMMENT '列描述') CASCADE;
此时,如果字段不是加在了表的末尾,则在未回溯历史分区数据的情况下,历史分区下的数据将会出现列乱序,数据无法正常使用