Hive分区、分桶操作及其比较(转自:http://blog.csdn.net/epitomizelu/article/details/41911657)
1,Hive分區(qū)。
???? 是指按照數(shù)據(jù)表的某列或某些列分為多個(gè)區(qū),區(qū)從形式上可以理解為文件夾,比如我們要收集某個(gè)大型網(wǎng)站的日志數(shù)據(jù),一個(gè)網(wǎng)站每天的日志數(shù)據(jù)存在同一張表上,由于每天會(huì)生成大量的日志,導(dǎo)致數(shù)據(jù)表的內(nèi)容巨大,在查詢時(shí)進(jìn)行全表掃描耗費(fèi)的資源非常多。那其實(shí)這個(gè)情況下,我們可以按照日期對(duì)數(shù)據(jù)表進(jìn)行分區(qū),不同日期的數(shù)據(jù)存放在不同的分區(qū),在查詢時(shí)只要指定分區(qū)字段的值就可以直接從該分區(qū)查找。
下面從用shell命令操作分區(qū)表和從hdfs文件系統(tǒng)查看分區(qū)表相結(jié)合的方式加深對(duì)分區(qū)表的認(rèn)識(shí)。
第一,創(chuàng)建分區(qū)表并將本地文件中的數(shù)據(jù)加載到分區(qū)表中。
要注意的是:首先,創(chuàng)建分區(qū)表的時(shí)候,要通過(guò)關(guān)鍵字 partitioned by (name? string)聲明該表是分區(qū)表,并且是按照字段name進(jìn)行分區(qū),name值一致的所有記錄存放在一個(gè)分區(qū)中,分區(qū)屬性name的類型是string類型。當(dāng)然,可以依據(jù)多個(gè)列進(jìn)行分區(qū),即對(duì)某個(gè)分區(qū)的數(shù)據(jù)按照某些列繼續(xù)分區(qū)。
其次,向分區(qū)表導(dǎo)入數(shù)據(jù)的時(shí)候,要通過(guò)關(guān)鍵字partition(name=“jack”)顯示聲明數(shù)據(jù)要導(dǎo)入到表的哪個(gè)分區(qū),這里表示要將數(shù)據(jù)導(dǎo)入到分區(qū)為name=jack的分區(qū)。
再次,這里要重點(diǎn)強(qiáng)調(diào),所謂分區(qū),這是將滿足某些條件的記錄打包,做個(gè)記號(hào),在查詢時(shí)提高效率,相當(dāng)于按文件夾對(duì)文件進(jìn)行分類,文件夾名可類比分區(qū)字段。這個(gè)分區(qū)字段形式上存在于數(shù)據(jù)表中,在查詢時(shí)會(huì)顯示到客戶端上,但并不真正在存儲(chǔ)在數(shù)據(jù)表文件中,是所謂偽列。所以,千萬(wàn)不要以為是對(duì)屬性表中真正存在的列按照屬性值的異同進(jìn)行分區(qū)。比如上面的分區(qū)依據(jù)的列name并不真正的存在于數(shù)據(jù)表中,是我們?yōu)榱朔奖愎芾硖砑拥囊粋€(gè)偽列,這個(gè)列的值也是我們?nèi)藶橐?guī)定的,不是從數(shù)據(jù)表中讀取之后根據(jù)值的不同將其分區(qū)。我們并不能按照某個(gè)數(shù)據(jù)表中真實(shí)存在的列,如userid來(lái)分區(qū)。
第二,查看分區(qū)表目錄:
通過(guò)如下命令查看分區(qū)表在文件系統(tǒng)中的存儲(chǔ)路徑,我們會(huì)發(fā)現(xiàn)分區(qū)所依據(jù)的列反應(yīng)在文件路徑上,上面安裝name=“jack”分區(qū),實(shí)際上是創(chuàng)建了一個(gè)文件夾名為name=jack,并將該此導(dǎo)入的數(shù)據(jù)放置該在文件夾下面。
大家會(huì)發(fā)現(xiàn),在下圖中當(dāng)我們使用cat命令查看文件內(nèi)容時(shí),會(huì)發(fā)現(xiàn)這個(gè)偽列也有顯示在客戶端,這其實(shí)只是顯示的一種效果而已,后面我們會(huì)同hdfs文件系統(tǒng)查看文件內(nèi)容,會(huì)發(fā)現(xiàn)文件中其實(shí)沒(méi)有真正存儲(chǔ)這列數(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ù):
在這個(gè)操作中,我們就可以驗(yàn)證分區(qū)所依據(jù)的列其實(shí)是一個(gè)偽列,如果你要從具有相同結(jié)構(gòu)的分區(qū)表中導(dǎo)入數(shù)據(jù),會(huì)失敗。比如兩個(gè)分區(qū)表,都有兩個(gè)真實(shí)的列和一個(gè)分區(qū)列(偽列),我們要將一個(gè)分區(qū)表中的數(shù)據(jù)導(dǎo)入到另一個(gè)分區(qū)表,會(huì)報(bào)錯(cuò)。錯(cuò)誤信息顯示要導(dǎo)入的表只有兩列(偽列不記在內(nèi),這說(shuō)明其實(shí)數(shù)據(jù)表文件中只有兩列),而源表卻有三列(將偽列計(jì)算在類),我覺(jué)得這是一個(gè)bug。
?
?
2,分桶。
分桶是相對(duì)分區(qū)進(jìn)行更細(xì)粒度的劃分。分桶將整個(gè)數(shù)據(jù)內(nèi)容安裝某列屬性值得hash值進(jìn)行區(qū)分,如要安裝name屬性分為3個(gè)桶,就是對(duì)name屬性值的hash值對(duì)3取摸,按照取模結(jié)果對(duì)數(shù)據(jù)分桶。如取模結(jié)果為0的數(shù)據(jù)記錄存放到一個(gè)文件,取模為1的數(shù)據(jù)存放到一個(gè)文件,取模為2的數(shù)據(jù)存放到一個(gè)文件。
第一,如何分桶:
注意:第一,分桶之前要執(zhí)行命令hive.enforce.bucketiong=true;
第二,要使用關(guān)鍵字clustered by 指定分區(qū)依據(jù)的列名,還要指定分為多少桶,這里指定分為3桶。
第三,與分區(qū)不同的是,分區(qū)依據(jù)的不是真實(shí)數(shù)據(jù)表文件中的列,而是我們指定的偽列,但是分桶是依據(jù)數(shù)據(jù)表中真實(shí)的列而不是偽列。所以在指定分區(qū)依據(jù)的列的時(shí)候要指定列的類型,因?yàn)樵跀?shù)據(jù)表文件中不存在這個(gè)列,相當(dāng)于新建一個(gè)列。而分桶依據(jù)的是表中已經(jīng)存在的列,這個(gè)列的數(shù)據(jù)類型顯然是已知的,所以不需要指定列的類型。
第二,向桶中插入數(shù)據(jù):
第三,查看桶信息:
由上圖可知分3個(gè)桶就是將數(shù)據(jù)表由一個(gè)文件存儲(chǔ)分為3個(gè)文件存儲(chǔ)。
第四,查看分桶數(shù)據(jù):
要指定關(guān)鍵字tablesample。
?
?
3,分區(qū)又分桶。
可以對(duì)數(shù)據(jù)表分區(qū)之后繼續(xù)分桶。
但是分區(qū)之后繼續(xù)分桶,我們?cè)趆dfs文件系統(tǒng)上看不出分桶的多個(gè)數(shù)據(jù)表文件,只能看見一個(gè)文件,但是能從文件路徑上看出分區(qū)的信息。
看看分區(qū)又分桶的查詢結(jié)果:
?
?
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Hive分区、分桶操作及其比较(转自:http://blog.csdn.net/epitomizelu/article/details/41911657)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 管理员权限怎么解除 取消管理员权限的方法
- 下一篇: 制作系统时卷标怎么更改 如何修改制作系统