Hive分区表新增字段并指定位置
1、Hive分区表新增字段Hive分区表新增字段并指定位置主要涉及两步:新增字段和移动字段
1)新增字段
ALTER TABLE table_name ADD COLUMNS (col_name data_type , ...) ;
该下令答应用户将新列添加到现有列的末尾但在分区列之前
ADD COLUMNS下令只修改Hive的元数据,不修改实际数据。用户应该确保表/分区的实际数据结构符合元数据定义
2)更改字段
ALTER TABLE table_name CHANGE col_old_name col_new_name column_type ;
该下令答应用户更改列的名称、数据类型、注释或位置,或它们的任意组合
CHANGE COLUMN下令只修改Hive的元数据,不修改实际数据。用户应该确保表/分区的实际数据结构符合元数据定义
值得注意的是,更改字段通常会报不兼容错误:
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Unable to alter table. The following columns have types incompatible with the existing columns in their respective positions : ...
不兼容的情况可以为类型转换不兼容或修改列位置不兼容
对于类型转换不兼容,主要针对的是列中已存储的数据类型与转换的目标类型是否兼容。比方,将string类型的列转换为int,如果string类型的列数据是数字,则可以转换,否则将报错
更改字段类型必须满足隐式转换。如果只想改变列的类型而不关心数据的精确性,则可以设置如下参数的值为false(默认true):
set hive.metastore.disallow.incompatible.col.type.changes=false;
对于修改列位置不兼容,这通常针对于Spark on Hive模式。更改列位置只有元数据变动(逻辑上),实际底层的数据不会更改(物理上),底层数据类型与元数据类型前后不同等,因此不答应变动。另外,Spark不支持CASCADE关键字
以下是一些使用示例:
CREATE TABLE test_change (a int, b int, c int);
// 将列a的名称更改为a1
ALTER TABLE test_change CHANGE a a1 INT;
// 将列a1的名称更改为a2,数据类型更改为string,并将其放在列b后
ALTER TABLE test_change CHANGE a1 a2 STRING AFTER b;
// 新表的结构:b int, a2 string, c int
// 将列c的名称更改为c1,并放在第一列
ALTER TABLE test_change CHANGE c c1 INT FIRST;
// 新表的结构:c1 int, b int, a2 string
// 给列a1添加注释
ALTER TABLE test_change CHANGE a1 a1 INT COMMENT 'a1 comment';
2、CASCADE关键字
CASCADE中文为"级联",顾名思义就是有联系的。Hive官网对CASCADE关键字的描述如下:
CASCADE/RESTRICT子句在Hive 1.1.0中可用。CHANGE COLUMN CASCADE下令修改表元数据的列,并将雷同的更改级联到全部分区元数据。RESTRICT是默认值,它只限制对表元数据的列更改
CHANGE COLUMN CASCADE子句将覆盖表分区的列元数据,而不管表或分区的保护模式怎样,请谨慎使用
详情参考官网:https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-AlterColumn
什么意思呢?下面以一个示例演示不加CASCADE与添加CASCADE的区别
1)数据准备
create table test_cascade (id bigint, name string) partitioned by (dt string);
insert into table test_cascade partition (dt='2024-11-01') values (1, 'a');
insert into table test_cascade partition (dt='2024-12-01') values (2, 'b');
select * from test_cascade;
'''
id name dt
1 a 2024-11-01
2 b 2024-12-01
'''
2)不加CASCADE
alter table test_cascade add columns (age int);
insert into table test_cascade partition (dt='2024-11-01') values (1,'a',19);
insert into table test_cascade partition (dt='2024-12-01') values (2,'b',18);
insert into table test_cascade partition (dt='2025-01-01') values (3,'c',20);
select * from test_cascade;
'''
id name age dt
1 a NULL 2024-11-01
1 a NULL 2024-11-01
2 b NULL 2024-12-01
2 b NULL 2024-12-01
3 c 20 2025-01-01
'''
3)添加CASCADE
alter table test_cascade add columns (age int) cascade;
insert into table test_cascade partition (dt='2024-11-01') values (1,'a',19);
insert into table test_cascade partition (dt='2024-12-01') values (2,'b',18);
insert into table test_cascade partition (dt='2025-01-01') values (3,'c',18);
select * from test_cascade;
'''
id name age dt
1 a NULL 2024-11-01
1 a 19 2024-11-01
2 b NULL 2024-12-01
2 b 18 2024-12-01
3 c 20 2025-01-01
'''
据此,可得如下结论:
[*]不加CASCADE:插入数据时,已存在数据的分区新增字段值为NULL,无数据的分区新增字段值可以插入成功
[*]添加CASCADE:插入数据时,已存在数据的分区和无数据的分区新增字段值都可以插入成功
即就是,默认RESTRICT只变动新分区的表结构(新分区元数据),而CASCADE不仅变动新分区的表结构(新分区元数据),同时也级联变动旧分区的表结构(旧分区元数据)
3、汗青分区新增列为NULL的题目
实际应用中,通常会存在修改表结构的需求,比方,增加一个字段
如果使用如下语句新增列:
ALTER TABLE table_name ADD COLUMNS (col_name data_type );
则可以成功添加列col_name,但如果数据表table_name中已有旧的分区,则该旧分区中的col_name将为NULL且无法更新,纵然使用INSERT OVERWRITE也无效
出现这个题目的原因就是没有使用CASCADE关键字导致的。CASCADE不仅可以变动新分区的表结构(元数据),同时也会级联变动旧分区的表结构(元数据)
办理方法也很简单,只必要在原语句背面添加CASCADE关键字即可:
ALTER TABLE table_name ADD COLUMNS (col_name data_type ) CASCADE;
针对分区表新增字段不加CASCADE关键字时对于汗青分区新插入的数据,新增的列数据都会显示为NULL,别的已有列的数据则显示正常
值得注意的是,如果还必要更改新增列的位置,也必要使用CASCADE关键字:
ALTER TABLE table_name CHANGE col_name col_name data_type AFTER column_name CASCADE;
另外,如果存储格式为Parquet,那么该新增列的数据都将为NULL,如果为TextFile格式,则不会出现这种情况
参考文章:https://blog.csdn.net/sx157559322/article/details/131950817
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]