溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Hive分區(qū)表的分區(qū)操作方法

發(fā)布時(shí)間:2021-08-24 12:02:17 來(lái)源:億速云 閱讀:827 作者:chen 欄目:大數(shù)據(jù)

本篇內(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分區(qū)表的分區(qū)操作方法

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è)表中

導(dǎo)出到本地文件系統(tǒng)

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ù)的存放路徑就不一樣了。

導(dǎo)出到Hive的另一個(gè)表中

其實(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)很不方便!

hive> insert overwrite local directory '/home/iteblog/local'

    > row format delimited

    > fields terminated by '\t'

    select from wyp;

 

[wyp@master ~/local]$ vim 000000_0

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

這個(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í)!

向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

AI