1、基本概念
(1)桶表是對某一列數據進行哈希取值以將數據打散,然后放到不同文件中存儲。
(2)在hive分區表中,分區中的數據量過於龐大時,建議使用桶。
(3)在分桶時,對指定字段的值進行hash運算得到hash值,並使用hash值除以桶的個數做取余運算得到的值進行分桶,保證每個桶中有數據但每個桶中的數據不一定相等。
做hash運算時,hash函數的選擇取決於分桶字段的數據類型
(4)分桶后的查詢效率比分區后的查詢效率更高
2、桶表的創建
create table btable1 (id int) clustered by(id) into 4 buckets;
創建只有一個字段(id)的桶表,按照id分桶,分為4個bucket,而bucket的數量等於實際數據插入中reduce的數量。
3、間接加載數據
桶表不能通過load的方式直接加載數據,只能從另一張表中插入數據
4、操作示例
(1)環境配置,使hive能夠識別桶
必須按照如下配置: vim ~/.hiverc 添加:set hive.enforce.bucketing = true;
(2)創建桶表
create table btable1 (id int) clustered by(id) into 4 buckets;
(3)創建中間過渡表並為其加載數據
create table btest2(id int); load data local inpath 'btest2' into table btest2;
(4)桶表的數據插入
insert into table btest1 select * from btest2;
(5)修改桶表中bueket數量
alter table btest3 clustered by(name,age) sorted by(age) into 10 buckets;
(6)Hive中的抽樣查詢
select * from table_name tablesample(bucket X out of Y on field);
X表示從哪個桶中開始抽取,Y表示相隔多少個桶再次抽取。
Y必須為分桶數量的倍數或者因子,比如分桶數為6,Y為6,則表示只從桶中抽取1個bucket的數據;若Y為3,則表示從桶中抽取6/3(2)個bucket的數據
create table bkt(name string,id string,phone string,card_num bigint,email string,addr string) clustered by(card_num) into 30 buckets; create table bak(name string,id string,phone string,card_num bigint,email string,addr string) row format delimited fields terminated by ',' load data local inpath '/home/xfvm/bak' into table bak; insert into table bkt select * from bak;
示例:
select * from bkt tablesample(bucket 2 out of 6 on card_num)
表示從桶中抽取5(30/6)個bucket數據,從第2個bucket開始抽取,抽取的個數由每個桶中的數據量決定。相隔6個桶再次抽取,因此,依次抽取的桶為:2,8,14,20,26
注意:執行數據插入時,reduce數量等於分桶數量
5、Hive中的視圖(按需查詢,提高查詢效率)
創建視圖時只是創建一個與源表的映射,視圖中的字段由用戶按需決定。
create view bktview as select bkt.card_num,bkt.name,bkt.email,bkt.addr from bkt
視圖的查詢結果,數據實際上仍然存放在源表中。