Hive表的分桶和分区

Hive的分区使用我就不多说了,看我的另一篇博文就可以
https://blog.csdn.net/dudadudadd/article/details/113128126

首先我们对于分桶,我们要知道的是,我们并不常用,它的应用场景在数据颗粒度相当细的时候才会使用

数据颗粒度说的是数据处理的范围,比如一个城市、一个国家、一个日期范围等,这些数据量大,且对数据分区下的数据做操作时,不会存在大量微量操作时我们就只用分区就好了

而我们如果要对数据做非常微量的处理,比如我们对数据操作的级别细致到了一个年级中的一个班级,这种情况下可以考虑分桶

但是我们在日常做数据处理的时候,很少使用分桶,甚至是基本不用,我认为这主要是有两个原因

一是在表设计的时候,数据操作的颗粒度级别一般都不是很细微的那种,如果很细那么那么大的数据量想要处理完那就很耗时,小的数据量又不值得,所以对于数据的处理,我们大数据一般只做涉及数据量很大的操作,而那些涉及数据量小且数据颗粒度相当细的操作,往往会被放在如业务系统这类地方去直接实现

举个例子吧,比如我们处理一个学校的数据,如果我们要对所有学校师生生活中的每一件事的数据做处理,我们就可以用时间分区,或者特殊需要时可以使用年级等,不容易发生改变的字段,当然用这种不易变化字段的情况微乎其微

而如果我们处理的业务是针对各个班的,那么我们就可以考虑按班级分桶,因为一个班级中一般在40人左右,能产生的数据量对于大数据来说很少

从这个例子来看大家会发现一个事实,就是分桶,其实应用在数据操作量很细,却需要大数据做为处理手段的情况下才会考虑使用的

注意我的考虑是标红的,因为即使数据量较小,我们一般也不会使用分桶,只是因为第二原因

单对于分桶来说,长时间的运作会导致分桶表的数据一直向桶里装的总有一天会变成高表,这就丢失了分桶可操作少量数据做颗粒度细的操作的始终,也就是从宏观上说会变得同分区且分区字段是不易发生变化的字段一样的效果

当然可以分区、分桶一起用,如下:

create table mytable (id int)
partitioned by (dt string)
clustered by (id) into 3 buckets
row format delimited fields terminated by '\n';

但是这就多此一举了,明明分区了,干嘛还要分桶

所以上面两个原因导致分桶基本不用,不过我们也要知道使用方法

首先我们要知道分桶和分区在使用上的不同,建表的时候分区表的分区字段,必须是表字段之外的字段,分桶表则必须是表字段中的一个字段,分区表使用时要指定分区,而分桶表不用,直接使用就可以,如果遇到我前面例子中分区分桶同时存在时,只需要如使用分区表那样正常使用就可以了

首先建立分桶 表的语句如下

create table mytable (id int)
clustered by (id) into 3 buckets
row format delimited fields terminated by '\n';

意为按照表字段id分三个桶

之后使用时,不需要对分桶做特意指定,我们就当在使用普通的全量表就可以了,但是我们要知道两个配置

set hive.enforce.bucketing = true;
set mapreduce.job.reduces=4;//这个是你的分桶数

有时候导入的数据分桶不均匀,或者无法分桶,这个时候就需要上面的配置,在执行语句的时候一起执行,用来强制分桶

且要注意如果分桶正常,在hdfs上分桶表的数据目录,应该和分区表类似,也就是说分桶数等于文件个数

但是还有一个注意点就是,如果在使用load之后,发现使用了我上面说的两个配置,而hdfs上的文件数还是不对,比如你执行了下面操作

set hive.enforce.bucketing = true;
set mapreduce.job.reduces=4;//这个是你的分桶数
load data...........//load语句省略

那么不要慌,这是正常的现象,这一点解释起来比较麻烦,总的来说就是load数据时数据无法完成自动分桶,所以分桶表要想生效除了前面我说的两个配置之外,我们还要使用insert语句,且同时要使用开窗函数distribute by对数据手动分桶,就是说我们load的那种张表只能作为原始表用,从它出发向另一张正常的分区表中加载数据,语句样例如下

set hive.enforce.bucketing = true;
set mapreduce.job.reduces=4;//这个是你的分桶数
insert into table mytable111
select id from mytable distribute by(id);

如果你想让桶内数据有序,那么还需要在建表的时候添加设置

create table mytable (id int)
clustered by (id) into 3 buckets
sorted by(id DESC)//id倒序
row format delimited fields terminated by '\n';

在加载数据的时候就可以有序了,当然也可以指定排序

set hive.enforce.bucketing = true;
set mapreduce.job.reduces=4;//这个是你的分桶数
insert into table mytable111
select id from mytable distribute by(id) sorted by(id asc);

到此分桶就说这些

但是我最后想和大家说的是,无论是分区还是分桶他们只是在加载数据的时候需要特别注意,在查询的时候其实没差别反之都是要按需求指定分区或者分桶字段的,至于删除和修改,大数据一般不考虑这两个功能,因为大数据的数据是从其他系统等地方都过来的,抽取的时候就是当前的最终版,没有修改和删除的必要

这也是老版本hive不支持修改和删除的原因,不过新版本由于有需要所以支持了,但是用的也很少,一般不使用

猜你喜欢

转载自blog.csdn.net/dudadudadd/article/details/113131486