hive的分割槽以及分桶

2021-08-20 19:03:05 字數 3668 閱讀 7661

2023年10月26日 09:50:38

閱讀數:3999 1

、hive 分割槽表

在hive select查詢中一般會掃瞄整個表內容,會消耗很多時間做沒必要的工作。有時候只需要掃瞄表中關心的一部分資料,因此建表時引入了partition概念。分割槽表指的是在建立表時指定的partition的分割槽空間。

hive

可以對資料按照某列或者某些列進行分割槽管理,所謂分割槽我們可以拿下面的例子進行解釋。

當前網際網路應用每天都要儲存大量的日誌檔案,幾g、幾十g甚至更大都是有可能。儲存日誌,其中必然有個屬性是日誌產生的日期。在產生分割槽時,就可以按照日誌產生的日期列進行劃分。把每一天的日誌當作乙個分割槽。

將資料組織成分區,主要可以提高資料的查詢速度。至於使用者儲存的每一條記錄到底放到哪個分割槽,由使用者決定。即使用者在載入資料的時候必須顯示的指定該部分資料放到哪個分割槽。

1.1 

實現細節

1、乙個表可以擁有乙個或者多個分割槽,每個分割槽以資料夾的形式單獨存在表資料夾的目錄下。

2、表和列名不區分大小寫。

3、分割槽是以字段的形式在表結構中存在,通過describetable命令可以檢視到字段存在,

但是該字段不存放實際的資料內容,僅僅是分割槽的表示(偽列)

。1.2 

語法 1. 

建立乙個分割槽表,以 ds 為分割槽列:

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

2. 將資料新增到時間為 2013-08-16 這個分割槽中:

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

3. 將資料新增到時間為 2013-08-20 這個分割槽中:

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

4. 從乙個分割槽中查詢資料:

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

5.  

往乙個分割槽表的某乙個分割槽中新增資料:

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

可以檢視分割槽的具體情況,使用命令:

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

或者:show partitionstablename;

2、hive 桶

對於每乙個表(table)或者分割槽,

hive

可以進一步組織成桶,也就是說桶是更為細粒度的資料範圍劃分。hive也是

針對某一列進行桶的組織。hive採用對列值雜湊,然後除以桶的個數求餘的方式決定該條記錄存放在哪個桶當中。

把錶(或者分割槽)組織成桶(bucket)有兩個理由:

(1)獲得更高的查詢處理效率。桶為表加上了額外的結構,hive 在處理有些查詢時能利用這個結構。具體而言,連線兩個在(包含連線列的)相同列上劃分了桶的表,可以使用 map 端連線 (map-side join)高效的實現。比如join操作。對於join操作兩個表有乙個相同的列,如果對這兩個表都進行了桶操作。那麼將儲存相同列值的桶進行join操作就可以,可以大大較少join的資料量。

(2)使取樣(sampling)更高效。在處理大規模資料集時,在開發和修改查詢的階段,如果能在資料集的一小部分資料上試執行查詢,會帶來很多方便。

1. 建立帶桶的 table :

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

首先,我們來看如何告訴hive—個表應該被劃分成桶。我們使用clustered by 子句來指定劃分桶所用的列和要劃分的桶的個數:

create table bucketed_user(id int) name string)

clustered by (id) into 4buckets;

在這裡,我們使用使用者id來確定如何劃分桶(hive使用對值進行雜湊並將結果除 以桶的個數取餘數。這樣,任何一桶裡都會有乙個隨機的使用者集合(ps:其實也能說是隨機,不是嗎?)。

用hiveql對兩個劃分了桶的表進行連線,可參見「map連線」部分(p400)。

桶中的資料可以根據乙個或多個列另外進行排序。由於這樣對每個桶的連線變成了高效的

歸併排序(merge-sort)

, 因此可以進一步提公升map端連線的效率。以下語法宣告乙個表使其使用排序桶:

create table bucketed_users(id int, name string)

clustered by (id) sorted by(id asc) into 4 buckets;

我們如何保證表中的資料都劃分成桶了呢?把在hive外生成的資料載入到劃分成 桶的表中,當然是可以的。其實讓hive來劃分桶更容易。這一操作通常針對已有的表。

hive

並不檢查資料檔案中的桶是否和表定義中的桶一致(無論是對於桶的數量或用於劃分桶的列)。如果兩者不匹配,在查詢時可能會碰到錯 誤或未定義的結果。因此,建議讓hive來進行劃分桶的操作。

2. 往表中插入資料:

insert overwrite tablebucketed_users select * from users;

物理上,每個桶就是表(或分割槽)目錄裡的乙個檔案。它的檔名並不重要,但是桶 n 是按照字典序排列的第 n 個檔案。

事實上,桶對應於 mapreduce 的輸出檔案分割槽:乙個作業產生的桶(輸出檔案)和reduce任務個數相同.

3. 對桶中的資料進行取樣:

hive> select * frombucketed_users

>   tablesample(bucket 1 out of 4 on id);

0 nat

4 ann

桶的個數從1開始計數。因此,前面的查詢從4個桶的第乙個中獲取所有的使用者。 對於乙個大規模的、均勻分布的資料集,這會返回表中約四分之一的資料行。我們 也可以用其他比例對若干個桶進行取樣(因為取樣並不是乙個精確的操作,因此這個 比例不一定要是桶數的整數倍)。

注:tablesample是抽樣語句,語法:tablesample(bucket x outof y)

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

hive分割槽與分桶

在hive select查詢中一般會掃瞄整個表內容,會消耗很多時間做沒必要的工作。有時候只需要掃瞄表中關心的一部分資料,因此建表時引入了partition概念。分割槽表指的是在建立表時指定的partition的分割槽空間。hive可以對資料按照某列或者某些列進行分割槽管理,所謂分割槽我們可以拿下面的...

hive的分桶,和分割槽

開啟分桶模式 set hive.enforce.bucketing true 制定reduce個數是4 set mapreduce.job.reduces 4 建立乙個分桶表 create table stu buck sno int,sname string,string,sage int,sde...

Hive分割槽和分桶區別

一.定義上 分割槽 建立分割槽表 create table student id int,name string,age int,address string partitioned by dt string,type string 制定分割槽 row format delimited fields...