Hive(六)【分区表、分桶表】

一.分区表

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 '	';

分区字段属于分区表的一个伪列,数据里面并没有记录这列的值,分区字段的值体现在分区目录名上面。

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 '	';

加载数据

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 '	';

(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 '	';

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的分桶采用对分桶字段的值进行哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中

原文地址:https://www.cnblogs.com/wh984763176/p/13209890.html