Hive是基於Hadoop分佈式文件系統的,它的數據存儲在Hadoop分佈式文件系統中。Hive自己是沒有專門的數據存儲格式,也沒有爲數據創建索引,只須要在建立表的時候告訴Hive數據中的列分隔符和行分隔符,Hive就能夠解析數據。因此往Hive表裏面導入數據只是簡單的將數據移動到表所在的目錄中!
Hive的幾種常見的數據導入方式
這裏介紹四種:
(1)、從本地文件系統中導入數據到Hive表;
(2)、從HDFS上導入數據到Hive表;
(3)、從別的表中查詢出相應的數據並導入到Hive表中;
(4)、在建立表的時候經過從別的表中查詢出相應的記錄並插入到所建立的表中。
Hive提供的默認文件存儲格式有textfile、sequencefile、rcfile等。用戶也能夠經過實現接口來自定義輸入輸的文件格式。html
在實際應用中,textfile因爲無壓縮,磁盤及解析的開銷都很大,通常不多使用。Sequencefile以鍵值對的形式存儲的二進制的格式,其支持針對記錄級別和塊級別的壓縮。rcfile是一種行列結合的存儲方式(text file和sequencefile都是行表[row table]),其保證同一條記錄在同一個hdfs塊中,塊以列式存儲。通常而言,對於OLTP而言,行表優點大於列表,對於OLAP而言,列表的優點大於行表,特別容易想到當作聚合操做時,列表的複雜度將會比行表小的多,雖然單獨rcfile的列運算不必定老是存在的,可是rcfile的高壓縮率確實減小文件大小,所以實際應用中,rcfile老是成爲不二的選擇,達觀數據平臺在選擇文件存儲格式時也大量選擇了rcfile方案。數據庫
1、從本地文件系統中導入數據到Hive表分佈式
先在Hive裏面建立好表,以下:
- 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文件,內容以下:
- [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表的數據目錄下查看,以下命令:
- 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
複製代碼
須要注意的是:
和咱們熟悉的關係型數據庫不同,Hive如今還不支持在insert語句裏面直接給出一組記錄的文字形式,也就是說,Hive並不支持INSERT INTO …. VALUES形式的語句。
2、HDFS上導入數據到Hive表oop
從本地文件系統中將數據導入到Hive表的過程當中,實際上是先將數據臨時複製到HDFS的一個目錄下(典型的狀況是複製到上傳用戶的HDFS home目錄下,好比/home/wyp/),而後再將數據從那個臨時目錄下移動(注意,這裏說的是移動,不是複製!)到對應的Hive表的數據目錄裏面。既然如此,那麼Hive確定支持將數據直接從HDFS上的一個目錄移動到相應Hive表的數據目錄下,假設有下面這個文件/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
複製代碼
上面是須要插入數據的內容,這個文件是存放在HDFS上/home/wyp目錄(和一中提到的不一樣,一中提到的文件是存放在本地文件系統上)裏面,咱們能夠經過下面的命令將這個文件裏面的內容導入到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)
複製代碼
從上面的執行結果咱們能夠看到,數據的確導入到wyp表中了!請注意load data inpath ‘/home/wyp/add.txt’ into table wyp;裏面是沒有local這個單詞的,這個是和一中的區別。
3、從別的表中查詢出相應的數據並導入到Hive表中post
假設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做爲了分區字段。對於分區,這裏在作解釋一下:
分區:在Hive中,表的每個分區對應表下的相應目錄,全部分區的數據都是存儲在對應的目錄中。好比wyp表有dt和city兩個分區,則對應dt=20131218,city=BJ對應表的目錄爲/user/hive/warehouse/dt=20131218/city=BJ,全部屬於這個分區的數據都存放在這個目錄中。
下面語句就是將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)
複製代碼
這裏作一下說明:
咱們知道咱們傳統數據塊的形式insert into table values(字段1,字段2),這種形式hive是不支持的。
經過上面的輸出,咱們能夠看到從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子句,這樣的好處是咱們只須要掃描一遍源表就能夠生成多個不相交的輸出。這個很酷吧!
4、在建立表的時候經過從別的表中查詢出相應的記錄並插入到所建立的表中ui
在實際狀況中,表的輸出結果可能太多,不適於顯示在控制檯上,這時候,將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查詢因爲某種緣由而失敗,新表是不會建立的!url