本文鏈接:https://blog.csdn.net/JENREY/article/details/80588493
1蜘腌,Hive分區(qū)安拟。
???? 是指按照數(shù)據(jù)表的某列或某些列分為多個區(qū),區(qū)從形式上可以理解為文件夾训裆,比如我們要收集某個大型網(wǎng)站的日志數(shù)據(jù),一個網(wǎng)站每天的日志數(shù)據(jù)存在同一張表上,由于每天會生成大量的日志酪刀,導(dǎo)致數(shù)據(jù)表的內(nèi)容巨大,在查詢時進行全表掃描耗費的資源非常多钮孵。那其實這個情況下骂倘,我們可以按照日期對數(shù)據(jù)表進行分區(qū),不同日期的數(shù)據(jù)存放在不同的分區(qū)巴席,在查詢時只要指定分區(qū)字段的值就可以直接從該分區(qū)查找历涝。
下面從用shell命令操作分區(qū)表和從hdfs文件系統(tǒng)查看分區(qū)表相結(jié)合的方式加深對分區(qū)表的認識。
第一漾唉,創(chuàng)建分區(qū)表并將本地文件中的數(shù)據(jù)加載到分區(qū)表中荧库。
要注意的是:首先,創(chuàng)建分區(qū)表的時候赵刑,要通過關(guān)鍵字 partitioned by (name? string)聲明該表是分區(qū)表分衫,并且是按照字段name進行分區(qū),name值一致的所有記錄存放在一個分區(qū)中般此,分區(qū)屬性name的類型是string類型蚪战。當然,可以依據(jù)多個列進行分區(qū)铐懊,即對某個分區(qū)的數(shù)據(jù)按照某些列繼續(xù)分區(qū)邀桑。
其次,向分區(qū)表導(dǎo)入數(shù)據(jù)的時候科乎,要通過關(guān)鍵字partition(name=“jack”)顯示聲明數(shù)據(jù)要導(dǎo)入到表的哪個分區(qū)壁畸,這里表示要將數(shù)據(jù)導(dǎo)入到分區(qū)為name=jack的分區(qū)。
再次喜喂,這里要重點強調(diào)瓤摧,所謂分區(qū)竿裂,這是將滿足某些條件的記錄打包,做個記號照弥,在查詢時提高效率腻异,相當于按文件夾對文件進行分類,文件夾名可類比分區(qū)字段这揣。這個分區(qū)字段形式上存在于數(shù)據(jù)表中悔常,在查詢時會顯示到客戶端上,但并不真正在存儲在數(shù)據(jù)表文件中给赞,是所謂偽列机打。所以,千萬不要以為是對屬性表中真正存在的列按照屬性值的異同進行分區(qū)片迅。比如上面的分區(qū)依據(jù)的列name并不真正的存在于數(shù)據(jù)表中残邀,是我們?yōu)榱朔奖愎芾硖砑拥囊粋€偽列,這個列的值也是我們?nèi)藶橐?guī)定的柑蛇,不是從數(shù)據(jù)表中讀取之后根據(jù)值的不同將其分區(qū)芥挣。我們并不能按照某個數(shù)據(jù)表中真實存在的列,如userid來分區(qū)耻台。
第二空免,查看分區(qū)表目錄:
通過如下命令查看分區(qū)表在文件系統(tǒng)中的存儲路徑,我們會發(fā)現(xiàn)分區(qū)所依據(jù)的列反應(yīng)在文件路徑上盆耽,上面安裝name=“jack”分區(qū)蹋砚,實際上是創(chuàng)建了一個文件夾名為name=jack,并將該此導(dǎo)入的數(shù)據(jù)放置該在文件夾下面摄杂。
大家會發(fā)現(xiàn)坝咐,在下圖中當我們使用cat命令查看文件內(nèi)容時,會發(fā)現(xiàn)這個偽列也有顯示在客戶端匙姜,這其實只是顯示的一種效果而已畅厢,后面我們會同hdfs文件系統(tǒng)查看文件內(nèi)容,會發(fā)現(xiàn)文件中其實沒有真正存儲這列數(shù)據(jù)氮昧。
第三,查看分區(qū)數(shù)據(jù):
分區(qū)的目的就是提高查詢效率浦楣,查詢分區(qū)數(shù)據(jù)的方式就是指定分區(qū)名袖肥,指定分區(qū)名之后就不再全表掃描,直接從指定分區(qū)(如name=jack的分區(qū))中查詢振劳,從hdfs的角度看就是從相應(yīng)的文件系統(tǒng)中(如name=jack文件夾下)去查找特定的數(shù)據(jù)椎组。如下圖所示:
第四,查看分區(qū)信息:
第五历恐,向分區(qū)中插入數(shù)據(jù):
在這個操作中寸癌,我們就可以驗證分區(qū)所依據(jù)的列其實是一個偽列专筷,如果你要從具有相同結(jié)構(gòu)的分區(qū)表中導(dǎo)入數(shù)據(jù),會失敗蒸苇。比如兩個分區(qū)表磷蛹,都有兩個真實的列和一個分區(qū)列(偽列),我們要將一個分區(qū)表中的數(shù)據(jù)導(dǎo)入到另一個分區(qū)表溪烤,會報錯味咳。錯誤信息顯示要導(dǎo)入的表只有兩列(偽列不記在內(nèi),這說明其實數(shù)據(jù)表文件中只有兩列)檬嘀,而源表卻有三列(將偽列計算在類)槽驶,我覺得這是一個bug。
2鸳兽,分桶掂铐。
分桶是相對分區(qū)進行更細粒度的劃分。分桶將整個數(shù)據(jù)內(nèi)容安裝某列屬性值得hash值進行區(qū)分揍异,如要安裝name屬性分為3個桶全陨,就是對name屬性值的hash值對3取摸,按照取模結(jié)果對數(shù)據(jù)分桶蒿秦。如取模結(jié)果為0的數(shù)據(jù)記錄存放到一個文件烤镐,取模為1的數(shù)據(jù)存放到一個文件,取模為2的數(shù)據(jù)存放到一個文件棍鳖。
第一炮叶,如何分桶:
注意:第一,分桶之前要執(zhí)行命令hive.enforce.bucketiong=true;
第二渡处,要使用關(guān)鍵字clustered by 指定分區(qū)依據(jù)的列名镜悉,還要指定分為多少桶,這里指定分為3桶医瘫。
第三侣肄,與分區(qū)不同的是,分區(qū)依據(jù)的不是真實數(shù)據(jù)表文件中的列醇份,而是我們指定的偽列稼锅,但是分桶是依據(jù)數(shù)據(jù)表中真實的列而不是偽列。所以在指定分區(qū)依據(jù)的列的時候要指定列的類型僚纷,因為在數(shù)據(jù)表文件中不存在這個列矩距,相當于新建一個列。而分桶依據(jù)的是表中已經(jīng)存在的列怖竭,這個列的數(shù)據(jù)類型顯然是已知的锥债,所以不需要指定列的類型。
第二,向桶中插入數(shù)據(jù):
第三哮肚,查看桶信息:
由上圖可知分3個桶就是將數(shù)據(jù)表由一個文件存儲分為3個文件存儲登夫。
第四,查看分桶數(shù)據(jù):
要指定關(guān)鍵字tablesample允趟。
3恼策,分區(qū)又分桶。
可以對數(shù)據(jù)表分區(qū)之后繼續(xù)分桶拼窥。
但是分區(qū)之后繼續(xù)分桶戏蔑,我們在hdfs文件系統(tǒng)上看不出分桶的多個數(shù)據(jù)表文件,只能看見一個文件鲁纠,但是能從文件路徑上看出分區(qū)的信息总棵。
看看分區(qū)又分桶的查詢結(jié)果: