您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Hive分區(qū)表的分區(qū)操作方法”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“Hive分區(qū)表的分區(qū)操作方法”吧!
Hive 沒(méi)有行級(jí)別的數(shù)據(jù)的增刪改,往表中裝載數(shù)據(jù)唯一途徑就是 使用大量數(shù)據(jù)進(jìn)行裝載,可以通過(guò)load 可以 insert
動(dòng)態(tài)分區(qū) ,動(dòng)態(tài)靜態(tài)
所以hive提供了一個(gè)動(dòng)態(tài)分區(qū)功能,其可以基于查詢參數(shù)的位置去推斷分區(qū)的名稱,從而建立分區(qū)
注意:使用,insert...select 往表中導(dǎo)入數(shù)據(jù)時(shí),查詢的字段個(gè)數(shù)必須和目標(biāo)的字段個(gè)數(shù)相同,不能多,也不能少,否則會(huì)報(bào)錯(cuò)。但是如果字段的類型不一致的話,則會(huì)使用null值填充,不會(huì)報(bào)錯(cuò)。而使用load data形式往hive表中裝載數(shù)據(jù)時(shí),則不會(huì)檢查。如果字段多了則會(huì)丟棄,少了則會(huì)null值填充。同樣如果字段類型不一致,也是使用null值填充。
多個(gè)分區(qū)字段時(shí),實(shí)現(xiàn)半自動(dòng)分區(qū)(部分字段靜態(tài)分區(qū),注意靜態(tài)分區(qū)字段要在動(dòng)態(tài)前面)
為了對(duì)表進(jìn)行合理的管理以及提高查詢效率,Hive可以將表組織成“分區(qū)”。一個(gè)分區(qū)實(shí)際上就是表下的一個(gè)目錄,一個(gè)表可以在多個(gè)維度上進(jìn)行分區(qū),分區(qū)之間的關(guān)系就是目錄樹的關(guān)系。
1、創(chuàng)建分區(qū)表
通過(guò) PARTITIONED BY 子句指定,分區(qū)的順序決定了誰(shuí)是父目錄,誰(shuí)是子目錄。
創(chuàng)建有一個(gè)分區(qū)的分區(qū)表:
CREATE TABLE IF NOT EXISTS part_test( c1 string ,c2 string ,c3 string ,c4 string )PARTITIONED BY (day_id string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '|' STORED AS TEXTFILE;
創(chuàng)建有兩個(gè)分區(qū)的分區(qū)表:
CREATE TABLE IF NOT EXISTS part_test_1( c1 string ,c2 string ,c3 string ,c4 string ) PARTITIONED BY (month_id string,day_id string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '|' STORED AS TEXTFILE;
2、 外部分區(qū)表
外部表也可以建成分區(qū)表,如hdfs目錄/user/tuoming/part下有
201805和201806兩個(gè)目錄,201805下有一個(gè)20180509子目錄,201806下有20180609和20180610兩個(gè)子目錄。
創(chuàng)建一個(gè)映射到/user/tuoming/part目錄的外部分區(qū)表:
CREATE EXTERNAL TABLE IF NOT EXISTS part_test_2( c1 string ,c2 string ,c3 string ,c4 string )PARTITIONED BY (month_id string,day_id string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE
LOCATION '/user/tuoming/part';為part_test_2增加分區(qū):
alter table part_test_2 add partition(month_id='201805',day_id='20180509') location '/user/tuoming/part/201805/20180509'; alter table part_test_2 add partition(month_id='201806',day_id='20180609') location '/user/tuoming/part/201806/20180609'; alter table part_test_2 add partition(month_id='201806',day_id='20180610') location '/user/tuoming/part/201806/20180610';
使用show partitions語(yǔ)句查看part_test_2有哪些分區(qū):
show partitions part_test_2;3、 內(nèi)部分區(qū)表
創(chuàng)建一個(gè)主分區(qū)為month_id,子分區(qū)為day_id的內(nèi)部分區(qū)表:
CREATE TABLE IF NOT EXISTS part_test_3( c1 string ,c2 string ,c3 string ,c4 string )PARTITIONED BY (month_id string,day_id string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '|' STORED AS TEXTFILE;
為內(nèi)部分區(qū)表加載數(shù)據(jù)
(1)使用load data inpath…overwrite into table partition語(yǔ)句從hdfs目錄加載:
load data inpath '/user/tuoming/test/test' overwrite into table part_test_3 partition(month_id='201805',day_id='20180509');
數(shù)據(jù)內(nèi)容如下:
(2)使用insert overwrite table/ insert into…partition語(yǔ)句從查詢結(jié)果中加載:
覆蓋插入:
insert overwrite table part_test_3 partition(month_id='201805',day_id='20180509') select * from part_test_temp;
追加插入:
insert into part_test_3 partition(month_id='201805',day_id='20180509') select * from part_test_temp;
注意:使用以上兩種方法為內(nèi)部分區(qū)表加載數(shù)據(jù)不需要預(yù)創(chuàng)建分區(qū),加載數(shù)據(jù)時(shí)會(huì)自動(dòng)創(chuàng)建相應(yīng)的分區(qū)。如果想要為內(nèi)部表預(yù)先創(chuàng)建分區(qū),需要使用hadoop fs –mkdir命令在表目錄下先創(chuàng)建相應(yīng)的分區(qū)目錄,然后再使用alter table add partition語(yǔ)句增加分區(qū):
4、 刪除分區(qū)
使用alter table…drop partition語(yǔ)句刪除對(duì)應(yīng)分區(qū):
alter table part_test_3 drop partition(day_id='20180509');
注意:外部分區(qū)表使用alter table…drop partition語(yǔ)句刪除分區(qū),只會(huì)刪除元數(shù)據(jù),相應(yīng)的目錄和文件并不會(huì)刪除。內(nèi)部表使用該語(yǔ)句刪除分區(qū),既會(huì)刪除元數(shù)據(jù),也會(huì)刪除相應(yīng)的目錄和數(shù)據(jù)文件。
5、 動(dòng)態(tài)分區(qū)
上述使用insert overwrite table…partition…從查詢結(jié)果加載數(shù)據(jù)到分區(qū),必須指定特定的分區(qū),而且每個(gè)分區(qū)都需要使用一條插入語(yǔ)句。當(dāng)需要一次插入多個(gè)分區(qū)的數(shù)據(jù)時(shí),可以使用動(dòng)態(tài)分區(qū),根據(jù)查詢得到的數(shù)據(jù)動(dòng)態(tài)分配到分區(qū)里。動(dòng)態(tài)分區(qū)與靜態(tài)分區(qū)的區(qū)別就是不指定分區(qū)目錄,由hive根據(jù)實(shí)際的數(shù)據(jù)選擇插入到哪一個(gè)分區(qū)。
#啟動(dòng)動(dòng)態(tài)分區(qū)功能 set hive.exec.dynamic.partition=true; #允許全部分區(qū)都是動(dòng)態(tài)分區(qū) set hive.exec.dynamic.partition.mode=nostrick;
#month_id為靜態(tài)分區(qū),day_id為動(dòng)態(tài)分區(qū):
insert overwrite table dynamic_test partition(month_id='201710',day_id) select c1,c2,c3,c4,c5,c6,c7,day_id from kafka_offset where substr(day_id,1,6)='201710';
# month_id和 day_id均為動(dòng)態(tài)分區(qū):
insert overwrite table dynamic_test partition(month_id,day_id) select c1,c2,c3,c4,c5,c6,c7,substr(day_id,1,6) as month_id,day_id from kafka_offset;
為了讓分區(qū)列的值相同的數(shù)據(jù)盡量在同一個(gè)mapreduce中,這樣每一個(gè)mapreduce可以盡量少的產(chǎn)生新的文件夾,可以借助distribute by的功能,將分區(qū)列值相同的數(shù)據(jù)放到一起。
insert overwrite table dynamic_test partition(month_id,day_id) select c1,c2,c3,c4,c5,c6,c7,substr(day_id,1,6) as month_id,day_id from kafka_offset distribute by month_id,day_id;
Hive中的幾種不同的數(shù)據(jù)導(dǎo)出方式。可以根據(jù)導(dǎo)出的地方不一樣,將這些方式分為三種:
導(dǎo)出到本地文件系統(tǒng);
導(dǎo)出到HDFS中;
導(dǎo)出到Hive的另一個(gè)表中。
為了避免單純的文字,我將一步一步地用命令進(jìn)行說(shuō)明。
文章目錄
1 導(dǎo)出到本地文件系統(tǒng)
2 導(dǎo)出到HDFS中
3 導(dǎo)出到Hive的另一個(gè)表中
hive> insert overwrite local directory '/home/wyp/wyp' select * from wyp;
這條HQL的執(zhí)行需要啟用Mapreduce完成,運(yùn)行完這條語(yǔ)句之后,將會(huì)在本地文件系統(tǒng)的/home/wyp/wyp目錄下生成文件,這個(gè)文件是Reduce產(chǎn)生的結(jié)果(這里生成的文件名是000000_0),我們可以看看這個(gè)文件的內(nèi)容:
[wyp@master ~/wyp]$ vim 000000_0 5^Awyp1^A23^A131212121212 6^Awyp2^A24^A134535353535 7^Awyp3^A25^A132453535353 8^Awyp4^A26^A154243434355 1^Awyp^A25^A13188888888888 2^Atest^A30^A13888888888888 3^Azs^A34^A899314121
和導(dǎo)入數(shù)據(jù)到Hive不一樣,不能用 insert into
來(lái)將數(shù)據(jù)導(dǎo)出:可以看出,這就是wyp表中的所有數(shù)據(jù)。數(shù)據(jù)中的列與列之間的分隔符是 ^A
(ascii碼是 \00001
)。
導(dǎo)出到HDFS中
和導(dǎo)入數(shù)據(jù)到本地文件系統(tǒng)一樣的簡(jiǎn)單,可以用下面的語(yǔ)句實(shí)現(xiàn):
hive> insert overwrite directory '/home/wyp/hdfs' select * from wyp;
將會(huì)在HDFS的 /home/wyp/hdfs
目錄下保存導(dǎo)出來(lái)的數(shù)據(jù)。注意,和導(dǎo)出文件到本地文件系統(tǒng)的HQL少一個(gè)local,數(shù)據(jù)的存放路徑就不一樣了。
其實(shí)這個(gè)在《Hive幾種數(shù)據(jù)導(dǎo)入方式》文中就用到了,這也是Hive的數(shù)據(jù)導(dǎo)入方式,如下操作:
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)
如果你用的Hive版本是0.11.0,那么你可以在導(dǎo)出數(shù)據(jù)的時(shí)候來(lái)指定列之間的分隔符(可以參見本博客的《Hive0.11查詢結(jié)果保存到文件并指定列之間的分隔符》),操作如下:細(xì)心的讀者可能會(huì)問(wèn),怎么導(dǎo)入數(shù)據(jù)到文件中,數(shù)據(jù)的列之間為什么不是wyp表設(shè)定的列分隔符呢?其實(shí)在Hive 0.11.0版本之間,數(shù)據(jù)的導(dǎo)出是不能指定列之間的分隔符的,只能用默認(rèn)的列分隔符,也就是上面的^A來(lái)分割,這樣導(dǎo)出來(lái)的數(shù)據(jù)很不直觀,看起來(lái)很不方便!
|
這個(gè)很不錯(cuò)吧!
其實(shí),我們還可以用hive的 -e
和 -f
參數(shù)來(lái)導(dǎo)出數(shù)據(jù)。其中-e 表示后面直接接帶雙引號(hào)的sql語(yǔ)句;而-f是接一個(gè)文件,文件的內(nèi)容為一個(gè)sql語(yǔ)句,如下:
[wyp@master ~/local]$ hive -e "select * from wyp" >> local/wyp.txt [wyp@master ~/local]$ cat wyp.txt 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
[wyp@master ~/local]$ cat wyp.sql select * from wyp [wyp@master ~/local]$ hive -f wyp.sql >> local/wyp2.txt
得到的結(jié)果也是用 \t
分割的。也可以用-f參數(shù)實(shí)現(xiàn):
上述語(yǔ)句得到的結(jié)果也是 \t
分割的。
到此,相信大家對(duì)“Hive分區(qū)表的分區(qū)操作方法”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。