导入(移动)数据到hive1.1.0表的方法

hive数据导入代码格式(会移动源文件位置):
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [partition (分区列名1=值1,分区列名2=值2,...)]

对以上公式细分,Hive有好几种常见的数据导入方式,这里介绍四种
(1) 从本地文件系统中导入数据到Hive表;
(2) 从HDFS上导入数据到Hive表; 
(3) 从别的表中查询出相应的数据并导入到Hive表中; 
(4) 在创建表的时候通过从别的表中查询出相应的记录并插入到所创建的表中。


0. 创建hive表

 hive> create table FEFJay
     > (id int, name string, 
     > age int, tel string)
     > ROW FORMAT DELIMITED
     > FIELDS TERMINATED BY '\t' 
     > STORED AS TEXTFILE; 
OK 
Time taken: 2.832 seconds

这个表有四个字段,行的各个列之间分隔符是制表符,结果保存为文件。


1. 从本地文件导入数据到hive表

本地文件系统里面有个/home/FEFJay/FEFJay.txt文件,行的各个列之间分隔符是制表符,内容如下:

[FEFJay@master ~]$ cat FEFJay.txt  
1       FEFJay     25      13188888888888 
2       test    30      13888888888888  
3       zs      34      899314121

执行命令,把文件导入到hive表:

hive> load data local inpath '/home/FEFJay/FEFJay.txt' into table FEFJay;

这样就将FEFJay.txt里面的内容导入到FEFJay表里面去了,可以到FEFJay表的数据目录下查看,如下命令:

hive>dfs -ls /user/hive/warehouse/FEFJay

和我们熟悉的关系型数据库不一样,Hive现在还不支持在insert语句里面直接给出一组记录的文字形式,也就是说,Hive并不支持INSERT INTO …. VALUES形式的语句。


2. 从HDFS上导入数据到Hive表

从本地文件系统中将数据导入到Hive表的过程中,其实是先将数据临时复制到HDFS的一个目录下(典型的情况是复制到上传用户的HDFS home目录下,比如/home/FEFJay/),然后再将数据从那个临时目录下移动(是移动,不是复制)到对应的Hive表的数据目录里面。

HDFS有下面这个文件/home/FEFJay/add.txt,具体的操作如下:

hive> load data inpath '/home/FEFJay/add.txt' into table FEFJay; 

这就把数据从Hadoop导入到hive表中了。

查看hive表数据:

hive> select * from FEFJay;

请注意load data inpath ‘/home/FEFJay/add.txt’ into table FEFJay; 里面是没有local这个单词的,这个是和从本地文件导入到hive表的区别。


3.从hive中别的表中查询出相应的数据并导入到另一个Hive表中

3.1 创建测试表

假设Hive中有test表,其建表语句如下所示:

hive>create table test(
    >id int, name string,
    >tel string
    >partitioned by
    >(age int)
    >ROW FORMAT DELIMITED
    >FIELDS TERMINATED BY '\t'
    >STORED AS TEXTFILE;

大体和FEFJay表的建表语句类似,只不过test表里面用age作为了分区字段。
对于分区,这里在做解释一下:在Hive中,表的每一个分区对应表下的相应目录,所有分区的数据都是存储在对应的目录中。比如FEFJay表有dt和city两个分区,则对应dt=20131218,city=BJ对应表的目录为/user/hive/warehouse/dt=20131218/city=BJ,所有属于这个分区的数据都存放在这个目录中。

3.2插入一个hive表的部分数据到另一个hive表

3.2.1 静态分区插入(目标表有明确分区)

将FEFJay表中的查询结果并插入到test表中:

hive> insert into table test
    > partition (age='25')
    > select id, name, tel from FEFJay;

查看插入结果:

 hive> select * from test;

这里做一下说明: 我们知道我们传统数据块的形式insert into table values(字段1,字段2),这种形式hive是不支持的。

3.2.2 动态分区插入(目标表没有明确分区)

如果目标表(test)中不存在分区字段,可以去掉partition (age=’25′)语句。当然,我们也可以在select语句里面通过使用分区值来动态指明分区:

hive>set hive.exec.dynamic.partition.mode=nonstrict;
hive> insert into table test
    > partition (age)
    > select id, name,
    > tel, age
    > from FEFJay;

这种方法叫做动态分区插入,但是Hive中默认是关闭的,所以在使用前需要先把
hive.exec.dynamic.partition.mode设置为nonstrict。当然,Hive也支持insert overwrite方式来插入数据,从字面我们就可以看出,overwrite是覆盖的意思,是的,执行完这条语句的时候,相应数据目录下的数据将会被覆盖!而insert into则不会,注意两者之间的区别。例子如下:

hive> insert overwrite table test 
    > PARTITION (age)
    > select id, name, tel, age 
    > from FEFJay;

3.3插入一个hive表的部分数据到另外多个hive表

更可喜的是,Hive还支持多表插入,什么意思呢?在Hive中,我们可以把insert语句倒过来,把from放在最前面,它的执行效果和放在后面是一样的,如下:

 hive> show create table test3; 
 CREATE  TABLE test3( id int, name string) 
 
 hive>from FEFJay
     >insert into table test
     >partition(age)
     >select id, name, tel,age
     >insert into table test3
     >select id,name
     >where age > 25;

可以在同一个查询中使用多个insert子句,这样的好处是我们只需要扫描一遍源表就可以生成多个不相交的输出。


4.复制表部分列作为新表

在实际情况中,表的输出结果可能太多,不适于显示在控制台上,这时候,将Hive的查询输出结果直接存在一个新的表中是非常方便的,我们称这种情况为CTAS(create table .. as select 首字母大写)。
创建表的时候通过从别的表中查询出相应的记录并插入到所创建的表中。

如下:

hive>create table test4
    >as
    >select id,name,tel
    >from FEFJay;

数据就插入到test4表中去了,CTAS操作是原子的,因此如果select查询由于某种原因而失败,新表不会创建的!

posted @ 2016-11-08 20:29  FEFJay  阅读(990)  评论(0编辑  收藏  举报