hive数据分析002-分桶

一、桶的概念:

对于每一个表(table)或者分区, Hive可以进一步组织成桶,

也就是说桶是更为细粒度的数据范围划分。Hive也是 针对某一列进行桶的组织。Hive采用
对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。
把表(或者分区)组织成桶(Bucket)有两个理由:
(1)、获得更高的查询处理效率。
(2)、使取样(sampling)更高效。

强制多个 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’

二、操作
(1)、分桶案例:
a、创建普通表:

create table if not exists stu(
eNo int,
name string,
sex string,
age int
)
row format delimited fields terminated by'\t'
stored as textfile;

创建一个文件

vi stu.txt
1	xiaoA	nan	21
2	xiaoB	nv	24
3	xiaoC	nan	21
4	xiaoD	nan	21
5	xiaoE	nan	21
6	xiaoF	nv	26
7	xiaoG	nan	21
8	xiaoH	nan	21
9	xiaoI	nv	27
10	xiaoJ	nv	29
11	xiaoK	nan	21
12	xiaoM	nv	21

将文件数据导入hive表中

load data local inpath '/home/hadoop/data/stu.txt' overwrite into table stu;

b、创建分桶表(对stu表的eNo字段分桶)
注意:分桶字段和分区字段区别

create table if not exists bk_stu(
eNo int,
name string,
sex string,
age int
)
clustered by(eNo) into 4 buckets
row format delimited fields terminated by'\t'
stored as textfile;

注意:
强制多个 reduce 进行输出:
插入数据前需设置,不设置将会只有一个文件:

set hive.enforce.bucketing = true

要向分桶表中填充数据,需要将 hive.enforce.bucketing 属性设置为 true。
这 样,Hive 就知道用表定义中声明的数量来创建桶。

c、从普通表将数据插入到分桶表(注意;插入数据到分桶表时,只能以结果集
的方式插入数据)。

insert into table bk_stu select * from stu;

从hive查看hdfs中的数据方法

hive> dfs -ls hdfs:///user/hive/warehouse/zl.db;
Found 9 items
drwxr-xr-x   - zl supergroup          0 2022-04-21 15:48 hdfs:///user/hive/warehouse/zl.db/bucket_stu
drwxr-xr-x   - zl supergroup          0 2022-04-15 23:01 hdfs:///user/hive/warehouse/zl.db/flowsum
drwxr-xr-x   - zl supergroup          0 2022-04-15 22:45 hdfs:///user/hive/warehouse/zl.db/person
drwxr-xr-x   - zl supergroup          0 2022-04-17 13:21 hdfs:///user/hive/warehouse/zl.db/pt_flow
drwxr-xr-x   - zl supergroup          0 2022-04-21 15:04 hdfs:///user/hive/warehouse/zl.db/pv
drwxr-xr-x   - zl supergroup          0 2022-04-16 16:13 hdfs:///user/hive/warehouse/zl.db/tb_regexp_log
drwxr-xr-x   - zl supergroup          0 2022-04-15 22:45 hdfs:///user/hive/warehouse/zl.db/ticket
drwxr-xr-x   - zl supergroup          0 2022-04-17 14:45 hdfs:///user/hive/warehouse/zl.db/user01
drwxr-xr-x   - zl supergroup          0 2022-04-17 14:22 hdfs:///user/hive/warehouse/zl.db/users

查看分桶,可以看到,分桶的数据

hive> dfs -ls hdfs:///user/hive/warehouse/zl.db/bucket_stu;
Found 2 items
-rwxr-xr-x   2 zl supergroup         60 2022-04-21 15:48 hdfs:///user/hive/warehouse/zl.db/bucket_stu/000000_0
-rwxr-xr-x   2 zl supergroup         71 2022-04-21 15:48 hdfs:///user/hive/warehouse/zl.db/bucket_stu/000001_0

抽样数据结果如下

hive> select * from bucket_stu;
OK
10	oo	nan	22
8	mm	nv	29
6	ff	nan	20
4	dd	nan	23
2	bb	nvn	21
11	ss	nan	20
9	nn	nan	28
7	gg	nan	20
5	ee	nv	22
3	cc	nan	24
1	aa	nv	19

那么如何从分好的桶中取数据呢
注:tablesample是抽样语句,
语法:TABLESAMPLE(BUCKET x OUT OF y)

y必须是table总bucket数的倍数或者因子。
hive根据y的大小,决定抽样的比例。
例如,table总共分了64份:clustered by(eNo) into 64 buckets
当y=32时,抽取(64/32=)2个bucket的数据
当y=128时,抽取(64/128=)1/2个bucket的数据。

x表示从哪个bucket开始抽取。
例如,table总bucket数为32:clustered by(eNo) into 32 buckets
tablesample(bucket 3 out of 16)
表示总共抽取(32/16=)2个bucket的数据,
分别为第3个bucket和第(3+16=)19个bucket的数据。
分桶表查询方式:
clustered by(eNo) into 4 buckets
(1)、随机查询并且返回一桶数据:

select * from bk_stu tablesample(bucket 3 out of 4);

(2)、随机查询并且返回两桶数据:

select * from bk_stu tablesample(bucket 1 out of 2); 

(3)、随机查询并且返回全桶数据:

select * from bk_stu tablesample(bucket 1 out of 1);

(4)、随机查询并且返回半桶数据:

select * from bk_stu tablesample(bucket 3 out of 8);

三、分桶总结

抽样查询======================
分桶表:bk_stu
普通表:stu

#随机从某表中取10条数据:
select * from stu order by rand() limit 3;
11 xiaoK nan 21
3 xiaoC nan 21
4 xiaoD nan 21
Time taken: 114.053 seconds, Fetched: 3 row(s)

select * from bk_stu tablesample(bucket 1 out of 4 on eNo);
OK
12 xiaoM nv 21
8 xiaoH nan 21
4 xiaoD nan 21
Time taken: 1.567 seconds, Fetched: 3 row(s)

对比时间:分桶表查询的速度肯定比普通表块!

#数据块取样 (TABLESAMPLE (n PERCENT))抽取表大小的n%
select * from bk_stu tablesample(50 PERCENT);
select * from bk_stu tablesample(25 PERCENT);

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

#指定抽取条数(TABLESAMPLE (n ROWS))
select * from bk_stu tablesample(4ROWS);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值