1. 程式人生 > >Hive 之 寫入資料的方式

Hive 之 寫入資料的方式

轉子:http://blog.csdn.net/lifuxiangcaohui/article/details/40588929

Hive的幾種常見的資料匯入方式
這裡介紹四種:
(1)、從本地檔案系統中匯入資料到Hive表;
(2)、從HDFS上匯入資料到Hive表;
(3)、從別的表中查詢出相應的資料並匯入到Hive表中;
(4)、在建立表的時候通過從別的表中查詢出相應的記錄並插入到所建立的表中。


一、從本地檔案系統中匯入資料到Hive表

先在Hive裡面建立好表,如下:
  1. hive> create table wyp
  2.     > (id int, name string,
  3.     > age int, tel string)
  4.     > ROW FORMAT DELIMITED
  5.     > FIELDS TERMINATED BY '\t'
  6.     > STORED AS TEXTFILE;
  7. OK
  8. Time taken: 2.832 seconds
複製程式碼
這個表很簡單,只有四個欄位,具體含義我就不解釋了。本地檔案系統裡面有個/home/wyp/wyp.txt檔案,內容如下:
  1. [[email protected] ~]$ cat wyp.txt
  2. 1       wyp     25      13188888888888
  3. 2       test    30      13888888888888
  4. 3       zs      34      899314121
複製程式碼
wyp.txt檔案中的資料列之間是使用\t分割的,可以通過下面的語句將這個檔案裡面的資料匯入到wyp表裡面,操作如下:
  1. hive> load data local inpath 'wyp.txt' into table wyp;
  2. Copying data from file:/home/wyp/wyp.txt
  3. Copying file: file:/home/wyp/wyp.txt
  4. Loading data to table default.wyp
  5. Table default.wyp stats:
  6. [num_partitions: 0, num_files: 1, num_rows: 0, total_size: 67]
  7. OK
  8. Time taken: 5.967 seconds
複製程式碼
這樣就將wyp.txt裡面的內容匯入到wyp表裡面去了,可以到wyp表的資料目錄下檢視,如下命令:

  1. hive> dfs -ls /user/hive/warehouse/wyp ;
  2. Found 1 items
  3. -rw-r--r--3 wyp supergroup 67 2014-02-19 18:23 /hive/warehouse/wyp/wyp.txt
複製程式碼
需要注意的是:

和我們熟悉的關係型資料庫不一樣,Hive現在還不支援在insert語句裡面直接給出一組記錄的文字形式,也就是說,Hive並不支援INSERT INTO …. VALUES形式的語句。

二、HDFS上匯入資料到Hive表

  從本地檔案系統中將資料匯入到Hive表的過程中,其實是先將資料臨時複製到HDFS的一個目錄下(典型的情況是複製到上傳使用者的HDFS home目錄下,比如/home/wyp/),然後再將資料從那個臨時目錄下移動(注意,這裡說的是移動,不是複製!)到對應的Hive表的資料目錄裡面。既然如此,那麼Hive肯定支援將資料直接從HDFS上的一個目錄移動到相應Hive表的資料目錄下,假設有下面這個檔案/home/wyp/add.txt,具體的操作如下:
  1. [[email protected] /home/q/hadoop-2.2.0]$ bin/hadoop fs -cat /home/wyp/add.txt
  2. 5       wyp1    23      131212121212
  3. 6       wyp2    24      134535353535
  4. 7       wyp3    25      132453535353
  5. 8       wyp4    26      154243434355
複製程式碼
上面是需要插入資料的內容,這個檔案是存放在HDFS上/home/wyp目錄(和一中提到的不同,一中提到的檔案是存放在本地檔案系統上)裡面,我們可以通過下面的命令將這個檔案裡面的內容匯入到Hive表中,具體操作如下:

  1. hive> load data inpath '/home/wyp/add.txt' into table wyp;
  2. Loading data to table default.wyp
  3. Table default.wyp stats:
  4. [num_partitions: 0, num_files: 2, num_rows: 0, total_size: 215]
  5. OK
  6. Time taken: 0.47 seconds
  7. hive> select * from wyp;
  8. OK
  9. 5       wyp1    23      131212121212
  10. 6       wyp2    24      134535353535
  11. 7       wyp3    25      132453535353
  12. 8       wyp4    26      154243434355
  13. 1       wyp     25      13188888888888
  14. 2       test    30      13888888888888
  15. 3       zs      34      899314121
  16. Time taken: 0.096 seconds, Fetched: 7 row(s)
複製程式碼
從上面的執行結果我們可以看到,資料的確匯入到wyp表中了!請注意load data inpath ‘/home/wyp/add.txt’ into table wyp;裡面是沒有local這個單詞的,這個是和一中的區別。

三、從別的表中查詢出相應的資料並匯入到Hive表中

假設Hive中有test表,其建表語句如下所示:

  1. hive> create table test(
  2.     > id int, name string
  3.     > ,tel string)
  4.     > partitioned by
  5.     > (age int)
  6.     > ROW FORMAT DELIMITED
  7.     > FIELDS TERMINATED BY '\t'
  8.     > STORED AS TEXTFILE;
  9. OK
  10. Time taken: 0.261 seconds
複製程式碼
大體和wyp表的建表語句類似,只不過test表裡面用age作為了分割槽欄位。對於分割槽,這裡在做解釋一下:
分割槽:在Hive中,表的每一個分割槽對應表下的相應目錄,所有分割槽的資料都是儲存在對應的目錄中。比如wyp表有dt和city兩個分割槽,則對應dt=20131218,city=BJ對應表的目錄為/user/hive/warehouse/dt=20131218/city=BJ,所有屬於這個分割槽的資料都存放在這個目錄中。

下面語句就是將wyp表中的查詢結果並插入到test表中:
  1. hive> insert into table test
  2.     > partition (age='25')
  3.     > select id, name, tel
  4.     > from wyp;
  5. #####################################################################
  6.            這裡輸出了一堆Mapreduce任務資訊,這裡省略
  7. #####################################################################
  8. Total MapReduce CPU Time Spent: 1 seconds 310 msec
  9. OK
  10. Time taken: 19.125 seconds
  11. hive> select * from test;
  12. OK
  13. 5       wyp1    131212121212    25
  14. 6       wyp2    134535353535    25
  15. 7       wyp3    132453535353    25
  16. 8       wyp4    154243434355    25
  17. 1       wyp     13188888888888  25
  18. 2       test    13888888888888  25
  19. 3       zs      899314121       25
  20. Time taken: 0.126 seconds, Fetched: 7 row(s)
複製程式碼
這裡做一下說明:
我們知道我們傳統資料塊的形式insert into table values(欄位1,欄位2),這種形式hive是不支援的。

通過上面的輸出,我們可以看到從wyp表中查詢出來的東西已經成功插入到test表中去了!如果目標表(test)中不存在分割槽欄位,可以去掉partition (age=’25′)語句。當然,我們也可以在select語句裡面通過使用分割槽值來動態指明分割槽:
  1. hive> set hive.exec.dynamic.partition.mode=nonstrict;
  2. hive> insert into table test
  3.     > partition (age)
  4.     > select id, name,
  5.     > tel, age
  6.     > from wyp;
  7. #####################################################################
  8.            這裡輸出了一堆Mapreduce任務資訊,這裡省略
  9. #####################################################################
  10. Total MapReduce CPU Time Spent: 1 seconds 510 msec
  11. OK
  12. Time taken: 17.712 seconds
  13. hive> select * from test;
  14. OK
  15. 5       wyp1    131212121212    23
  16. 6       wyp2    134535353535    24
  17. 7       wyp3    132453535353    25
  18. 1       wyp     13188888888888  25
  19. 8       wyp4    154243434355    26
  20. 2       test    13888888888888  30
  21. 3       zs      899314121       34
  22. Time taken: 0.399 seconds, Fetched: 7 row(s)
複製程式碼
這種方法叫做動態分割槽插入,但是Hive中預設是關閉的,所以在使用前需要先把hive.exec.dynamic.partition.mode設定為nonstrict。當然,Hive也支援insert overwrite方式來插入資料,從字面我們就可以看出,overwrite是覆蓋的意思,是的,執行完這條語句的時候,相應資料目錄下的資料將會被覆蓋!而insert into則不會,注意兩者之間的區別。例子如下:

  1. hive> insert overwrite table test
  2.     > PARTITION (age)
  3.     > select id, name, tel, age
  4.     > from wyp;
複製程式碼
更可喜的是,Hive還支援多表插入,什麼意思呢?在Hive中,我們可以把insert語句倒過來,把from放在最前面,它的執行效果和放在後面是一樣的,如下:
  1. hive> show create table test3;
  2. OK
  3. CREATE  TABLE test3(
  4.   id int,
  5.   name string)
  6. Time taken: 0.277 seconds, Fetched: 18 row(s)
  7. hive> from wyp
  8.     > insert into table test
  9.     > partition(age)
  10.     > select id, name, tel, age
  11.     > insert into table test3
  12.     > select id, name
  13.     > where age>25;
  14. hive> select * from test3;
  15. OK
  16. 8       wyp4
  17. 2       test
  18. 3       zs
  19. Time taken: 4.308 seconds, Fetched: 3 row(s)
複製程式碼
可以在同一個查詢中使用多個insert子句,這樣的好處是我們只需要掃描一遍源表就可以生成多個不相交的輸出。這個很酷吧!

四、在建立表的時候通過從別的表中查詢出相應的記錄並插入到所建立的表中

在實際情況中,表的輸出結果可能太多,不適於顯示在控制檯上,這時候,將Hive的查詢輸出結果直接存在一個新的表中是非常方便的,我們稱這種情況為CTAS(create table .. as select)如下:

  1. hive> create table test4
  2.     > as
  3.     > select id, name, tel
  4.     > from wyp;
  5. hive> select * from test4;
  6. OK
  7. 5       wyp1    131212121212
  8. 6       wyp2    134535353535
  9. 7       wyp3    132453535353
  10. 8       wyp4    154243434355
  11. 1       wyp     13188888888888
  12. 2       test    13888888888888
  13. 3       zs      899314121
  14. Time taken: 0.089 seconds, Fetched: 7 row(s)
複製程式碼

資料就插入到test4表中去了,CTAS操作是原子的,因此如果select查詢由於某種原因而失敗,新表是不會建立的!