大数据之路Week08_day03 (Hive的动态分区和分桶)
一、動態分區
先來說說我對動態分區的理解與一些感受吧。
由于我們通過hive去查詢數據的時候,實際還是查詢HDFS上的數據,一旦一個目錄下有很多文件呢?而我們去查找的數據也沒有那么多,全盤掃描就會浪費很多時間和資源。
為了避免全盤掃描和提高查詢效率,引入了分區的概念。
分區的展現形式,就是在HDFS上的多級目錄展現。
分區又分為靜態分區和動態分區,靜態分區是我們在創建表的時候去手動創建分區,然后將文件load上去。
這樣就會顯得很麻煩,當我們數據量特別大而且是同一類型數據的時候,手動就會顯得很麻煩,也很容易出錯。
于是我們有了動態分區,使用 insert 去插入數據
在去使用動態分區的時候,我們首先需要開啟動態分區。
開啟動態分區支持
hive>set hive.exec.dynamic.partition=true; (一定要開啟!!!!!)
設置嚴格動態分區
hive>set hive.exec.dynamic.partition.mode=nostrict;
設置最大可以分多少區
hive>set hive.exec.max.dynamic.partitions.pernode=1000;
當然,這里需要注意的一點就是,適當的分區可以提高我們的查詢效率,但是過多的去分區,效果則會相反,因為分區多了,多級目錄就會加深,去查詢的時候就會將時間浪費在這個遞歸查詢上面,反而會降低查詢效率。
一般創建動態分區的時候,先將所有數據放在一個目錄下,然后通過insert into ... select ... from ... 的方式將數據加載過去,自動創建
舉例:(說那么多,不如實際操作記憶深刻)
首先我們先準備數據
1,小虎1,12,man,lol-book-moive,beijing:shangxuetang-shanghai:pudong
2,小虎2,13,boy,lol-book-moive,beijing:shangxuetang-shanghai:pudong
3,小虎3,13,man,lol-book-moive,beijing:shangxuetang-shanghai:pudong
4,小虎4,12,boy,lol-book-moive,beijing:shangxuetang-shanghai:pudong
5,小虎5,13,man,lol-book-moive,beijing:shangxuetang-shanghai:pudong
6,小虎6,13,boy,lol-book-moive,beijing:shangxuetang-shanghai:pudong
7,小虎7,13,man,lol-book-moive,beijing:shangxuetang-shanghai:pudong
8,小虎8,12,boy,lol-book-moive,beijing:shangxuetang-shanghai:pudong
9,小虎9,12,man,lol-book-moive,beijing:shangxuetang-shanghai:pudong
創建一個普通的表
create table stu_dy1_1
(
id int,
name string,
age int,
gender string,
likes array<string>,
address map<string,string>
)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':'
將數據load到這個表中
load data local 'Linux本地文件目錄' into table stu_dy1_1;
然后創建動態分區表
create table stu_dy1_2
(
id int,
name string,
likes array<string>,
address map<string,string>
)partitioned by(age int,gender string)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':'
最后使用inset的方式將stu_dy1_1上的數據加載過來
from放在前面或者后面都可以
from stu_dy1_1
insert into stu_dy1_2 partition(age,gender)
select id,name,likes,address,age,gender 或者 insert into stu_dy1_2 partition(age,gender)
select id,name,likes,address,age,gender from stu_dy1_1
去HDFS上查看
二、分桶
首先,分區和分桶是兩個不同的概念,很多資料上說需要先分區在分桶,其實不然,分區是對數據進行劃分,而分桶是對文件進行劃分。
當我們的分區之后,最后的文件還是很大怎么辦,就引入了分桶的概念。
將這個比較大的文件再分成若干個小文件進行存儲,我們再去查詢的時候,在這個小范圍的文件中查詢就會快很多。
對于hive中的每一張表、分區都可以進一步的進行分桶。
當然,分桶不是說將文件隨機進行切分存儲,而是有規律的進行存儲。在看完下面的例子后進行解釋,現在干巴巴的解釋也不太好理解。它是由列的哈希值除以桶的個數來決定每條數據劃分在哪個桶中。
創建順序和分區一樣,創建的方式不一樣。
舉例:
首先我們依然需要開啟分桶的支持:
set hive.enforce.bucketing=true; (依然十分重要,不然無法進行分桶操作!!!!)
數據準備:(id,name,age)
1,tom,11
2,cat,22
3,dog,33
4,hive,44
5,hbase,55
6,mr,66
7,alice,77
8,scala,88
創建一個普通的表
create table psn31
(
id int,
name string,
age int
)
row format delimited
fields terminated by ','
將數據load到這張表中
load data local '文件在Linux上的絕對路徑' into table psn31;
創建分桶表
create table psn_bucket
(
id int,
name string,
age int
)
clustered by(age) into 4 buckets
row format delimited
fields terminated by ','
將數據insert到表psn_bucket中(注意:這里和分區表插入數據有所區別,分區表需要select 和指定分區,而分桶則不需要)
insert into psn_bucket select id,name,age from psn31;
去HDFS上查看數據
查詢數據
我們在linux中使用Hadoop的命令查看一下(與我們猜想的順序一致)
這里設置的桶的個數是4 數據按照 年齡%4 進行放桶(文件)
11%4 == 3 -----> 000003_0
22%4 == 2 -----> 000002_0
33%4 == 1 -----> 000001_0
44%4 == 0 -----> 000000_0
...以此類推
在HIve進行查詢
select * from psn_bucket tablesample(bucket 2 out of 2);
隨機取值(設置因子,桶的個數/因子)
這里就是取2號桶和4號桶,取2個
select * from psn_bucket tablesample(bucket 2 out of 4);
隨機取值(設置因子,桶的個數/因子)
這里就是取2號桶,取一個
select * from psn_bucket tablesample(bucket 2 out of 8);
隨機取值(設置倍數,倍數/桶的個數)
這里就是取2號桶 1/2個數據
取出來是一條數據
而我們一般取因子!!!
總結
以上是生活随笔為你收集整理的大数据之路Week08_day03 (Hive的动态分区和分桶)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: main函数的入口函数
- 下一篇: html5文本标签