hive 表分桶标准 hive分桶表创建

admin2024-06-06  6

一、分桶表

1、建表语句

create table test_bucket_sorted (
id int comment 'ID', 
name string comment '名字'
)
comment '测试分桶'
clustered by(id) sorted by (id) into 4 buckets
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' ;

上面建表指定了这张表分为四个桶。

2、原理:hive的分桶就是mapreduce的partition。

(1)原理:当insert插入数据到分桶表时,会把insert的sql转为mapreduce程序处理,而分桶表的桶数就是reducer的数量。

然后使用分桶键作为mapreduce的partition分区键,每条数据的分桶键的hash对桶数求余的值 就是这一条数据所属reducer的索引。

我们知道,每个reducer都会一个文件。所以上面例子中的桶数是四,那么insert插入数据到分桶表后,我们在该表的hdfs目录下可以看到新增了四个文件。。文件命名与reducer的输出文件命名风格一样。

(2)注意:

《1》默认情况下,当插入的数据量不大的时候,是不会分桶的。

然后我测试的数据就只有9条:

[root@hadoopTest ~]# cat data.txt 
1       name1
2       name2
3       name3
4       name4
5       name5
6       name6
7       name7
8       name8
9       name9

先把这些数据放到中间表里,这样才能用insert...select

所以为了测试出效果,我们需要设置属性为强制分桶:set hive.enforce.bucketing=true;

这样的话我们的insert就会分为四个reducer处理了。hdfs输出文件如下:

hive 表分桶标准 hive分桶表创建,hive 表分桶标准 hive分桶表创建_大数据,第1张

如果再次分桶插入数据,那么又会产生四个新文件:

hive 表分桶标准 hive分桶表创建,hive 表分桶标准 hive分桶表创建_大数据_02,第2张

《2》load data方式插入数据是不会分桶的,因为根本不会转为mapreduce程序处理。。

3、分桶表的作用:

方便数据抽样:select * from teacher tablesample(bucket 1 out 3 on name);

注:分桶语法----TABLESAMPLE(BUCKET x OUT OF y)  

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

x表示从哪个bucket开始抽取。

例如:table总bucket数为3,tablesample(bucket 3 out of 3),表示总共抽取(3/3=)1个bucket的数据,抽取第3个bucket的数据。再例如:table总bucket数为32,tablesample(bucket 3 out of 16),表示总共抽取(32/16=)2个bucket的数据,分别为第3个bucket和第(3+16=)19个bucket的数据。

查询第一个桶里数据,并返回一半数据:

select * from teacher tablesample(bucket 1 out of 6 on name);
 

二、分桶且桶内排序(clustered by+sorted by)

sorted by是需要与clustered by一起用的,不能单独用

1、建表

create table test_bucket_sorted (
id int comment 'ID', 
name string comment '名字'
)
comment '测试分桶'
clustered by(id) sorted by (id) into 4 buckets
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ;

2、insert数据

insert数据到该表中所转为的mapreduce程序为:

将会启动与分桶数的相同的reducer任务。 按id进行partition分区,不同数据根据partition分区给不同reducer处理。

然后,同一个reducer处理的数据都会按照sorted by 指定的字段进行排序。

从这里就能够知道,分桶表与分桶排序其实就是在insert数据到该表时,读取到该表设置了分桶与分桶排序,那么就会根据建表的分桶信息设置一个partitioner,然后根据建表的sorted by字段设置reducer阶段的WritableComparator,用于reducer段数据的排序。。

三、分区表

1、建表语句:

create table dept_partition(deptno int, dname string, loc string)
partitioned by (month string)
row format delimited fields terminated by '\t';

2、插入和导入语句

(1)静态分区

insert overwrite table dept_partition partition(month='2015-01-19') select * from test;
load data local inpath '/root/hive/partitions/file1' into table dept_partition
partition (month='2015-01-19');

都是在后面指定要插入或者导入的分区就行。。。"2015-01-19"这个分区是一个文件夹,而文件夹的名字就是2015-01-19。

(2)动态分区

在insert ...select时,使用select 查询出的字段列表中的最后的字段作为分区的key(如果分区字段只有一个,那么就是使用select列表中的最后一个字段,如果分区字段有多个,那么就使用select列表的最后n个字段作为分区key),该字段值相同的数据会放到同一个分区。

#启动动态分区功能
set hive.exec.dynamic.partition=true;  
#允许全部分区都是动态分区
set hive.exec.dynamic.partition.mode=nostrick;
#month_id为静态分区,day_id为动态分区:
insert overwrite table dynamic_test partition(month_id='201710',day_id)  
select c1,c2,c3,c4,c5,c6,c7,day_id from kafka_offset
where substr(day_id,1,6)='201710';

# month_id和 day_id均为动态分区:
insert overwrite table dynamic_test partition(month_id,day_id)  
select c1,c2,c3,c4,c5,c6,c7,substr(day_id,1,6) as month_id,day_id from kafka_offset;

为了让分区列的值相同的数据尽量在同一个mapreduce中,这样每一个mapreduce可以尽量少的产生新的文件夹,可以借助distribute by的功能,将分区列值相同的数据放到一起。

insert overwrite table dynamic_test partition(month_id,day_id)
select c1,c2,c3,c4,c5,c6,c7,substr(day_id,1,6) as month_id,day_id from kafka_offset
distribute by month_id,day_id;

2、原理:

不论insert还是load data,其实都是把数据全部放到该表的目录下的与分区名同名的目录下。。

这样的好处就是:

查询的时候把分区当做一个字段使用,在where条件中指定month='2015-01-19',那么hive在查询数据只就只扫描该分区文件夹下面的数据,其他分区的数据就忽略了。可以提升效率。

四、分区分桶一起用

一起用时,在insert时就要指定分区(或者冬天分区),然后按照分桶规则,在每个分区目录下进行分桶。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!