1、首先准备数据源:

学生成绩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

2、建普通表:

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;

3、建分区表语句:

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;