向hive中加载或添加数据的三种方式

时间:2022-03-06 08:19:17


每次博客尽量以一个项目的标准来写,做到大家可以动手操作实践。

首先准备数据源:学生成绩txt文件,共七个字段(ID,name,Chinese,English,math,school,class)

[root@xxx tmp]#  hdfs dfs -cat  /tmp/score.txt 
0001,zhangsan,99,98,100,school1,class1
0002,lisi,59,89,79,school2,class1
0003,wangwu,89,99,100,school3,class1
0004,zhangsan2,99,98,100,school1,class1
0005,lisi2,59,89,79,school2,class1
0006,wangwu2,89,99,100,school3,class1

建普通表:
create table score1
(id string comment 'ID', 
name string comment 'name',  
Chinese double comment 'Chinese',
English double comment 'English',
math double comment 'math',
school string comment 'school',
class string comment 'class')
comment 'score1'  
row format delimited fields terminated by ','
stored as textfile;

建分区表语句:
create table score
(id string comment 'ID', 
name string comment 'name',  
Chinese double comment 'Chinese',
English double comment 'English',
math double comment 'math')
comment 'score'  
partitioned by(school string,class string)
row format delimited fields terminated by ','

stored as textfile;


一、load加载

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]  

解释:
local:可选,表示从本地文件系统中加载,而非hdfs
overwrite:可选,先删除原来数据,然后再加载

partition:这里是指将inpath中的所有数据加载到那个分区,并不会判断源数据中每一条记录属于哪个分区。

注意:load完了之后,会自动把INPATH下面的源数据删掉,其实就是将INPATH下面的数据移动到/usr/hive/warehouse目录下了。

分区加载:load data inpath '/tmp/score.txt' into table score partition (school="school1",class="class1") 

select * from score查询出来的六条记录,两个分区字段都变成了school1和class1

  score.id score.name score.chinese score.english score.math score.school score.class
1 0001 zhangsan 99 98 100 school1 class1
2 0002 lisi 59 89 79 school1 class1
3 0003 wangwu 89 99 100 school1 class1
4 0004 zhangsan2 99 98 100 school1 class1
5 0005 lisi2 59 89 79 school1 class1
6 0006 wangwu2 89 99 100 school1 class1


而hive的score表对应的hdfs文件依旧没变,因此load的命令的执行其实就是简单的mv操作。
[root@xxx tmp]#  hdfs dfs -cat /user/hive/warehouse/jira.db/score/school=school1/class=class1/score.txt
0001,zhangsan,99,98,100,school1,class1
0002,lisi,59,89,79,school2,class1
0003,wangwu,89,99,100,school3,class1
0004,zhangsan2,99,98,100,school1,class1
0005,lisi2,59,89,79,school2,class1

0006,wangwu2,89,99,100,school3,class1

如果要实现真正的分区加载则应该采用下面的加载方式。

先load加载到非分区表score1:

load data inpath '/tmp/score.txt' into table score1;

这个时候查询是ok的

  score1.id score1.name score1.chinese score1.english score1.math score1.school score1.class
1 0001 zhangsan 99 98 100 school1 class1
2 0002 lisi 59 89 79 school2 class1
3 0003 wangwu 89 99 100 school3 class1
4 0004 zhangsan2 99 98 100 school1 class1
5 0005 lisi2 59 89 79 school2 class1
6 0006 wangwu2 89 99 100 school3 class1

再insert into 到分区表,见下面操作。

二、insert插入

hive不支持INSERT INTO, UPDATE, DELETE操作,这样的话,就不要很复杂的锁机制来读写数据。
INSERT INTO syntax is only available starting in version 0.8。INSERT INTO就是在表或分区中追加数据,并不是经典数据库中的insert into操作,只是insert into单词一样。

基本模式
INSERT INTO|OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1
多插入模式
FROM frometable1,fromtable2....
INSERT INTO|OVERWRITE TABLE desttable1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1
[INSERT INTO|OVERWRITE TABLE desttable2 [PARTITION ...] select_statement2] ...
动态分区模式

INSERT INTO|OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement


将score1中的某个分区数据insert到score中:
insert overwrite table score partition (school="school1",class="class1") select id,name,Chinese,English,math from score1 where school="school1" and class="class1";
insert overwrite table score partition (school="school2",class="class1") select id,name,Chinese,English,math from score1 where school="school2" and class="class1";

insert overwrite table score partition (school="school3",class="class1") select id,name,Chinese,English,math from score1 where school="school3" and class="class1";

查询表文件数据:
[root@xxx tmp]#  hdfs dfs -cat  /user/hive/warehouse/jira.db/score/school=school1/class=class1/000000_0
0001,zhangsan,99.0,98.0,100.0

0004,zhangsan2,99.0,98.0,100.0

分区数据并没有存在表文件中,仅存在目录上,因此,这下hive的分区本质摸清楚了。那么问题来了,假如分区数很多,每条一个分区岂不累死,hive提出了动态分区的功能,上面的语句是静态分区,需要手动指定。动态分区和静态分区并不在我们这章博客的讨论范围。


三、create ... as操作

这个相对简单
create table score2 as select * from score
建完的score2表没有分区,因此,create ... as 不能复制分区表。

分区表的复制:
1.需要先用create table score3 like score来复制表结构,然后将原表的数据复制到 新表(score3)
1. 创建新表: create table score3 like score;
2. 将HDFS的数据文件复制一份到新表目录,hive cmd模式下: 
dfs -cp -f /user/hive/warehouse/score/* /user/hive/warehouse/score3/
3. 修复分区元数据信息,hive cmd模式下: MSCK REPAIR TABLE score3;