Hive 桶的分区


(一)、桶的概念:
对于每个表(table)或者分区, Hive能够进一步组织成桶(没有分区能分桶吗?),
也就是说桶是更为细粒度的数据范围划分。Hive也是 针对某一列进行桶的组织。Hive采用
对列值哈希,而后除以桶的个数求余的方式决定该条记录存放在哪一个桶当中。
把表(或者分区)组织成桶(Bucket)有两个理由:
(1)、得到更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用
这个结构。具体而言,链接两个在(包含链接列的)相同列上划分了桶的表,可使用
Map 端链接 (Map-side join)高效的实现。好比JOIN操做。对于JOIN操做两个表有一个
相同的列,若是对这两个表都进行了桶操做。那么将保存相同列值的桶进行JOIN操做就可
以,能够大大较少JOIN的数据量。
(2)、使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,
若是能在数据集的一小部分数据上试运行查询,会带来不少方便。ide

(3)、强制多个 reduce 进行输出:
插入数据前需设置,不设置将会只有一个文件:
set hive.enforce.bucketing = true
要向分桶表中填充数据,须要将 hive.enforce.bucketing 属性设置为 true。
这 样,Hive 就知道用表定义中声明的数量来建立桶。而后使用 INSERT 命令便可。
须要注意的是: clustered by和sorted by不会影响数据的导入,这意味着,用户必须本身负责数据如何如何导入,包括数据的分桶和排序。
'set hive.enforce.bucketing = true' 能够自动控制上一轮reduce的数量从而适配bucket的个数,
固然,用户也能够自主设置mapred.reduce.tasks去适配bucket个数,推荐使用'set hive.enforce.bucketing = true' oop


2、案例操做
一、以用户ID做为分桶依据,将用户数据分4个桶存放
建立普通表:
create table if not exists u_users(
uid int,
uname string,
uage int
)
row format delimited fields terminated by',';ui

vi u_users.txt
1,xiaoA,12
2,xiaoB,10
3,xiaoC,12
4,xiaoD,17
5,xiaoE,12
6,xiaoF,16
7,xiaoG,15
8,xiaoH,12
9,xiaoW,12
10,xiaoT,12
11,xiaoL,18orm

load data local inpath '/opt/data/u_users.txt' into table u_users;排序

建立分桶表(用户ID做为分桶依据):
create table if not exists bk_users(
uid int,
uname string,
uage int
)
clustered by(uid) into 4 buckets
row format delimited fields terminated by',';ci

说明:
1.clustered by(uid) into 4 buckets 在row format delimited fields terminated by','前面,顺序不能调
2.clustered by(uid) into 4 buckets 是以表的uid做为分桶依据,而后将数据分为4个桶操做。开发


强制多个 reduce 进行输出桶文件
set hive.enforce.bucketing = truestring

加载数据到分桶表:
注意:对分桶表数据的导入只能以结果集的方式添加
insert into table bk_users select * from u_users;it


查看分桶表目录下的桶文件:
hive> dfs -ls hdfs://Hadoop001:9000/user/hive/warehouse/db_1608c.db/bk_users;
Found 4 items
-rwxr-xr-x 3 root supergroup 22 2017-04-24 14:49 hdfs://Hadoop001:9000/user/hive/warehouse/db_1608c.db/bk_users/000000_0
-rwxr-xr-x 3 root supergroup 33 2017-04-24 14:49 hdfs://Hadoop001:9000/user/hive/warehouse/db_1608c.db/bk_users/000001_0
-rwxr-xr-x 3 root supergroup 34 2017-04-24 14:49 hdfs://Hadoop001:9000/user/hive/warehouse/db_1608c.db/bk_users/000002_0
-rwxr-xr-x 3 root supergroup 34 2017-04-24 14:49 hdfs://Hadoop001:9000/user/hive/warehouse/db_1608c.db/bk_users/000003_0io

hive> dfs -cat hdfs://Hadoop001:9000/user/hive/warehouse/db_1608c.db/bk_users/000000_0;
8,xiaoH,12
4,xiaoD,17
hive> dfs -cat hdfs://Hadoop001:9000/user/hive/warehouse/db_1608c.db/bk_users/000001_0;
9,xiaoW,12
5,xiaoE,12
1,xiaoA,12
hive> dfs -cat hdfs://Hadoop001:9000/user/hive/warehouse/db_1608c.db/bk_users/000002_0;
10,xiaoT,12
6,xiaoF,16
2,xiaoB,10
hive> dfs -cat hdfs://Hadoop001:9000/user/hive/warehouse/db_1608c.db/bk_users/000003_0;
11,xiaoL,18
7,xiaoG,15
3,xiaoC,12

分桶表的查询:
select * from bk_users;

tablesample是桶抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y)
select * from bk_users TABLESAMPLE(BUCKET x OUT OF y);

y尽量是table总bucket数的倍数或者因子。

y必需要大于x,不然报错。
hive根据y的大小,决定抽样的比例;

clustered by(id) into 16 buckets;
例如,table总共分了16桶,当y=8时,抽取(16/8=)2个bucket的数据,
当y=32时,抽取(16/32=)1/2个bucket的数据。
x表示从哪一个bucket开始抽取。

clustered by(id) into 32 buckets;
例如,table总bucket数为32,tablesample(bucket 3 out of 16),
表示总共抽取(32/16=)2个bucket的数据,
分别为第3个bucket和第(3+16=)19个bucket的数据。


bk_users分桶结构:clustered by(uid) into 4 buckets
#从bk_users分桶表抽出一桶数据:
x=2,y=4
select * from bk_users TABLESAMPLE(BUCKET 2 OUT OF 4);

#从bk_users分桶表抽出二桶数据:
x=2,y=2
select * from bk_users TABLESAMPLE(BUCKET 2 OUT OF 2);

#从bk_users分桶表抽出四桶数据:
x=1,y=1
select * from bk_users TABLESAMPLE(BUCKET 1 OUT OF 1);

#从bk_users分桶表抽出半桶数据:
x=1,y=8
select * from bk_users TABLESAMPLE(BUCKET 1 OUT OF 8);


=================抽样查询======================
#随机从某表中取5条数据:
select * from u_users order by rand() limit 5;

#数据块取样 (TABLESAMPLE (n PERCENT))抽取表大小的n%
select * from u_users TABLESAMPLE (10 PERCENT);

#指定数据大小取样(TABLESAMPLE (nM)) M为MB单位
select * from u_users TABLESAMPLE (10M);

#指定抽取条数(TABLESAMPLE (n ROWS))
select * from u_users TABLESAMPLE (5 ROWS);


************分区+分桶+混合方式分区******************************
案例2:按国家、城市分桶,以f1字段做为分桶依据
create external table if not exists tb_part_bk_users(
f1 string,
f2 string,
f3 string,
contry string,
city string
)
row format delimited fields terminated by'\t';


load data local inpath '/opt/data/par_buc.txt' into table tb_part_bk_users;

建立分区+分桶表:
create external table if not exists part_bk_users(
f1 string,
f2 string,
f3 string
)
partitioned by(contry string,city string)
clustered by(f1) into 5 buckets
row format delimited fields terminated by'\t';

说明:1.partitioned by(contry string,city string) clustered by(f1) into 5 buckets 先写分区操做、在设置分桶操做 混合方式将数据添加到分区分桶表: 1.打开动态分区设置、设置动态分区模式为非严格模式 set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict; 2.强制多个 reduce 进行输出桶文件 set hive.enforce.bucketing = true 3.只能以结果集的方式添加数据到分桶表 insert into table part_bk_users partition(contry='CA',city) select f1,f2,f3,city from tb_part_bk_users where contry='CA'; insert into table part_bk_users partition(contry='US',city) select f1,f2,f3,city from tb_part_bk_users where contry='US';

相关文章
相关标签/搜索