hive的insert语句列顺序问题以及新增字段遇到的坑

讲问题之前,先简单创建一个表:

CREATE TABLE IF NOT EXISTS `my.test_table`(
  `col1` int COMMENT "第一列",
  `col2` int COMMENT "第二列"
)
COMMENT "测试表"
PARTITIONED BY (`pt` int COMMENT "测试分区")
ROW FORMAT SERDE
  "org.apache.hadoop.hive.ql.io.orc.OrcSerde"
STORED AS INPUTFORMAT
  "org.apache.hadoop.hive.ql.io.orc.OrcInputFormat"
OUTPUTFORMAT
  "org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat";

初始表有col1,col2两列,pt分区只是为了对比结果

insert语句列顺序

hive不像mysql、oracle这些数据库一样在insert的时候可以指定字段,必须在插入的时候插入的是全字段。所以我一直以为可以通过指定插入数据的别名来改变插入字段的顺序,好吧,事实证明我是错的!

我们来简单作一个设想,假如我们执行以下的sql会发生什么:

insert overwrite table my.test_table partition(pt=1) select 2 as col2, 1 as col1 from my.online_table;

按常规逻辑来说,查询的时候应该是col1字段都为1,col2字段都为2。但是事实上执行

select col1, col2 from my.test_table;

结果是:

2    1
2    1
2    1
2    1
....

事实上,hive并不关心你执行insert语句所用的别名,别名代表的字段可以不存在,甚至比别名都可以相同。下面的语句执行也是一样的效果:

insert overwrite table my.test_table partition(pt=1) select 2 as invalid_col, 1 as invalid_col from my.online_table;

是不是觉得很惊喜。所以,请严格保证insert语句中的字段和建表语句中的字段的顺序一致!!!

对新增字段插入数据再查询发现是NULL

hive比较特殊的地方,在于它的表结构和数据其实是分开的。这个会导致,对hive分区表新增字段后,在执行插入分区的动作,会发现其实数据文件中已经有新字段值了,但是在查询的时候新字段的值还是显示为null。

例如我执行了下面的方法新增了一列col3:

alter table my.test_table add columns(col3 int comment '第三列')

然后想插入一些数据:

insert overwrite table my.test_table partition(pt=1) select 1 as col1, 2 as col2, 3 as col3 from my.online_table; 

结果查询col1,col2,col3发现结果其实是:

1    2    NULL
1    2    NULL
...1

这是因为你对表结构进行了改变,但是历史分区的数据却没有做改变(新增分区不会出现这个情况)。

为了解决上面的问题,可以采用两种方式:

  • 如果已经执行添加操作,并且没有带cascade,可以尝试下面的方法:
使用replace 恢复表结构,这样历史的分区数据都不会消失
alter table industry_db.product replace
columns(product_name string comment ‘产品名’);
  • 在新增的时候加上cascade关键词
alter table my.test_table add columns(col3 int comment '第三列') cascade

官方文档描述如下:


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.

如上所述,在1.1.0中表和分区的元数据就是分开处理的,在增加字段的时候添加CASCADE能同时更新表和分区 对于,在添加字段的时候没有指定的cascade的情况

因为我们在重跑数据的时候,虽然HDFS上的数据更新了,但是我们查询的时候仍然查询的是旧的元数据信息(即Mysql中的信息)

注意:对于执行了add column语句之后新生成的分区,是不会有问题的,Hive会自动维护新分区中的元数据。

转载请注明出处: hive的insert语句列顺序问题以及新增字段遇到的坑 - Boblim - 博客园

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hive中,insert语句用于将数据插入到表中。与其他数据库不同的是,Hive在插入数据时不能指定字段,必须插入全字段。因此,无法通过指定插入数据的别名来改变插入字段顺序。\[1\] 此外,Hive对于insert语句中使用的别名并不关心,别名代表的字段可以不存在,甚至可以相同。这意味着执行insert语句时,别名并不影响插入的结果。\[2\] 以下是一些示例insert语句的用法: - insert overwrite table my.test_table partition(pt=1) select 2 as invalid_col, 1 as invalid_col from my.online_table; 这个语句将从my.online_table中选择2和1作为无效,并覆盖插入到my.test_table的pt=1分区中。\[2\] - from test_table insert overwrite table test_insert1 select key; 这个语句将从test_table中选择key,并覆盖插入到test_insert1表中。\[3\] - insert overwrite table test_insert2 select value; 这个语句将从默认表中选择value,并覆盖插入到test_insert2表中。\[3\] 总之,Hiveinsert语句在插入数据时不能指定字段,必须插入全字段。别名在插入过程中并不影响结果。 #### 引用[.reference_title] - *1* *2* [hiveinsert语句顺序问题以及新增字段遇到](https://blog.csdn.net/hzp666/article/details/123046169)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Hiveinsert操作,导出数据到本地、hdfs](https://blog.csdn.net/liyonghui123/article/details/84676708)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值