好程式設計師大資料學習路線分享hive分割槽和分桶

好程式設計師IT發表於2019-08-20

好程式設計師大資料學習路線分享 hive 分割槽和分桶, hive分割槽

1. 為什麼要分割槽??

當單個表資料量越來越大的時候,hive查詢通常會全表掃描,這將會浪費我們不關心資料的掃描,浪費大量時間。從而hive引出分割槽概念partition

2. 怎麼分割槽??

看具體業務,能把一堆資料拆分成多個堆的資料就可以。 通常使用id 、 年 、 月 、天 、區域 、省份、 hive分割槽和mysql分割槽的區別?? mysql的分割槽欄位採用的表內欄位。 hive的分割槽欄位使用的是表外欄位。

3.hive 分割槽細節??

1、分割槽本質是在該表下建立對應的目錄。 2、分割槽名大小寫不區分,建議不要使用中文。 3、可以查詢分割槽資訊。但是我們的分割槽欄位相當於是一個偽欄位,在後設資料中存在,但是不真實存在資料內容中。

4、載入資料時要指定分割槽

4. 分割槽操作

建立一級分割槽表:

create table if not exists day_part(
uid int,
uname string
)
partitioned by(year int)
row format delimited fields terminated by '\t'
;
load data local inpath '/root/Desktop/student.txt' into table day_part partition(year=2017);
load data local inpath '/root/Desktop/score.txt' into table day_part partition(year=2016);
show partitions day_part;

二級分割槽

create table if not exists day_part1(
uid int,
uname string
)
partitioned by(year int,month int)
row format delimited fields terminated by '\t'
;
load data local inpath '/root/Desktop/student.txt' into table day_part1 partition(year=2017,month=04);
load data local inpath '/root/Desktop/score.txt' into table day_part1 partition(year=2017,month=03);

三級分割槽:

create table if not exists day_part2(
uid int,
uname string
)
partitioned by(year int,month int,day int)
row format delimited fields terminated by '\t'
;

對分割槽進行操作: 顯示分割槽:

show partitions day_part;

新增分割槽:空的

alter table day_part1 add partition(year=2017,month=2);
alter table day_part1 add partition(year=2017,month=1) partition(year=2016,month=12);

新增分割槽並載入資料:

alter table day_part1 add partition(year=2016,month=11) location "/user/hive/warehouse/qf1603.db/day_part1/year=2017/month=2";

修改--分割槽所對應的儲存路徑:

## 路徑必須從 hdfs 寫起
alter table day_part1 partition(year=2016,month=11) set location "hdfs://linux1:9000/user/hive/warehouse/qf1603.db/day_part1/year=2017/month=3";

刪除分割槽:刪除分割槽將會刪除對應的分割槽目錄(資料)

## 刪除某個分割槽
alter table day_part1 drop partition(year=2017,month=2);
## 刪除多個
alter table day_part1 drop partition(year=2017,month=3),partition(year=2017,month=4);

靜態分割槽、動態分割槽、混合分割槽 靜態分割槽:新增分割槽或者是載入分割槽資料時,已經指定分割槽名。 動態分割槽:新增分割槽或者是載入分割槽資料時,分割槽名未知。 混合分割槽:靜態分割槽和動態分割槽同時存在。

動態分割槽的相關屬性: hive.exec.dynamic.partition=true :是否允許動態分割槽 hive.exec.dynamic.partition.mode=strict :分割槽模式設定nostrict strict:最少需要有一個是靜態分割槽 nostrict:可以全部是動態分割槽 hive.exec.max.dynamic.partitions=1000 :允許動態分割槽的最大數量 hive.exec.max.dynamic.partitions.pernode =100 :單個節點上的mapper/reducer允許建立的最大分割槽

建立臨時表:

## 建立臨時表
create table if not exists tmp(
uid int,
commentid bigint,
recommentid bigint,
year int,
month int,
day int
)
row format delimited fields terminated by '\t';
## 載入資料
load data local inpath '/root/Desktop/comm' into table tmp;

建立動態分割槽:

## 建立動態分割槽表
create table if not exists dyp1(
uid int,
commentid bigint,
recommentid bigint
)
partitioned by(year int,month int,day int)
row format delimited fields terminated by '\t'
;

為動態分割槽載入資料:

## 嚴格模式
insert into table dyp1 partition(year=2016,month,day)
select uid,commentid,recommentid,month,day from tmp;
## 非嚴格模式
## 設定非嚴格模式動態分割槽
set hive.exec.dynamic.partition.mode=nostrict;
## 建立動態分割槽表
create table if not exists dyp2(
uid int,
commentid bigint,
recommentid bigint
)
partitioned by(year int,month int,day int)
row format delimited fields terminated by '\t';
## 為非嚴格模式動態分割槽載入資料
insert into table dyp2 partition(year,month,day)
select uid,commentid,recommentid,year,month,day from tmp;

hive提供我們一個嚴格模式:為了阻止使用者不小心提交惡意hql hive.mapred.mode=nostrict : strict
如果該模式值為strict,將會阻止以下三種查詢: 1、對分割槽表查詢,where中過濾欄位不是分割槽欄位。 2、笛卡爾積join查詢,join查詢語句,不帶on條件 或者 where條件。

select
stu.id,
stu.name,
score.grade
from student stu
join score
;

可以:

select
stu.id,
stu.name,
score.grade
from student stu
join score
where stu.id = score.uid
;

3、對order by查詢,有order by的查詢不帶limit語句。

select
student.*
from student
order by student.id desc
;

注意: 1、儘量不要是用動態分割槽,因為動態分割槽的時候,將會為每一個分割槽分配reducer數量,當分割槽數量多的時候,reducer數量將會增加,對伺服器是一種災難。 2、動態分割槽和靜態分割槽的區別,靜態分割槽不管有沒有資料都將會建立該分割槽,動態分割槽是有結果集將建立,否則不建立。 3、hive動態分割槽的嚴格模式和hive提供的hive.mapred.mode的嚴格模式。

分桶

1. 為什麼要分桶??

分割槽資料依然很大,對分割槽資料或者表資料更加細粒度的管理。 分桶關鍵字: clustered by(uid) into n buckets 、bucket 、 分桶使用表內欄位 怎麼分桶?? 對分桶欄位進行hash值,然後將hash值模於總的桶數,然後得到桶數

2. 分桶的意義:

1、快速抽樣查詢。tablesample 2、減少查詢掃描資料量,提高查詢效率。

## 建立分桶表,設定 4 個分桶
create table if not exists bucket1(
uid int,
uname String
)
clustered by(uid) into 4 buckets
row format delimited fields terminated by '\t'
;

3. 分桶的操作:

為分桶表載入資料: 分桶不能使用load方式來載入資料,而需要iinsert into方式來載入 並且需要設定屬性:

## 設定分桶啟用
hive> set hive.enforce.bucketing=true;
## 錯誤的載入資料方式
load data local inpath '/root/Desktop/student' into table bucket1;
## 建立分桶表,設定 4 個分桶
create table if not exists bucket7(
uid int,
uname String
)
clustered by(uid) into 4 buckets
row format delimited fields terminated by '\t'
;
## 為分桶表載入資料
insert into table bucket7
select id,name from student
;

分桶查詢:tablesample(bucket x out of y on uid) 注意:x不能大於y x:所取桶的起始位置, y:所取桶的總數,y是總桶數的因子。y大於源總桶數相當於拉伸,y小於源總桶數相當於壓縮 1 out of 2 1 1+4/2 2 out of 2 2 2+4/2

1 out of 4 1 1+4

select * from bucket7;
select * from bucket7 tablesample(bucket 1 out of 4 on uid);
select * from bucket7 tablesample(bucket 2 out of 4 on uid);
select * from bucket7 tablesample(bucket 1 out of 2 on uid);
select * from bucket7 tablesample(bucket 2 out of 2 on uid);
select * from bucket7 tablesample(bucket 3 out of 2 on uid);
select * from bucket7 tablesample(bucket 1 out of 8 on uid);
select * from bucket7 tablesample(bucket 5 out of 8 on uid);

分割槽+分桶:(qfstu) uid,uname,class,master gender分割槽 分桶uid 基偶分桶 查詢女生中的學號為基數??

## 建立表
create table if not exists qftmp(
uid int,
uname string,
class int,
gender int)
row format delimited fields terminated by '\t';
## 載入資料
load data local inpath '/home/qf' into table qftmp;
## 建立動態分割槽分桶表
create table if not exists qf(
uid int,
uname string,
class int)
partitioned by(gender int)
clustered by(uid) into 2 buckets
row format delimited fields terminated by '\t';
## 為動態分割槽分桶表載入資料
insert into table qf partition(gender)
select uid,uname,class,gender from qftmp;

 

查詢女生中的學號為基數?????

 

select * from qf where gender = 2 and uid%2 != 0;
select * from qf tablesample(bucket 2 out of 2 on uid) where gender = 2;

分桶使用內部關鍵字,分割槽使用的是外部欄位。 兩者都是對hive的一個最佳化。 分割槽和分桶的數量都要合理設定,不是越多越好。

抽樣:

select * from student order by rand() limit 3;
select * from student limit 3;
select * from student tablesample(3 rows);
select * from student tablesample(20B); ## 最小單位是 B
select * from student tablesample(20 percent);## 百分比


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2654303/,如需轉載,請註明出處,否則將追究法律責任。

相關文章