一、分桶
分區針對的是數據的存儲路徑;分桶針對的是數據文件,就相當於hadoop裏面的真正的分區。
★怎麼選擇桶?默認時對某一列進行hash,使用hashcode對 桶的個數求模取餘,確定哪一條記錄進入哪一個桶。分桶後,桶內有序,整體不一定有序。
分區提供一個隔離數據和優化查詢的便利方式。不過,並非所有的數據集都可形成合理的分區,特別是之前所提到過的要確定合適的劃分大小這個疑慮。
分桶是將數據集分解成更容易管理的若干部分的另一個技術。
分桶的目的一部分也是爲了抽樣調查
案例實操:
1、創建分桶表
create table stu_buk(id int, name string)
clustered by(id) #根據什麼分桶-----
into 4 buckets #分幾個桶
row format delimited fields terminated by '\t';
2、導入數據
1001 ss1
1002 ss2
1003 ss3
1004 ss4
1005 ss5
1006 ss6
1007 ss7
1008 ss8
hive (default)> load data local inpath '/opt/module/datas/student.txt' into table stu_buck;
3、查看創建的分桶表中是否分成4個桶
居然發現沒有4個桶?原因是分桶表是不能通過load上傳數據的,試想一下,數據上傳到hdfs上,這個過程怎麼識別分桶字段,有怎麼取hash值呢
★綜上所述可得,分通表只能是使用insert select的方式
步驟:
(1)先建一個普通的stu表
create table stu(id int, name string) row format delimited fields terminated by '\t'; |
(2)向普通的stu表中導入數據
load data local inpath '/opt/module/datas/student.txt' into table stu; |
(3)導入數據到分桶表,通過子查詢的方式
insert into table stu_buck select id, name from stu; |
注意:做這些的前提是,reduce必須是隻有一個
所以必要時要設置:
hive (default)> set hive.enforce.bucketing=true; hive (default)> set mapreduce.job.reduces=-1; hive (default)> insert into table stu_buck select id, name from stu; |
二、抽樣查詢
對於非常大的數據集,有時用戶需要使用的是一個具有代表性的查詢結果而不是全部結果。Hive可以通過對錶進行抽樣來滿足這個需求。
查詢表stu_buck中的數據。
hive (default)> select * from stu_buck tablesample(bucket 1 out of 4 on id); |
注:tablesample是抽樣語句,語法:TABLESAMPLE(BUCKET x OUT OF y) 。
y必須是table總bucket數的倍數或者因子。hive根據y的大小,決定抽樣的比例。例如,table總共分了4份,當y=2時,抽取(4/2=)2個bucket的數據,當y=8時,抽取(4/8=)1/2個bucket的數據。
x表示從哪個bucket開始抽取,如果需要取多個分區,以後的分區號爲當前分區號加上y。例如,table總bucket數爲4,tablesample(bucket 1 out of 2),表示總共抽取(4/2=)2個bucket的數據,抽取第1(x)個和第3(x+y)個bucket的數據。
注意:x的值必須小於等於y的值,否則
會經常報:FAILED: SemanticException [Error 10061]: Numerator should not be bigger than denominator in sample clause for table stu_buck,這是原因是x的值大於了y的值