99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
2020-06-28 閱讀量: 1848
Hive SQL的分區(qū)表和分桶表
  • 分區(qū)和分桶

Hive將表劃分為分區(qū)(partition)表和分桶(bucket)表。

分區(qū)可以讓數(shù)據(jù)的部分查詢變得更快,也就是說(shuō),在加載數(shù)據(jù)的時(shí)候可以指定加載某一部分?jǐn)?shù)據(jù),并不是全量的數(shù)據(jù)。

分桶表通常是在原始數(shù)據(jù)中加入一些額外的結(jié)構(gòu),這些結(jié)構(gòu)可以用于高效的查詢,例如,基于ID的分桶可以使得用戶的查詢非常的塊。

    • 分區(qū)表 

所謂的分區(qū)表,指的就是將數(shù)據(jù)按照表中的某一個(gè)字段進(jìn)行統(tǒng)一歸類,并存儲(chǔ)在表中的不同的位置,也就是說(shuō),一個(gè)分區(qū)就是一類,這一類的數(shù)據(jù)對(duì)應(yīng)到hdfs存儲(chǔ)上就是對(duì)應(yīng)一個(gè)目錄。當(dāng)我們需要進(jìn)行處理的時(shí)候,可以通過(guò)分區(qū)進(jìn)行過(guò)濾,從而只去部分?jǐn)?shù)據(jù),而沒(méi)必要取全部數(shù)據(jù)進(jìn)行過(guò)濾,從而提升數(shù)據(jù)的處理效率。且分區(qū)表是可以分層級(jí)創(chuàng)建。

分區(qū)表又分為靜態(tài)分區(qū)表動(dòng)態(tài)分區(qū)表兩種:

    • 靜態(tài)分區(qū)表:所謂的靜態(tài)分區(qū)表指的就是,我們?cè)趧?chuàng)建表的時(shí)候,就已經(jīng)給該表中的數(shù)據(jù)定義好了數(shù)據(jù)類型,在進(jìn)行加載數(shù)據(jù)的時(shí)候,我們已經(jīng)知道該數(shù)據(jù)屬于什么類型,并且直接加載到該分區(qū)內(nèi)就可以了。來(lái)看一個(gè)簡(jiǎn)單的分區(qū)表的創(chuàng)建語(yǔ)句(這里創(chuàng)建的是一張內(nèi)部表):

1

hive> create table enter_country_people(id int,name string,cardNum string) partitioned by (enter_date string,country string);

指定分區(qū)表關(guān)鍵字:partitioned by

這里的分區(qū)字段為:enter_date、country,也就是說(shuō),先按照enter_date進(jìn)行分類,在enter_date的基礎(chǔ)上,在按照country再次進(jìn)行分類

注意,這里的分區(qū)字段不能包含在表定義字段中,因?yàn)樵谙虮碇衛(wèi)oad數(shù)據(jù)的時(shí)候,需要手動(dòng)指定該字段的值。

接下來(lái)向表中載入數(shù)據(jù),并且指定分區(qū)為enter_date='2019-01-02',country='china'

1

hive> load data inpath '/hadoop/guozy/data/enter__china_people' into table enter_country_people partition (enter_date='2019-01-02',country='china');

         這樣創(chuàng)建表之后的表目錄結(jié)構(gòu)是這樣的:

image.png

這里還有一個(gè)問(wèn)題就是,涉及到載入數(shù)據(jù)的方式

1、使用的是load命令,也就是我上面的方式,可以看到,在load數(shù)據(jù)之前,表中是沒(méi)有這個(gè)分區(qū)(enter_date='2019-01-02',country='china')的。當(dāng)執(zhí)行了load命令之后,hive會(huì)自動(dòng)創(chuàng)建該分區(qū)。這只是其中的一種方式,還有一種方式就是,我們直接可以通過(guò)移動(dòng)數(shù)據(jù)到該分區(qū)的目錄下

2、直接通過(guò)hdfs的mv命令移動(dòng)數(shù)據(jù)到該分區(qū)指定的目錄下。因?yàn)榍懊嬲f(shuō)過(guò),所謂的分區(qū)只是對(duì)應(yīng)到hdfs存儲(chǔ)中的一個(gè)目錄而已。最終數(shù)據(jù)查詢還是要到這個(gè)目錄中去進(jìn)行查詢數(shù)據(jù)。但是這種方式有個(gè)前提就是,該分區(qū)所在的目錄必須呀提前存在,注意,這里說(shuō)的是對(duì)應(yīng)的該目錄存在。當(dāng)然這個(gè)目錄你可以手動(dòng)mkdir,也可以通過(guò)hive添加分區(qū)的方式進(jìn)行創(chuàng)建,這里又分為兩種情況:

a.通過(guò)hive添加分區(qū)的方式進(jìn)行創(chuàng)建,例如:

1

hive> alter table enter_country_people add if not exists partition (enter_date='2019-01-03',country='US');

通過(guò)這種方式添加分區(qū)之后,會(huì)生成這樣一個(gè)目錄:hdfs://user/hive/warehouse/2019-01-03/US,此時(shí),我們就可以直接使用hdfs的mv或cp命令將數(shù)據(jù)摟到該目錄下。之后使用hive命令進(jìn)行查詢即可

b.第二種方式就是,我們先手動(dòng)創(chuàng)建該目錄:hdfs dfs -mkdir /user/hive/warehouse/2019-01-03/US,然后同樣使用上面這種方式,將數(shù)據(jù)mv或cp到該目錄下,但是,如果只是這樣的話,你去使用hive命令查詢數(shù)據(jù),發(fā)現(xiàn)查不到,為什么,因?yàn)閔ive查詢數(shù)據(jù)是需要先到元數(shù)據(jù)表中找到對(duì)應(yīng)數(shù)據(jù)的分區(qū)索引的,然后根據(jù)找到的分區(qū)索引,再去對(duì)應(yīng)的目錄中查找,但是才是我們根本沒(méi)有對(duì)hive的元數(shù)據(jù)進(jìn)行操作,所以元數(shù)據(jù)中沒(méi)有這個(gè)分區(qū)的信息,所以此時(shí),我們需要在增加一步操作,就是將該分區(qū)的信息添加到元數(shù)據(jù)庫(kù)中,我們使用hive的分區(qū)修復(fù)命令即可:

1

hive> msck repair table enter_country_people;

執(zhí)行上述命令之后,然后在進(jìn)行數(shù)據(jù)查詢,就沒(méi)有什么問(wèn)題了

    • 動(dòng)態(tài)分區(qū)表:所謂的動(dòng)態(tài)分區(qū)表,其實(shí)建表方式跟靜態(tài)分區(qū)表沒(méi)有區(qū)別,最主要的區(qū)別是在載入數(shù)據(jù)的時(shí)候,靜態(tài)分區(qū)表我們載入數(shù)據(jù)之前必須保證該分區(qū)存在,并且我么已經(jīng)明確知道載入的數(shù)據(jù)的類型,知道要將數(shù)據(jù)加載到那個(gè)分區(qū)當(dāng)中去,而動(dòng)態(tài)分區(qū)表,在載入的時(shí)候,我們事先并不知道該條數(shù)據(jù)屬于哪一類,而是需要hive自己去判斷該數(shù)據(jù)屬于哪一類,并將該條數(shù)據(jù)加載到對(duì)應(yīng)的目錄中去。建表語(yǔ)句跟靜態(tài)分區(qū)表的建表語(yǔ)句相同,這里不再贅述,主要來(lái)看看數(shù)據(jù)的加載:

    • 對(duì)于動(dòng)態(tài)分區(qū)表數(shù)據(jù)的加載,我們需要先開啟hive的非嚴(yán)格模式,并且通過(guò)insert的方式進(jìn)行加載數(shù)據(jù)

1

2

hive> set hive.exec.dynamic.partition.mode=nonstrict;

hive> insert into table enter_country_people(user string,age int) partition(enter_date,country) select user,age,enter_date,country from enter_country_people_bak;

注意:1、必須先開啟動(dòng)態(tài)分區(qū)模式為非嚴(yán)格模式

2、這里在指定分區(qū)的時(shí)候,并沒(méi)有指定具體分區(qū)的值,而只是指定的分區(qū)的字段

3、partition中的字段其實(shí)是作為插入目標(biāo)表中的一個(gè)字段,所以在從另外一張表select的時(shí)候必須查詢字段中包含索要分區(qū)的這個(gè)字段。

    • 分桶表

在表或者分區(qū)中使用分桶通常有兩個(gè)原因,一個(gè)是為了高效的查詢,另一個(gè)則是為了高效的抽樣。

桶其實(shí)是在表中加入了特殊的結(jié)構(gòu),hive在查詢的時(shí)候可以利用這些結(jié)構(gòu)來(lái)提高查詢效率。比如,如果兩個(gè)表根據(jù)相同的字段進(jìn)行分桶,則在對(duì)這兩個(gè)表進(jìn)行關(guān)聯(lián)的時(shí)候可以使用map-side關(guān)聯(lián)高效實(shí)現(xiàn)。前提是,關(guān)聯(lián)的字段在分桶字段中出現(xiàn)才可以。先看下hive的分桶建表語(yǔ)句:

1

hive> create table user_bucket(id int comment 'ID',name string comment '姓名',age int comment '年齡') comment '測(cè)試分桶' clustered by (id) sorted by (id) into 4 buckets row format delimited fields terminated by '\t';

上述語(yǔ)句,指定根據(jù)id字段進(jìn)行分桶,并且分為4個(gè)桶,并且每個(gè)桶內(nèi)按照id字段升序排序,如果不加sorted by,則桶內(nèi)不經(jīng)過(guò)排序的,具體的分桶規(guī)則是怎樣的呢?Hive是根據(jù)指定的分桶字段,上述語(yǔ)句中為id,根據(jù)id進(jìn)行hash之后在對(duì)分桶數(shù)量4進(jìn)行取余來(lái)決定該數(shù)據(jù)存放在哪個(gè)桶中,因此每個(gè)桶都是整體數(shù)據(jù)的隨機(jī)抽樣。

在map-side關(guān)聯(lián)操作中,兩個(gè)表如果根據(jù)相同的字段進(jìn)行分桶,在處理左表的bucket是,可以直接從外表對(duì)應(yīng)的bucket中提取數(shù)據(jù)進(jìn)行關(guān)聯(lián)操作。map-side關(guān)聯(lián)的兩個(gè)表不一定需要完全相同的bucket數(shù)量,只要成倍數(shù)即可。同樣,Hive不會(huì)對(duì)數(shù)據(jù)是否滿足表定義中的分桶進(jìn)行校驗(yàn),只有在查詢時(shí)出現(xiàn)異常才會(huì)報(bào)錯(cuò),所以一般,我們將分桶的工作交給Hive自己來(lái)完成(設(shè)置hive.enforce.bucketing=true).

載入數(shù)據(jù):

在載入數(shù)據(jù)的時(shí)候,需要注意一下,如果說(shuō)我們只是單純的使用load語(yǔ)句進(jìn)行將數(shù)據(jù)載入到表中的話,其實(shí)是沒(méi)有任何的分桶效果的,因?yàn)檫@樣hdfs文件只有一個(gè),像這樣:

1

hive> load data inpath '/hadoop/guozy/data/user.txt' into table user_bucket;

此時(shí),我們需要借助一個(gè)中間表,先將數(shù)據(jù)load到中間表中,然后通過(guò)insert的方式來(lái)向分桶表中載入數(shù)據(jù):

1

2

3

hive> create table tmp_table (id int comment 'ID',name string comment '名字',age int comment '年齡') comment '測(cè)試分桶中間表' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ;

hive> load data inpath '/hadoop/guoxb/data/user.txt' into table tmp_table;

hive> insert into user_bucket select * from tmp_table;

這樣就實(shí)現(xiàn)了分桶的效果,注意,分桶和分區(qū)的區(qū)別,分區(qū)體現(xiàn)在hdfs上的文件目錄,而分桶則提現(xiàn)在hdfs是具體的文件,上述的語(yǔ)句中,最終會(huì)在hdfs上生成四個(gè)文件,而不是四個(gè)目錄,如果當(dāng)在次向該分桶表中insert數(shù)據(jù)后,會(huì)又增加4個(gè)文件,而不是在原來(lái)的文件上進(jìn)行追加。

一般情況下,建表分桶表的時(shí)候,我們都需要指定一下排序字段,這樣有一個(gè)好處就是,在每個(gè)桶進(jìn)行連接查詢時(shí),就變成了高效的歸并排序了。


24.7611
3
關(guān)注作者
收藏
評(píng)論(0)

發(fā)表評(píng)論

暫無(wú)數(shù)據(jù)
推薦帖子