Hadoop之Hive的分区表

Posted 柳小葱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hadoop之Hive的分区表相关的知识,希望对你有一定的参考价值。

🍦前几天的课程我们学习了Hive数据的导入、导出、查询和排序,有兴趣的小伙伴可以查看以往的文章👇:

❗️❗️❗️ 今天要介绍的内容在Hive中非常重要,即分区表

1.分区表

分区表实际上就是对应一个 HDFS 文件系统上的独立的文件夹,该文件夹下是该分区所有的数据文件。Hive 中的分区就是分目录,把一个大的数据集根据业务需要分割成小的数据集。在查询时通过 WHERE 子句中的表达式选择查询所需要的指定的分区,这样的查询效率会提高很多。

1.1 分区表的建立

  • 引入分区表(一般情况下,企业中的分区表都是以时间作为分区的)

我们首先建立三个分区表内所需要的文件

--dept1.txt
10	ACCOUNTING	1700
20	RESEARCH	1800
--dept2.txt
30	SALES	1900
40	OPERATIONS	1700
--dept3.txt
50	TEST	2000
60	DEV	1900

创建成功
在这里插入图片描述

  • 创建分区表
create table dept_par(deptno int, dname string, loc string)
partitioned by (day string)--分区表特有
row format delimited fields terminated by '\\t';

在这里插入图片描述

  • 各分区表导入数据
--第一天添加
load data local inpath '/opt/modul/datatest/dept1.txt' 
into table dept_par 
partition(day="2021-05-01");--指定分区目录
--第二天添加
load data local inpath '/opt/modul/datatest/dept2.txt' 
into table dept_par 
partition(day="2021-05-02");
--第三天添加
load data local inpath '/opt/modul/datatest/dept3.txt' 
into table dept_par 
partition(day="2021-05-03");

都按这种方式导入
在这里插入图片描述
我们在web服务上看一下数据:我们发现分区表可以理解为在数据表中创建了文件夹来管理数据。
在这里插入图片描述
分区信息也是数据的一个字段,用法和普通属性用法一样。
在这里插入图片描述
例如查询某天的数据

select * from dept_par where day="2021-05-01";

查询分区信息超级快!因为分区表就相当于目录,可以避免全表扫描。
在这里插入图片描述

1.2 查询分区表中数据

刚才其实演示过了,分区查询就相当于属性就行

--单分区查询
select * from dept_par where day="2021-05-01";
--多个分区查询
select * from dept_par where day="2021-05-01"
union
select * from dept_par where day="2021-05-02"
union
select * from dept_par where day="2021-05-03"
--多表分区的另一种写法
select * from dept_par where day="2021-05-01" or day="2021-05-02" or day="2021-05-03";

结果如下:
在这里插入图片描述

1.3 增加分区

也是使用alter…add…语句,需要添加多个分区时需要用空格隔开。

--添加一个分区
alter table dept_par add partition(day='2021-05-04');
--添加多个分区
alter table dept_par add partition(day='2021-05-04') partition(day='2021-05-05');

添加分区成功,但是里面没有数据。
在这里插入图片描述

1.4 删除分区

删除分区用alter…drop…语句,删除多个分区时需要用逗号隔开(吐槽它😟)

--删除一个
alter tabel dept_par drop partition(day='2021-05-04');
--删除多个分区
alter table dept_par drop partition(day='2021-05-04'),partition(day='2021-05-05');

删除成功。
在这里插入图片描述

1.5 查看分区

show partitions dept_par;

在这里插入图片描述

1.6 查看分区表结构

desc formatted dept_partition;

在这里插入图片描述

2. 二级分区

上一章节讲述了我们将天为单位进行分区,可如果按天分区数据量依然很大,我们这时就需要按照更小的范围分区,比如小时。

2.1 建立二级分区分区

--创建二级分区表
create table dept_par2(deptno int, dname string, loc string) 
partitioned by (day string,hour string) 
row format delimited fields terminated by '\\t';
  • 导入数据
load data local inpath '/opt/modul/datatest/dept3.txt' 
into table dept_par2
partition(day="2021-05-02",hour='12');--指定二级分区信息

创建成功
在这里插入图片描述

2.2 查询二级分区

这里查询也是将分区信息当成属性即可

--查询所有信息
select * from dept_par2;
--查询某天的信息
select * from dept_par2 where day='2021-05-01';
--查询某天某时的信息
select * from dept_par2 where day='2021-05-01' and hour='12';

结果:
在这里插入图片描述

3. HDFS数据与分区表关联的方法

在最开始的普通数据库建表语句中我们说过,数据是存在HDFS上面的,也就是说,如果通过hdfs命令直接在文件夹先存数据,后建表,都是可以查询到的,但是分区表也是这样的吗?
我们试一试:我们在分区表中建立一个day="2021-05-04"的目录,里面给他数据dept1.txt

#创建一个类似分区表的文件夹
hadoop fs -mkdir /user/hive/warehouse/dept_par/day=2021-05-04
#给他数据
hadoop fs -put dept1.txt /user/hive/warehouse/dept_par/day=2021-05-04

结果如下:
在这里插入图片描述
然后我们用语句查询一下:发现找不2021-05-04的数据!!!
在这里插入图片描述
说明元数据中对分区表也有数据的存储,我们应该怎么样才能将我们自建的目录统一到元数据中呢?

3.1 修复分区

  • 通过修复分区
--修复分区命令,该命令会匹配分区数据表,补充元数据。
msck repair table dept_par;

修复完成后,成功找到。
在这里插入图片描述

3.2 添加分区

我们在hdfs上再创建目录day=2021-05-05

#创建一个类似分区表的文件夹
hadoop fs -mkdir /user/hive/warehouse/dept_par/day=2021-05-05
#给他数据
hadoop fs -put dept2.txt /user/hive/warehouse/dept_par/day=2021-05-05
  • 添加分区
--添加对应分区
alter table dept_par add partition(day="2021-05-05");

结果如下:
在这里插入图片描述

3.3 创建文件夹后load数据

我们可以事先创建文件夹后,然后再使用load数据

-- 创建文件夹
hadoop fs -mkdir /user/hive/warehouse/dept_par/day=2021-05-06
  • load数据
--数据只能load方式,才会添加元数据
load data local inpath 
'/opt/modul/datatest/dept3.txt' 
into table dept_par 
partition(day="2021-05-06");

4. 动态分区

动态分区是指分区标准不确定,想依据表中的某个字段进行分区。例如,根据dept表中的deptno进行分区
在这里插入图片描述

  • 创建分区表
--首先我们创建一个分区表
create table dept_no_par(dname string, loc string)
partitioned by (deptno int)
row format delimited fields terminated by '\\t';
  • 传递数据
--动态分区会默认将最后一个字段名(deptno)作为分区标准
insert into table dept_no_par 
partition(deptno)
select dname,loc,deptno from dept;
--也可以这样,这种不需要改严格模式
insert into table dept_no_par 
select dname,loc,deptno from dept;

提示动态分区要在非严格模式
在这里插入图片描述

  • 设置非严格模式
set hive.exec.dynamic.partition.mode=nonstrict;
  • 再此执行,结果如下:分区成功。
    在这里插入图片描述

参考资料

《大数据Hadoop3.X分布式处理实战》

以上是关于Hadoop之Hive的分区表的主要内容,如果未能解决你的问题,请参考以下文章

Hadoop之Hive分桶表

从 spark(2.11) 数据帧写入 hive 分区表时出现 org.apache.hadoop.hive.ql.metadata.Hive.loadDynamicPartitions 异常

HADOOP-HIVE分区,桶,倾斜概念

hadoop离线day09--Apache Hive

hadoop离线day09--Apache Hive

hive归档分区