大數(shù)據(jù)工程師必會(huì)的知識(shí)點(diǎn)之一:關(guān)于hive的分區(qū)和分桶

1、Hive分區(qū)表

在Hive Select查詢中一般會(huì)掃描整個(gè)表內(nèi)容,會(huì)消耗很多時(shí)間做沒必要的工作。有時(shí)候只需要掃描表中關(guān)心的一部分?jǐn)?shù)據(jù),因此建表時(shí)引入了partition概念。分區(qū)表指的是在創(chuàng)建表時(shí)指定的partition的分區(qū)空間。 Hive可以對(duì)數(shù)據(jù)按照某列或者某些列進(jìn)行分區(qū)管理,所謂分區(qū)我們可以拿下面的例子進(jìn)行解釋。

當(dāng)前互聯(lián)網(wǎng)應(yīng)用每天都要存儲(chǔ)大量的日志文件,幾G、幾十G甚至更大都是有可能。存儲(chǔ)日志,其中必然有個(gè)屬性是日志產(chǎn)生的日期。在產(chǎn)生分區(qū)時(shí),就可以按照日志產(chǎn)生的日期列進(jìn)行劃分。把每一天的日志當(dāng)作一個(gè)分區(qū)。

將數(shù)據(jù)組織成分區(qū),主要可以提高數(shù)據(jù)的查詢速度。至于用戶存儲(chǔ)的每一條記錄到底放到哪個(gè)分區(qū),由用戶決定。即用戶在加載數(shù)據(jù)的時(shí)候必須顯示的指定該部分?jǐn)?shù)據(jù)放到哪個(gè)分區(qū)。

1.1實(shí)現(xiàn)細(xì)節(jié)

1、一個(gè)表可以擁有一個(gè)或者多個(gè)分區(qū),每個(gè)分區(qū)以文件夾的形式單獨(dú)存在表文件夾的目錄下。

2、表和列名不區(qū)分大小寫。

3、分區(qū)是以字段的形式在表結(jié)構(gòu)中存在,通過describetable命令可以查看到字段存在, 但是該字段不存放實(shí)際的數(shù)據(jù)內(nèi)容,僅僅是分區(qū)的表示(偽列) 。

1.2語法

1.創(chuàng)建一個(gè)分區(qū)表,以 ds 為分區(qū)列:

create table invites(id int, name string) partitioned by (ds string) row format delimited fieldsterminated by '' stored as textfile;

2. 將數(shù)據(jù)添加到時(shí)間為 2013-08-16這個(gè)分區(qū)中:

load data local inpath'/home/hadoop/Desktop/data.txt' overwrite into table invites partition(ds='2013-08-16');

3. 將數(shù)據(jù)添加到時(shí)間為 2013-08-20這個(gè)分區(qū)中:

load data local inpath'/home/hadoop/Desktop/data.txt' overwrite into table invites partition(ds='2013-08-20');

4. 從一個(gè)分區(qū)中查詢數(shù)據(jù):

select * from inviteswhere ds ='2013-08-12';

5. 往一個(gè)分區(qū)表的某一個(gè)分區(qū)中添加數(shù)據(jù):

insert overwrite tableinvites partition (ds='2013-08-12') select id,max(name) from test group by id;

可以查看分區(qū)的具體情況,使用命令:

hadoop fs -ls /home/hadoop.hive/warehouse/invites

或者:

show partitionstablename;

2、Hive桶

對(duì)于每一個(gè)表(table)或者分區(qū), Hive可以進(jìn)一步組織成桶,也就是說桶是更為細(xì)粒度的數(shù)據(jù)范圍劃分。Hive也是 針對(duì)某一列進(jìn)行桶的組織。Hive采用對(duì)列值哈希,然后除以桶的個(gè)數(shù)求余的方式?jīng)Q定該條記錄存放在哪個(gè)桶當(dāng)中。

把表(或者分區(qū))組織成桶(Bucket)有兩個(gè)理由:

(1)獲得更高的查詢處理效率。桶為表加上了額外的結(jié)構(gòu),Hive 在處理有些查詢時(shí)能利用這個(gè)結(jié)構(gòu)。具體而言,連接兩個(gè)在(包含連接列的)相同列上劃分了桶的表,可以使用 Map 端連接 (Map-side join)高效的實(shí)現(xiàn)。比如JOIN操作。對(duì)于JOIN操作兩個(gè)表有一個(gè)相同的列,如果對(duì)這兩個(gè)表都進(jìn)行了桶操作。那么將保存相同列值的桶進(jìn)行JOIN操作就可以,可以大大較少JOIN的數(shù)據(jù)量。

(2)使取樣(sampling)更高效。在處理大規(guī)模數(shù)據(jù)集時(shí),在開發(fā)和修改查詢的階段,如果能在數(shù)據(jù)集的一小部分?jǐn)?shù)據(jù)上試運(yùn)行查詢,會(huì)帶來很多方便。

1.創(chuàng)建帶桶的 table :

create tablebucketed_user(id int,name string)clustered by (id) sorted by(name) into 4buckets row format delimited fields terminated by '' stored as textfile;

首先,我們來看如何告訴Hive

—個(gè)表應(yīng)該被劃分成桶。我們使用CLUSTERED BY 子句來指定劃分桶所用的列和要?jiǎng)澐值耐暗膫€(gè)數(shù):

CREATE TABLE bucketed_user(id INT) name STRING)

CLUSTERED BY (id) INTO 4BUCKETS; 在這里,我們使用用戶ID

來確定如何劃分桶(Hive使用對(duì)值進(jìn)行哈希并將結(jié)果除 以桶的個(gè)數(shù)取余數(shù)。這樣,任何一桶里都會(huì)有一個(gè)隨機(jī)的用戶集合(PS:其實(shí)也能說是隨機(jī),不是嗎?)。

?對(duì)于map

端連接的情況,兩個(gè)表以相同方式劃分桶。處理左邊表內(nèi)某個(gè)桶的 mapper知道右邊表內(nèi)相匹配的行在對(duì)應(yīng)的桶內(nèi)。因此,mapper只需要獲取那個(gè)桶 (這只是右邊表內(nèi)存儲(chǔ)數(shù)據(jù)的一小部分)即可進(jìn)行連接。這一優(yōu)化方法并不一定要求兩個(gè)表必須桶的個(gè)數(shù)相同,兩個(gè)表的桶個(gè)數(shù)是倍數(shù)關(guān)系也可以。

用HiveQL

對(duì)兩個(gè)劃分了桶的表進(jìn)行連接,可參見“map連接”部分(P400)。

桶中的數(shù)據(jù)可以根據(jù)一個(gè)或多個(gè)列另外進(jìn)行排序。由于這樣對(duì)每個(gè)桶的連接變成了高效的歸并排序(merge-sort),因此可以進(jìn)一步提升map

端連接的效率。以下語法聲明一個(gè)表使其使用排序桶:

CREATE TABLE bucketed_users(id INT, name STRING)

CLUSTERED BY (id) SORTED BY(id ASC) INTO 4 BUCKETS; 我們?nèi)绾伪WC表中的數(shù)據(jù)都劃分成桶了呢?把在Hive

外生成的數(shù)據(jù)加載到劃分成 桶的表中,當(dāng)然是可以的。其實(shí)讓Hive來劃分桶更容易。這一操作通常針對(duì)已有的表。

Hive并不檢查數(shù)據(jù)文件中的桶是否和表定義中的桶一致(

無論是對(duì)于桶的數(shù)量或用于劃分桶的列)。如果兩者不匹配,在査詢時(shí)可能會(huì)碰到錯(cuò) 誤或未定義的結(jié)果。因此,建議讓Hive來進(jìn)行劃分桶的操作。

2. 往表中插入數(shù)據(jù):

INSERT OVERWRITE TABLEbucketed_users SELECT * FROM users; 物理上,每個(gè)桶就是表(

或分區(qū))目錄里的一個(gè)文件。它的文件名并不重要,但是桶 n 是按照字典序排列的第 n 個(gè)文件。

事實(shí)上,桶對(duì)應(yīng)于 MapReduce

的輸出文件分區(qū):一個(gè)作業(yè)產(chǎn)生的桶(輸出文件)和reduce任務(wù)個(gè)數(shù)相同.

3. 對(duì)桶中的數(shù)據(jù)進(jìn)行采樣:

hive> SELECT * FROMbucketed_users

> TABLESAMPLE(BUCKET 1 OUT OF 4 ON id);

0 Nat

4 Ann 桶的個(gè)數(shù)從1

開始計(jì)數(shù)。因此,前面的查詢從4個(gè)桶的第一個(gè)中獲取所有的用戶。 對(duì)于一個(gè)大規(guī)模的、均勻分布的數(shù)據(jù)集,這會(huì)返回表中約四分之一的數(shù)據(jù)行。我們 也可以用其他比例對(duì)若干個(gè)桶進(jìn)行取樣(因?yàn)槿硬⒉皇且粋€(gè)精確的操作,因此這個(gè) 比例不一定要是桶數(shù)的整數(shù)倍)。

注:tablesample是抽樣語句,語法:TABLESAMPLE(BUCKET x OUTOF y)

y必須是table總bucket數(shù)的倍數(shù)或者因子。hive根據(jù)y的大小,決定抽樣的比例。例如,table總共分了64份,當(dāng)y=32時(shí),抽取(64/32=)2個(gè)bucket的數(shù)據(jù),當(dāng)y=128時(shí),抽取(64/128=)1/2個(gè)bucket的數(shù)據(jù)。x表示從哪個(gè)bucket開始抽取。例如,table總bucket數(shù)為32,tablesample(bucket 3 out of 16),表示總共抽取(32/16=)2個(gè)bucket的數(shù)據(jù),分別為第3個(gè)bucket和第(3+16=)19個(gè)bucket的數(shù)據(jù)。

總結(jié)

分區(qū)按照我們指定列范圍進(jìn)行分區(qū)(層級(jí)文件夾),而分桶是按照列值的hash值,這樣想同值都會(huì)在一個(gè)桶內(nèi)(一級(jí)文件夾內(nèi)不同文件區(qū)別不同的桶),便于join操作。

最后,小編整理了更多hive,大數(shù)據(jù)相關(guān)的學(xué)習(xí)資料可以分享給大家

轉(zhuǎn)發(fā) 關(guān)注后,++我vx:bmaaa01? 獲取

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Hive 已是目前業(yè)界最為通用、廉價(jià)的構(gòu)建大數(shù)據(jù)時(shí)代數(shù)據(jù)倉庫的解決方案了,雖然也有 Impala 等后起之秀,但目...
    達(dá)微閱讀 1,067評(píng)論 0 4
  • 概述 目前,在利用hive建設(shè)數(shù)據(jù)倉庫的過程中,總會(huì)遇見分區(qū)分桶的,跟傳統(tǒng)的DBMS系統(tǒng)一樣,通過表分區(qū)能夠在特定...
    原上野閱讀 3,301評(píng)論 0 0
  • 快樂大數(shù)據(jù)第5次課 hive(1)工作原理Hive的執(zhí)行入口是Driver,執(zhí)行的SQL語句首先提交到Drive驅(qū)...
    快樂大數(shù)據(jù)閱讀 586評(píng)論 0 0
  • Hive是基于Hadoop的一個(gè)數(shù)據(jù)倉庫工具,可以將結(jié)構(gòu)化的數(shù)據(jù)文件映射為一張數(shù)據(jù)庫表,并提供類SQL查詢功能。本...
    felix521閱讀 1,422評(píng)論 0 0
  • 分區(qū) 分區(qū)是以字段的形式在表結(jié)構(gòu)中存在,通過describe table命令可以查看到字段存在,但是該字段不存放實(shí)...
    felix_feng閱讀 2,061評(píng)論 0 5

友情鏈接更多精彩內(nèi)容