寫在前面的話,學Hive這麼久了,發現目前國內尚未一本完整的介紹Hive的書籍,並且互聯網上面的資料很亂,因而我決定寫一些關於《Hive的那些事》序列文章,分享給你們。我會在接下來的時間整理有關Hive的資料,若是對Hive的東西感興趣,請關注本博客。
今天的話題是總結Hive的幾種常見的數據導入方式,我總結爲四種
:數據庫
分享以前我仍是介紹下個人大數據交流羣:784557197, 不論是大學生,仍是工做人士, 只要想學,都歡迎進入交流oop
我會對每一種數據的導入進行實際的操做,由於純粹的文字讓人看起來很枯燥,並且學起來也很抽象。好了,開始操做!大數據
先在Hive裏面建立好表,以下:code
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
這個表很簡單,只有四個字段,具體含義我就不解釋了。本地文件系統裏面有個 /home/wyp/wyp.txt
文件,內容以下:hadoop
[wyp@master ~]$ cat wyp.txt 1 wyp 25 13188888888888 2 test 30 13888888888888 3 zs 34 899314121
wyp.txt
文件中的數據列之間是使用 \t
分割的,能夠經過下面的語句將這個文件裏面的數據導入到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裏面的內容導入到wyp表裏面去了,能夠到wyp表的數據目錄下查看,以下命令:string
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
數據的確導入到wyp表
裏面去了。it
<font color='green'>和咱們熟悉的關係型數據庫不同,Hive如今還不支持在insert語句裏面直接給出一組記錄的文字形式,也就是說,Hive並不支持INSERT INTO .... VALUES形式的語句。.
從本地文件系統中將數據導入到Hive表的過程當中,實際上是先將數據臨時複製到HDFS的一個目錄下(典型的狀況是複製到上傳用戶的HDFS home
目錄下,好比/home/wyp/
),而後再將數據從那個臨時目錄下移動(注意,這裏說的是移動,不是複製!)到對應的Hive表的數據目錄裏面。既然如此,那麼Hive確定支持將數據直接從HDFS上的一個目錄移動到相應Hive表的數據目錄下,假設有下面這個文件/home/wyp/add.txt
,具體的操做以下:io
[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
上面是須要插入數據的內容,這個文件是存放在HDFS上/home/wyp目錄(和一中提到的不一樣,一中提到的文件是存放在本地文件系統上)裏面,咱們能夠經過下面的命令將這個文件裏面的內容導入到Hive表中,具體操做以下:table
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)
從上面的執行結果咱們能夠看到,數據的確導入到wyp表中了!請注意load data inpath '/home/wyp/add.txt' into table wyp;裏面是沒有local這個單詞的,這個是和一中的區別。
假設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做爲了分區字段,下面語句就是將wyp表中的查詢結果並插入到test表中:
hive> insert into table test > partition (age='25') > select id, name, tel > from wyp; ##################################################################### 這裏輸出了一堆Mapreduce任務信息,這裏省略 ##################################################################### 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表中查詢出來的東西已經成功插入到test表中去了!若是目標表(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 wyp; ##################################################################### 這裏輸出了一堆Mapreduce任務信息,這裏省略 ##################################################################### 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)
這種方法叫作動態分區插入,可是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 wyp;
更可喜的是,Hive還支持多表插入,什麼意思呢?在Hive中,咱們能夠把insert語句倒過來,把from放在最前面,它的執行效果和放在後面是同樣的,以下:
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子句,這樣的好處是咱們只須要掃描一遍源表就能夠生成多個不相交的輸出。這個很酷吧!
在實際狀況中,表的輸出結果可能太多,不適於顯示在控制檯上,這時候,將Hive的查詢輸出結果直接存在一個新的表中是很是方便的,咱們稱這種狀況爲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)
數據就插入到test4表中去了,CTAS操做是原子的,所以若是select查詢因爲某種緣由而失敗,新表是不會建立的!好了,很晚了,今天就到這,洗洗睡!