创建分区表之前的数据准备: 先创建好dept1.txt dept2.txt dept3.txt 然后存入数据: 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_partition(
> deptno int, dname string, loc string)
> partitioned by (day string)
> row format delimited fields terminated by ',';
依次加载数据存入到表中。
load data local inpath '/opt/module/data/dept1.txt' into table dept_par partition(day='2021-9-28');
load data local inpath '/opt/module/data/dept2.txt' into table dept_par partition(day='2021-9-29');
load data local inpath '/opt/module/data/dept3.txt' into table dept_par partition(day='2021-9-30');
为什么要建立分区:
比如我们有100万条数据,分别属于十天中的某一天,而每当我们想要取出某一天的数据的时候,表中的数据没有分区那么我们在查询的时候就会完全遍历这100万条数据,做的无用功太多了、太消耗时间了。而当我们创建了分区之后我们只需要在查询的时候写入我们想要查询哪个分区的数据,在这里也就是哪一天的数据,就能直接去相对应的分区将数据精确的取出,减少了无用的查询,大大的提高了效率、节约了时间。
查询语句:
单分区查询:
select * from dept_par where day='2021-9-28';
也可以多分区联合查询: 一、
select * from dept_par where day='2021-9-28'
union
select * from dept_par where day='2021-9-29';
二、(全表查询)
select * from dept_par where day='2021-9-29' or day='2021-9-28';
查询结果:
添加分区:
添加单个分区:
alter table dept_par add partition(day='2021-9-25') ;
添加多个分区: 每个partition之间存在一个空格隔开。
alter table dept_par add partition(day='2021-9-25') partition(day='2021-9-26') partition(day='2021-9-27');
删除分区
删除单个分区:
alter table dept_par drop partition(day='2021-9-25');
删除多个分区: 这里需要注意与添加多个分区不同的是每个partition之间隔开的不是空格而是逗号。
alter table dept_par drop partition(day='2021-9-26'),partition(day='2021-9-27');
二级分区
创建dept_par2表:
create table dept_par2(dept int, dname string, loc string)
partitioned by (day string, hour string)
row format delimited fields terminated by ',';
加载数据:
load data local inpath '/opt/module/data/dept1.txt' into table dept_par2 partition(day='2021-9-28',hour='11');
load data local inpath '/opt/module/data/dept2.txt' into table dept_par2 partition(day='2021-9-28',hour='12');
load data local inpath '/opt/module/data/dept3.txt' into table dept_par2 partition(day='2021-9-29',hour='11');
数据查询:
select * from dept_par2;
select * from dept_par2 where day='2021-9-28';
select * from dept_par2 where day='2021-9-28' and hour = '11';
使HDFS数据与分区表产生联系的方式
方法一:上传数据后修复
现在hdfs中创建好路径:
hadoop fs -mkdir /user/hive/warehouse/dept_par/day=2021-10-1
向hdfs上的路径存储数据:
hadoop fs -put dept1.txt /user/hive/warehouse/dept_par/day=2021-10-1
先查询一下看看会不会出现我们存入的数据:
select * from dept_par;
发现查询出的结果依然为表中原有的数据并没有出现我们刚添加的数据 。 查询一下当前dept_par表的分区是否有我们刚刚创建的。
show partitions dept_par;
发现我们刚才以刚才的方式创建的分区是不可用的。 那么我们需要对表进行修复操作来达到我们的目的,也就是HDFS与分区表产生联系。 修复操作会根据HDFS中的目录信息把MySql中的元数据信息进行补充,比如在修复的时候会发现HDFS中有一个day='2021-10-1’的分区在MySql的元数据中不存在,就会进行修复操作。
msck repair table dept_par;
显示已经添加了day='2021-10-1’的分区。 然后我们检查dept_par包含的分区: 分区已经修复完成。 然后我们再查询dept_par的数据,看我们上传的数据是否已经存在于表中。 蓝框中为我们最开始想添加的分区中的数据,现已成功添加。
方法二:上传数据后添加分区
在HDFS中创建新的目录
hadoop fs -mkdir /user/hive/warehouse/dept_par/day=2021-10-2
向HDFS中放入数据:
hadoop fs -put dept1.txt /user/hive/warehouse/dept_par/day=2021-10-2
我们再次查询dept_par表中的数据,依然会发现我们刚上传的数据查询不到。 我们执行添加分区的操作:
alter table dept_par add partition(day='2021-10-2');
然后我们再查询数据,我们刚才上传的数据能够被查询出。
动态分区
创建一个新的 dept_no_par表:
create table dept_no_par(dname string, loc string)
partitioned by (deptno int)
row format delimited fields terminated by ',';
先进行一下设置:
导入数据:
insert into table dept_no_par partition(deptno)
select dname,loc,deptno from dept;
注:在所有执行MR的节点上,最大可创建1000个分区。 整个MRjob中最多能创建100000个文件
|