分区提供一个隔离数据和优化查询的便利方式。不过,并非所有的数据集都可形成合理的分区。对于一张表或者分区,Hive 可以进一步组织成桶,也就是更为细粒度的数据范围划分,分区针对的是数据的存储路径,分桶针对的是数据文件。
分桶表的基本原理是,首先为每行数据计算一个指定字段的数据的hash值,然后模以一个指定的分桶数,最后将取模运算结果相同的行,写入同一个文件中,这个文件就称为一个分桶(bucket)。需要对表的数据进行hash分区
分区和分桶没有必然的联系,是两个不同的概念。分区表是将数据存储到不同的分区里面,分桶表是将数据存储到不同的文件里面。
一张表可以既是分区表也是分桶表。对于分区分桶表,会对每一个分区里面的数据进行分桶。
不能对同一个字段既分区又分桶。因为如果一个字段分区了,那么这个字段在这个分区里面都是相同的,再分桶也是分到同一个桶里面,是没有意义的。而且分区字段还是一个虚拟字段。
分桶表的作用是对数据进行抽样
在实际生产过程中,当数据量比较大,且又希望对数据进行快速分析获取分析结果,并且还能够容忍一定程度上的分析误差的时候,可以考虑对数据进行抽样处理。需要注意的是,在抽样的时候,抽样字段和要分析的字段之间不能有关联性。例如性别和身高之间就是又关联性的,姓名和体重之间是没有关联性的
有1000W人口数据,我需要这些数据的体重比列
1000w分成20份,每份50W,我抽取8份来分析
在Hive中,分桶机制默认是不开启,需要开启分桶机制
set hive.enforce.bucketing = true;
建立分桶表 - 桶数指定的越多执行分桶的时候耗费的资源越多,下边的例子会根据name字段的值分到桶里
create table student_bucket(id int, name string) clustered by (name) into 5 buckets row format delimited fields terminated by '\t';
在Hive中向分桶表中添加数据的时候,只能使用insert方式而不能使用load方式,使用load方式不会对数据进行分桶
insert overwrite table student_bucket select id, name from student;
查看分成5个桶,每个桶代表一个单独的抽样文件
对数据进行抽样
select * from student_bucket tablesample (bucket 1 out of 2 on name);
bucket x out of y,x表示从第一个桶的第几行开始抽,y表示抽样步长,即每几行抽一次
每一个桶都会对应一个单独的结果文件