Hive的分割槽和排序

你的镁偷走了我的锌發表於2024-11-13

一、Hive的分割槽(十分重要)

1、分割槽是什麼
答:我們可以把一個大的檔案分隔成一個個小的檔案,這樣每次操作一個小檔案就很方便了
2、為什麼要進行分割槽
答:透過分割槽,當我們查詢的時候,可以只掃描與條件相關的分割槽,這樣做,避免了全域性掃描,加快查詢速度

1、靜態分割槽(SP)

靜態分割槽指的是,在我們將資料上傳到hdfs上的時候,進行手動分割槽,例如

靜態分割槽(單分割槽)

建立表時:
CREATE TABLE IF NOT EXISTS t_student (
sno int,
sname string
) partitioned by(grade int)
row format delimited fields terminated by ',';
與平常建表不同,在靜態分割槽建表的時候需要指定欄位,但是這個欄位不能和表欄位相同

將資料放到hdfs上的時候,需要指定分割槽
load data local inpath '/usr/local/soft/bigdata32/data/stu1.txt' into table t_student partition(grade=1);
load data local inpath '/usr/local/soft/bigdata32/data/stu2.txt' into table t_student partition(grade=2);
load data local inpath '/usr/local/soft/bigdata32/data/stu3.txt' into table t_student partition(grade=3);
load data local inpath '/usr/local/soft/bigdata32/data/stu4.txt' into table t_student partition(grade=5);
將stud1的資料放到grade1這個分割槽中去...

2、靜態分割槽(多分割槽)

create table if not exists t_teacher (
tno int,
tname string
) partitioned by(grade int,clazz int)
row format delimited fields terminated by ',';
指定多個分割槽欄位

向hdfs上載入資料
load data local inpath '/usr/local/soft/bigdata32/data/t1.txt' into table t_teacher partition(grade=1,clazz=1);
load data local inpath '/usr/local/soft/bigdata32/data/t2.txt' into table t_teacher partition(grade=1,clazz=2);
load data local inpath '/usr/local/soft/bigdata32/data/t3.txt' into table t_teacher partition(grade=1,clazz=3);
load data local inpath '/usr/local/soft/bigdata32/data/t4.txt' into table t_teacher partition(grade=2,clazz=1);
load data local inpath '/usr/local/soft/bigdata32/data/t5.txt' into table t_teacher partition(grade=2,clazz=2);
需要指定兩個分割槽編號,相當於巢狀關係

3、查詢語句

select count(*) from t_student where grade=1

檢視分割槽
show partition t_teacher;

2、動態分割槽(DP)

什麼是動態分割槽?
答:動態分割槽透過資料來進行判斷,並且動態分割槽只有在sql執行時才能決定

1、開啟動態分割槽

設定能夠進行動態分割槽
set hive.exec.dynamic.partition=true;
將分割槽改為不嚴格的
set hive.exec.dynamic.partition.mode=nonstrict;

2、構建動態分割槽

--建立分割槽表
CREATE TABLE IF NOT EXISTS t_student_d (
sno int,
sname string
) partitioned by (grade int,clazz int)
row format delimited fields terminated by ',';

--建立外部表
CREATE EXTERNAL TABLE IF NOT EXISTS t_student_e (
sno int,
sname string,
grade int,
clazz int
)
row format delimited fields terminated by ','
location "/bigdata29/teachers";

資料:
1,xiaohu01,1,1
2,xiaohu02,1,1
3,xiaohu03,1,1
4,xiaohu04,1,2
5,xiaohu05,1,2
6,xiaohu06,2,3
7,xiaohu07,2,3
8,xiaohu08,2,3
9,xiaohu09,3,3
10,xiaohu10,3,3
11,xiaohu11,3,3
12,xiaohu12,3,4
13,xiaohu13,3,4
14,xiaohu14,3,4
15,xiaohu15,3,4
16,xiaohu16,4,4
17,xiaohu17,4,4
18,xiaohu18,4,5
19,xiaohu19,4,5
20,xiaohu20,4,5
21,xiaohu21,4,5

指定分割槽欄位
insert overwrite table t_student_d partition (grade,clazz) select * from t_student_e;
結果會將資料自動的進行分割槽

3、動態分割槽的優缺點

優點:不用手動指定了,自動的會對資料進行分割槽
缺點:可能會發生資料傾斜

二、Hive的分桶

1、什麼是分桶

答:分桶是將一個大的檔案分成一個個小的檔案進行儲存

2、分桶的原理

答:對列進行雜湊,然後除以桶的個數進行取餘,這樣就決定了資料該放在哪個桶裡

3、進行分桶的操作

1、先開啟分桶的支援

set hive.enforce.bucketing=ture;

2、建立一個表

create table person
(
id int,
name string,
age int
)
row format delimited
fields terminated by ',';

3、將資料導到這張表中去

load data local inpath '/usr/loacl/soft/bigdata32/data/1.txt' into table person;

4、建立分桶表

create table psn_bucket
(
id int,
name string,
age int
)
clustered by(age) into 4 buckets
row format delimited fields terminated by ',';

5、將資料insert到分桶表中去

insert into psn_bucket select * from person;

三、Hive JDBC

1、新建maven專案並匯入依賴

2、編寫JDBC

四、Hive查詢語句

1、全域性排序

order by 就是全域性排序,因此只有一個reduce,會導致當資料規模較大的時候,查詢結果過慢
order by 後面可以跟 引數,如果不跟就預設為升序,如果加上desc就表示降序

2、區域性排序

sort by 是在資料進入reduce之前進行排序,他只能保證資料區域性有序

設定reduce的個數

set mapreduce.job.reduces=3;

檢視reduce的個數

set mapreduce.job.reduce;

分割槽排序

distribute by
根據指定的欄位將資料分到不同的reducer
一般結合sort by使用,但是要在sort by之前

分割槽並排序

cluster by 只能預設升序,不能使用倒序
能確保將指定列具有相同值的行分組在一起

五、Hive的內建函式

進多出一

select *,concat_ws(':',collect_set(列名))as 別名 from 表名 group by id;

進一出多

需要對一個資料進行拆分
select explode(split(列名,“資料分隔符”)) from 表名

lateral view 表生成函式,可以將explode的資料生成一個列表
資料:
1,這個殺手不太冷,劇情-動作-犯罪
2,七武士,動作-冒險-劇情
3,勇敢的心,動作-傳記-劇情-歷史-戰爭
4,東邪西毒,劇情-動作-愛情-武俠-古裝
5,霍位元人,動作-奇幻-冒險
透過如下sql將資料變成下面的形式(將一列變成多行)
select id,name from t_movie1 lateral view explode(split(types,"-")) typetable as type;
1,這個殺手不太冷,劇情
1,這個殺手不太冷,動作
1,這個殺手不太冷,犯罪
2,七武士,動作
2,七武士,冒險
2,七武士,劇情
3,勇敢的心,動作
3,勇敢的心,傳記
3,勇敢的心,劇情
3,勇敢的心,歷史
3,勇敢的心,戰爭
4,東邪西毒,劇情
4,東邪西毒,動作
4,東邪西毒,愛情
4,東邪西毒,武俠
4,東邪西毒,古裝
5,霍位元人,動作
5,霍位元人,奇幻
5,霍位元人,冒險
就是這在id,name欄位後面再加上拆分出來的資料

相關文章