一.分区表
1.本质
hive存在问题:hive里面没有索引机制,每次查询的时候,hive会暴力扫描整张表;而分区表的本质就是分目录,按照业务需求,把数据分成多个目录存储,然后查询的时候就可以通过where条件指定对应的分区;
2.创建分区表
create table dept_partition(
deptno int, dname string, loc string
)
partitioned by (day string)
row format delimited fields terminated by '\t';
分区字段属于分区表的一个伪列,数据里面并没有记录这列的值,分区字段的值体现在分区目录名上面。
3.加载数据到分区表
方式一:直接手动将数据导入分区目录
load data local inpath '/opt/module/hive/datas/dept_20200401.log' into table dept_partition partition(day='20200401');
方式二:通过动态分区导入,参考9动态分区
4.查看分区
show partitions 表名
5.增加分区
增加一个分区
alter table dept_partition add partition (day='20200629');
增加多个分区
alter table dept_partition add partition(day='20200405') partition(day='20200406');
6.删除分区
删除一个分区
alter table dept_partition drop partition (day='20200629');
删除多个分区
alter table dept_partition drop partition(day='20200405'),partition(day='20200406');
注意:删除多个分区,分区间用‘ , ’逗号分隔;增加多个分区不需要
7.二级分区
其实就是在一级分区下面再创建二级分区的目录
创建二级分区表
创建二级分区表
create table dept_partition2(
deptno int, dname string, loc string
)
partitioned by (day string, hour string)
row format delimited fields terminated by '\t';
加载数据
load data local inpath '/opt/module/hive/datas/dept_20200401.log'
into table dept_partition2
partition(day='20200401',hour='12');
增加分区
alter table dept_partition2 add partition(day='20200403',hour='01') partition(day='20200403',hour = '02');
删除分区
alter table dept_partition2 drop partition(day='20200403',hour='01'),partition(day='20200403',hour = '02');
8.分区表和元数据对应得三种方式
方式一:创建分区目录,上传数据到目录,再修复表
msck repair table dept_partition2;
方式二:创建分区目录,上传数据到目录,再添加对表添加分区
alter table dept_partition2 add partition(day='20200629');
方式三:直接load数据到分区表(常用)
load data inpath '/opt/20200629.log' into table dept_partition partition(day='20200629');
9.动态分区
每次手动上传数据特别麻烦,关系型数据库中,对分区表Insert数据时候,数据库自动会根据分区字段的值,将数据插入到相应的分区中,Hive中也提供了类似的机制,即动态分区(Dynamic Partition),只不过,使用Hive的动态分区,需要进行相应的配置。
1.开启动态分区参数设置
(1)开启动态分区功能(默认true,开启)
hive.exec.dynamic.partition=true
(2)设置为非严格模式(动态分区的模式,默认strict,表示必须指定至少一个分区为静态
分区,nonstrict模式表示允许所有的分区字段都可以使用动态分区。)
hive.exec.dynamic.partition.mode=nonstrict
(3)在所有执行MR的节点上,最大一共可以创建多少个动态分区。默认1000
hive.exec.max.dynamic.partitions=1000
(4)在每个执行MR的节点上,最大可以创建多少个动态分区。该参数需要根据实际的数据来设定。比如:源数据中包含了一年的数据,即day字段有365个值,那么该参数就需要设置成大于365,如果使用默认值100,则会报错。
hive.exec.max.dynamic.partitions.pernode=100
(5)整个MR Job中,最大可以创建多少个HDFS文件。默认100000
hive.exec.max.created.files=100000
(6)当有空分区生成时,是否抛出异常。一般不需要设置。默认false
hive.error.on.empty.partition=false
实操
(1)创建目标分区表
create table dept_partition_dy(id int, name string) partitioned by (loc int) row format delimited fields terminated by '\t';
(2)设置动态分区
set hive.exec.dynamic.partition.mode = nonstrict;
hive (default)> insert into table dept_partition_dy partition(loc) select deptno, dname, loc from dept;
(3)查看目标分区表的分区情况
hive (default)> show partitions dept_partition_dy;
二.分桶表
主要使用分桶进行抽样
1.创建分桶表
create table stu_buck(id int, name string)
clustered by(id)
into 4 buckets
row format delimited fields terminated by '\t';
2.查看分桶表信息
desc formatted stu_buck;
3.开启分桶表
set hive.enforce.bucketing=true;
4.导入数据到分桶表
load data local inpath '/opt/module/hive/datas/student.txt' into table stu_buck;
注意:(hive新版本load数据跑mr,因此要改用hdfs路径导数据)
5.查询分桶表
select * from stu_buck tablesample(bucket 1 out of 16 on id) limit 50;
tablesample
tablesample(bucket x out of y)
x:表示从第几桶开始抽数据(1,2,3,4)
y:表示抽数据的比例,是抽数据的分母
比如: 有4个分桶
tablesample(bucket 1 out of 16) 表示从第一桶开始抽数据,抽取第一桶数据的比例为(4(桶数)/16(分母))=1/4,抽取第一桶四分之一的数据
tablesample(bucket 2 out of 32) 表示从第二桶开始抽数据,抽取第二桶数据的比例为(4(桶数)/32(分母))=1/8,抽取第一桶八分
分桶规则
根据结果可知:Hive的分桶采用对分桶字段的值进行哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中