寫在前面的話,學(xué)Hive這么久了,發(fā)現(xiàn)目前國內(nèi)還沒有一本完整的介紹Hive的書籍,而且互聯(lián)網(wǎng)上面的資料很亂,于是我決定寫一些關(guān)于《Hive的那些事》序列文章,分享給大家。我會在接下來的時間整理有關(guān)Hive的資料,如果對Hive的東西感興趣,請關(guān)注本博客。
創(chuàng)新互聯(lián)主營佛山網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,重慶APP開發(fā),佛山h5微信平臺小程序開發(fā)搭建,佛山網(wǎng)站營銷推廣歡迎佛山等地區(qū)企業(yè)咨詢
今天的話題是總結(jié)Hive的幾種常見的數(shù)據(jù)導(dǎo)入方式,我總結(jié)為四種
:
分享之前我還是介紹下我的大數(shù)據(jù)交流群:784557197, 不管是大學(xué)生,還是工作人士, 只要想學(xué),都?xì)g迎進(jìn)入交流
我會對每一種數(shù)據(jù)的導(dǎo)入進(jìn)行實際的操作,因為純粹的文字讓人看起來很枯燥,而且學(xué)起來也很抽象。好了,開始操作!
先在Hive里面創(chuàng)建好表,如下:
hive> create table wyp
> (id int, name string,
> age int, tel string)
> ROW FORMAT DELIMITED
> FIELDS TERMINATED BY '\t'
> STORED AS TEXTFILE;
OK
Time taken: 2.832 seconds
這個表很簡單,只有四個字段,具體含義我就不解釋了。本地文件系統(tǒng)里面有個 /home/wyp/wyp.txt
文件,內(nèi)容如下:
[wyp@master ~]$ cat wyp.txt
1 wyp 25 13188888888888
2 test 30 13888888888888
3 zs 34 899314121
wyp.txt
文件中的數(shù)據(jù)列之間是使用\t
分割的,可以通過下面的語句將這個文件里面的數(shù)據(jù)導(dǎo)入到wyp表里面,操作如下:
hive> load data local inpath 'wyp.txt' into table wyp;
Copying data from file:/home/wyp/wyp.txt
Copying file: file:/home/wyp/wyp.txt
Loading data to table default.wyp
Table default.wyp stats:
[num_partitions: 0, num_files: 1, num_rows: 0, total_size: 67]
OK
Time taken: 5.967 seconds
這樣就將wyp.txt里面的內(nèi)容導(dǎo)入到wyp表里面去了,可以到wyp表的數(shù)據(jù)目錄下查看,如下命令:
hive> dfs -ls /user/hive/warehouse/wyp ;
Found 1 items
-rw-r--r--3 wyp supergroup 67 2014-02-19 18:23 /hive/warehouse/wyp/wyp.txt
數(shù)據(jù)的確導(dǎo)入到wyp表
里面去了。
和我們熟悉的關(guān)系型數(shù)據(jù)庫不一樣,Hive現(xiàn)在還不支持在insert語句里面直接給出一組記錄的文字形式,也就是說,Hive并不支持INSERT INTO .... VALUES形式的語句。.
從本地文件系統(tǒng)中將數(shù)據(jù)導(dǎo)入到Hive表的過程中,其實是先將數(shù)據(jù)臨時復(fù)制到HDFS的一個目錄下(典型的情況是復(fù)制到上傳用戶的HDFS home
目錄下,比如/home/wyp/
),然后再將數(shù)據(jù)從那個臨時目錄下移動(注意,這里說的是移動,不是復(fù)制?。┑綄?yīng)的Hive表的數(shù)據(jù)目錄里面。既然如此,那么Hive肯定支持將數(shù)據(jù)直接從HDFS上的一個目錄移動到相應(yīng)Hive表的數(shù)據(jù)目錄下,假設(shè)有下面這個文件/home/wyp/add.txt
,具體的操作如下:
[wyp@master /home/q/hadoop-2.2.0]$ bin/hadoop fs -cat /home/wyp/add.txt
5 wyp1 23 131212121212
6 wyp2 24 134535353535
7 wyp3 25 132453535353
8 wyp4 26 154243434355
上面是需要插入數(shù)據(jù)的內(nèi)容,這個文件是存放在HDFS上/home/wyp目錄(和一中提到的不同,一中提到的文件是存放在本地文件系統(tǒng)上)里面,我們可以通過下面的命令將這個文件里面的內(nèi)容導(dǎo)入到Hive表中,具體操作如下:
hive> load data inpath '/home/wyp/add.txt' into table wyp;
Loading data to table default.wyp
Table default.wyp stats:
[num_partitions: 0, num_files: 2, num_rows: 0, total_size: 215]
OK
Time taken: 0.47 seconds
hive> select * from wyp;
OK
5 wyp1 23 131212121212
6 wyp2 24 134535353535
7 wyp3 25 132453535353
8 wyp4 26 154243434355
1 wyp 25 13188888888888
2 test 30 13888888888888
3 zs 34 899314121
Time taken: 0.096 seconds, Fetched: 7 row(s)
從上面的執(zhí)行結(jié)果我們可以看到,數(shù)據(jù)的確導(dǎo)入到wyp表中了!請注意load data inpath '/home/wyp/add.txt' into table wyp;里面是沒有l(wèi)ocal這個單詞的,這個是和一中的區(qū)別。
假設(shè)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;
OK
Time taken: 0.261 seconds
大體和wyp表的建表語句類似,只不過test表里面用age作為了分區(qū)字段,下面語句就是將wyp表中的查詢結(jié)果并插入到test表中:
hive> insert into table test
> partition (age='25')
> select id, name, tel
> from wyp;
#####################################################################
這里輸出了一堆Mapreduce任務(wù)信息,這里省略
#####################################################################
Total MapReduce CPU Time Spent: 1 seconds 310 msec
OK
Time taken: 19.125 seconds
hive> select * from test;
OK
5 wyp1 131212121212 25
6 wyp2 134535353535 25
7 wyp3 132453535353 25
8 wyp4 154243434355 25
1 wyp 13188888888888 25
2 test 13888888888888 25
3 zs 899314121 25
Time taken: 0.126 seconds, Fetched: 7 row(s)
通過上面的輸出,我們可以看到從wyp表中查詢出來的東西已經(jīng)成功插入到test表中去了!如果目標(biāo)表(test)中不存在分區(qū)字段,可以去掉partition (age='25')語句。當(dāng)然,我們也可以在select語句里面通過使用分區(qū)值來動態(tài)指明分區(qū):
hive> set hive.exec.dynamic.partition.mode=nonstrict;
hive> insert into table test
> partition (age)
> select id, name,
> tel, age
> from wyp;
#####################################################################
這里輸出了一堆Mapreduce任務(wù)信息,這里省略
#####################################################################
Total MapReduce CPU Time Spent: 1 seconds 510 msec
OK
Time taken: 17.712 seconds
hive> select * from test;
OK
5 wyp1 131212121212 23
6 wyp2 134535353535 24
7 wyp3 132453535353 25
1 wyp 13188888888888 25
8 wyp4 154243434355 26
2 test 13888888888888 30
3 zs 899314121 34
Time taken: 0.399 seconds, Fetched: 7 row(s)
這種方法叫做動態(tài)分區(qū)插入,但是Hive中默認(rèn)是關(guān)閉的,所以在使用前需要先把hive.exec.dynamic.partition.mode
設(shè)置為nonstrict
。當(dāng)然,Hive也支持insert overwrite
方式來插入數(shù)據(jù),從字面我們就可以看出,overwrite
是覆蓋的意思,是的,執(zhí)行完這條語句的時候,相應(yīng)數(shù)據(jù)目錄下的數(shù)據(jù)將會被覆蓋!而insert into
則不會,注意兩者之間的區(qū)別。例子如下:
hive> insert overwrite table test
> PARTITION (age)
> select id, name, tel, age
> from wyp;
更可喜的是,Hive還支持多表插入,什么意思呢?在Hive中,我們可以把insert語句倒過來,把from放在最前面,它的執(zhí)行效果和放在后面是一樣的,如下:
hive> show create table test3;
OK
CREATE TABLE test3(
id int,
name string)
Time taken: 0.277 seconds, Fetched: 18 row(s)
hive> from wyp
> insert into table test
> partition(age)
> select id, name, tel, age
> insert into table test3
> select id, name
> where age>25;
hive> select * from test3;
OK
8 wyp4
2 test
3 zs
Time taken: 4.308 seconds, Fetched: 3 row(s)
可以在同一個查詢中使用多個insert子句,這樣的好處是我們只需要掃描一遍源表就可以生成多個不相交的輸出。這個很酷吧!
在實際情況中,表的輸出結(jié)果可能太多,不適于顯示在控制臺上,這時候,將Hive的查詢輸出結(jié)果直接存在一個新的表中是非常方便的,我們稱這種情況為CTAS(create table .. as select)如下:
hive> create table test4
> as
> select id, name, tel
> from wyp;
hive> select * from test4;
OK
5 wyp1 131212121212
6 wyp2 134535353535
7 wyp3 132453535353
8 wyp4 154243434355
1 wyp 13188888888888
2 test 13888888888888
3 zs 899314121
Time taken: 0.089 seconds, Fetched: 7 row(s)
數(shù)據(jù)就插入到test4表中去了,CTAS操作是原子的,因此如果select查詢由于某種原因而失敗,新表是不會創(chuàng)建的!
好了,很晚了,今天就到這,洗洗睡!