一 为什么表数据要分区管理
1 hive 中的数据是存储在对应的表的目录下的
2 查询数据的时候加载目录下的所有的文件 ,where 筛选过滤
3 日志数据可能每天都会有所增加,每天都有大量的文件 ,如每天的操作数据 ;
2018-09-02.log.....
2018-09-01.log.....
2018-08-31.log.....
4 为了对数据进行更好的管理,也为了在查询的时候增加查询速度,增加查询效率 ,需要对日志数据进行分区处理 ,也就是让静态文件根据一定的规则分文件夹来管理 ,查询的时候,只要根据文件夹去检索,可以减少很大的查询/检索工作 ,所以可以增加检索/查询数据的速度.
5 如果文件没有分文件夹管理 ,而是将所有文件都放在一个大的文件夹里面的话 ,那检索的时候就需要在这个大的文件夹里面从头开始一个一个的检索,因为没有确定的位置 ,所有检索工作量非常大,导致查询速度慢,效率低 ,当时如果根据日期来进行分文件夹来管理 ,比如查询 select * from tb_log where dt = '2018-09-02'时,就可以根据表目录,直接找到 09月 02日的文件夹然后查询,大大减少了查询工作量,因为有确定的位置信息,所以检索速度快,效率也高 ,分区格式如下 :
表目录如下 :
2018-09-01目录
01号的日志
01号的日志
01号的日志
2018-09-02目录
02号的日志
02号的日志
02号的日志
02号的日志
特点 : 有固定的数据存储 , 分文件存储
二 创建静态分区表
1 数据的处理
1.1 将不同日期不同后缀的文件分开存储插入到本地 /root/hive/datalog/ 目录下 ,生成静态文件
[root@linux03 datelog]# vi 2018-08-31_01.log
[root@linux03 datelog]# vi 2018-08-31_02.log
[root@linux03 datelog]# vi 2018-09-01_01.log
[root@linux03 datelog]# vi 2018-09-01_02.log
[root@linux03 datelog]# vi 2018-09-02_01.log
[root@linux03 datelog]# vi 2018-09-02_02.log
1.2 查看文件插入情况
[root@linux03 datelog]# ll
-rw-r--r--. 1 root root 75 Sep 2 23:12 2018-08-31_01.log ---> a
-rw-r--r--. 1 root root 75 Sep 2 23:12 2018-08-31_02.log----> b
-rw-r--r--. 1 root root 75 Sep 2 23:11 2018-09-01_01.log---> a
-rw-r--r--. 1 root root 75 Sep 2 23:11 2018-09-01_02.log----> b
-rw-r--r--. 1 root root 75 Sep 2 23:10 2018-09-02_01.log---> a
-rw-r--r--. 1 root root 75 Sep 2 23:10 2018-09-02_02.log----> b
2 创建一级静态分区表,按照日期进行分区管理
分区表实际上就是对应一个 HDFS 文件系统上的独立的文件夹 ,该文件夹下是该分区所有的数据文件 .Hive 中的分区就是分目录 ,
把一个大的数据集根据业务需要分割成小的数据集 .在查询时通过 where 子句中的表达式选择查询所需要的指定字段的分区 ,这样
的查询效率会提高很多 .
2.1 创建表并加载数据
1 创建静态一级分区表
create table tb_static_partition1(
id int,
ctime string,
name string)
partitioned by (dayt string) -------------------按照 "dayt"日期中的天来分区
row format delimited fields terminated by ",";
2 加载文件到刚刚创建的表里面 ---------指定分区内容
load data local inpath "/root/hive/datelog/2020-09-02_01.log" into table tb_static_partition1 partition(dayt="2018-09-02");
load data local inpath "/root/hive/datelog/2020-09-02_02.log" into table tb_static_partition1 partition(dayt="2018-09-02");
load data local inpath "/root/hive/datelog/2020-09-01_01.log" into table tb_static_partition1 partition(dayt="2018-09-01");
load data local inpath "/root/hive/datelog/2020-09-01_02.log" into table tb_static_partition1 partition(dayt="2018-09-01");
load data local inpath "/root/hive/datelog/2020-08-31_01.log" into table tb_static_partition1 partition(dayt="2018-08-31");
load data local inpath "/root/hive/datelog/2020-08-31_02.log" into table tb_static_partition1 partition(dayt="2018-08-31");
2.2 查看数据插入
1 查看文件加载后数据插入情况----------------hive 交互窗口上---------
0: jdbc:hive2://linux03:10000> select * from tb_static_partition1 ;
+--------------------------+-----------------------------+----------------------------+----------------------------+
| tb_static_partition1.id | tb_static_partition1.ctime | tb_static_partition1.name | tb_static_partition1.dayt |
+--------------------------+-----------------------------+----------------------------+----------------------------+
| 1 | 2018-08-31 | a | 2018-08-31 |
| 2 | 2018-08-31 | a | 2018-08-31 |
| 3 | 2018-08-31 | a | 2018-08-31 |
| 4 | 2018-08-31 | a | 2018-08-31 |
| 5 | 2018-08-31 | a | 2018-08-31 |
| 1 | 2018-08-31 | b | 2018-08-31 |
| 2 | 2018-08-31 | b | 2018-08-31 |
| 3 | 2018-08-31 | b | 2018-08-31 |
| 4 | 2018-08-31 | b | 2018-09-01 |
| 5 | 2018-08-31 | b | 2018-09-01 |
| 1 | 2018-09-01 | a | 2018-09-01 |
| 2 | 2018-09-01 | a | 2018-09-01 |
| 3 | 2018-09-01 | a | 2018-09-01 |
| 4 | 2018-09-01 | a | 2018-09-01 |
| 5 | 2018-09-01 | a | 2018-09-01 |
| 1 | 2018-09-01 | b | 2018-09-01 |
| 2 | 2018-09-01 | b | 2018-09-01 |
| 3 | 2018-09-01 | b | 2018-09-01 |
| 4 | 2018-09-01 | b | 2018-09-01 |
| 5 | 2018-09-01 | b | 2018-09-01 |
| 1 | 2018-09-02 | a | 2018-09-02 |
| 2 | 2018-09-02 | a | 2018-09-02 |
| 3 | 2018-09-02 | a | 2018-09-02 |
| 4 | 2018-09-02 | a | 2018-09-02 |
| 5 | 2018-09-02 | a | 2018-09-02 |
| 1 | 2018-09-02 | b | 2018-09-02 |
| 2 | 2018-09-02 | b | 2018-09-02 |
| 3 | 2018-09-02 | b | 2018-09-02 |
| 4 | 2018-09-02 | b | 2018-09-02 |
| 5 | 2018-09-02 | b | 2018-09-02 |
+--------------------------+-----------------------------+----------------------------+----------------------------+
2.3 查看数据分区后存储情况-------hdfs web上查看
1 在 hdfs web 端查看数据分区情况
/user/hive/warehouse/tb_static_partition1/dayt=2018-08-31/2018-08-31_01.log
/user/hive/warehouse/tb_static_partition1/dayt=2018-08-31/2018-08-31_02.log
/user/hive/warehouse/tb_static_partition1/dayt=2018-09-01/2018-09-01_01.log
/user/hive/warehouse/tb_static_partition1/dayt=2018-09-01/2018-09-01_02.log
/user/hive/warehouse/tb_static_partition1/dayt=2018-09-02/2018-09-02_01.log
/user/hive/warehouse/tb_static_partition1/dayt=2018-09-02/2018-09-02_02.log
3 创建静态二级分区 ,按照 月 /日 进行分区管理
3.1 创建表并加载数据
1 创建静态二级分区
create table tb_static_partition2(
id int,
ctime string,
name string)
partitioned by(montht string,dayt string)
row format delimited fields terminated by ",";
2 加载数据到刚刚创建的表里面
load data local inpath "/root/hive/datelog/2018-09-02_01.log" into table tb_static_partition2 partition(montht="09",dayt="02");
load data local inpath "/root/hive/datelog/2018-09-02_02.log" into table tb_static_partition2 partition(montht="09",dayt="02");
load data local inpath "/root/hive/datelog/2018-09-01_01.log" into table tb_static_partition2 partition(montht="09",dayt="01");
load data local inpath "/root/hive/datelog/2018-09-01_02.log" into table tb_static_partition2 partition(montht="09",dayt="01");
load data local inpath "/root/hive/datelog/2018-08-31_01.log" into table tb_static_partition2 partition(montht="08",dayt="31");
load data local inpath "/root/hive/datelog/2018-08-31_02.log" into table tb_static_partition2 partition(montht="08",dayt="31");
3.2 查看数据分区后存储情况-------hdfs web上查看
/user/hive/warehouse/tb_static_partition2/montht=09/ ---->不同月份被放在不同文件夹中
dayt=01/ ----->同一个月不同天被放在不同文件夹中
2018-09-01_01.log ---->同一天,当时文件内容不同/用户不同被分为不同文件存储
2018-09-01_02.log
dayt=02/
2018-09-02_01.log
2018-09-02_02.log
/user/hive/warehouse/tb_static_partition2/montht=08/
dayt=31/
2018-08-31_01.log
2018-08-31_02.log
4 创建静态三级分区 ,按照 年 /月 /日 进行分区
4.1 创建表并加载数据
1 创建静态三级分区表 ,按照 年 /月 /日 分区在不同文件夹上管理数据
create table tb_static_partition2(
id int,
ctime string,
name string)
partitioned by(yt string,mt string,dt string)
row format delimited fields terminated by ",";
2 将数据加载到刚刚创建的三级分区表里面
load data local inpath "/root/hive/datelog/2018-09-02_01.log" into table tb_static_partition2 partition(yt="2018",mt="09",dt="02");
load data local inpath "/root/hive/datelog/2018-09-02_02.log" into table tb_static_partition2 partition(yt="2018",mt="09",dt="02");
load data local inpath "/root/hive/datelog/2018-09-01_01.log" into table tb_static_partition2 partition(yt="2018",mt="09",dt="01");
load data local inpath "/root/hive/datelog/2018-09-01_02.log" into table tb_static_partition2 partition(yt="2018",mt="09",dt="01");
load data local inpath "/root/hive/datelog/2018-08-31_01.log" into table tb_static_partition2 partition(yt="2018",mt="08",dt="31");
load data local inpath "/root/hive/datelog/2018-08-31_02.log" into table tb_static_partition2 partition(yt="2018",mt="08",dt="31");
4.2 查看数据分区后存储情况-------hdfs web上查看
/user/hive/warehouse/tb_static_partition2/yt=2020 -----不同年份会被分在不同的文件中
mt=09/ ---->不同月份被放在不同文件夹中
dt=01/ ----->同一个月不同天被放在不同文件夹中
2020-09-01_01.log ---->同一天,当时文件内容不同/用户不同被分为不同文件存储
2020-09-01_02.log
dt=02/ ----->同一个月不同天被放在不同文件夹中
2020-09-02_01.log
2020-09-02_02.log
mt=08/ ---->不同月份被放在不同文件夹中
dt=31/
2020-08-31_01.log
2020-08-31_02.log
三 创建动态分区表
1 分区规则 :
1) 按照某个字段自动的将数据加载到指定的分区中
2) 数据在文件中 ,向按照某个字段进行分区 ,比如按照地域等
2 创建动态分区表的步骤 :
1) 创建普通的表
2) 向创建的普通表里面 load/加载 数据
3) 创建分区表
4) 开启动态分区
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrick;5) 将普通表查询结果插入到动态分区表中 :
insert into partition(address) select id,name,address from 普通表;
3 创建动态分区表
3.1 在本地 /root/hive/ 目录下创建 address.txt 文件 ,将结构化数据插入到文件中 ,生成静态文件
1 数据源
1,lixian,BeiJing
2,linchen,NanJing
3,lichun,XiJing
4,cls,DongleJing
5,hls,DongleJing
6,sls,DongleJing
2 在本地 /root/hive/ 目录下创建文件,将数据插入进去生成静态文件
[root@linux03 hive]# vi address.txt
[root@linux03 hive]# ll
-rw-r--r--. 1 root root 103 Sep 6 04:35 address.txt
3.2 创建普通表 ,将静态文件加载到普通表里面 ,然后查看插入情况
1 创建普通表
drop table tb_addr;
create table tb_addr(
id int,
name string,
address string)
row format delimited fields terminated by ",";
2 并加载数据
load data local inpath "/root/hive/address.txt" into table tb_addr;
3 查看数据加载导入情况
0: jdbc:hive2://linux03:10000> select * from tb_addr;
+-------------+---------------+------------------+
| tb_addr.id | tb_addr.name | tb_addr.address |
+-------------+---------------+------------------+
| 1 | lixian | BeiJing |
| 2 | linchen | NanJing |
| 3 | lichun | XiJing |
| 4 | cls | DongleJing |
| 5 | hls | DongleJing |
| 6 | sls | DongleJing |
+-------------+---------------+------------------+
3.3 创建动态分区表
drop table tb_addr_dynamic_partition;
create table tb_addr_dynamic_partition(
id int,
name string,
address string
)
partitioned by(addr string);
3.4 开启动态分区
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrick;
3.5 将普通表中查询的结果插入到开启了动态分区的表里面
insert into table tb_addr_dynamic_partition partition(addr)
select id,name,address ,address
from
tb_addr;
前三个字段是动态表与普通表一一对应的字段 ,最后这个address字段作为分区使用 from 过滤
3.6 查看动态分区表里面的数据情况
0: jdbc:hive2://linux03:10000> select * from tb_addr_dynamic_partition;
+------------------+------------+---------------+-----------------+
| 动态分区表名.id | 表名.name | 表名.address | 表名.addr |
+-------------------------------+---------------------------------+
| 1 | lixian | BeiJing | BeiJing |
| 5 | hls | DongleJing | DongleJing |
| 6 | sls | DongleJing | DongleJing |
| 4 | cls | DongleJing | DongleJing |
| 2 | linchen | NanJing | NanJing |
| 3 | lichun | XiJing | XiJing |
+------------------+------------+---------------+-----------------+
3.7 设置参数
设置参数
set hive.exec.dynamic.partition=true //使用动态分区
set hive.exec.dynamic.partition.mode=nonstrick;//无限制模式,如果模式是strict,则必须有一个静态分区且放在最前面
set hive.exec.max.dynamic.partitions.pernode=10000;//每个节点生成动态分区的最大个数
set hive.exec.max.dynamic.partitions=100000;//生成动态分区的最大个数
set hive.exec.max.created.files=150000;//一个任务最多可以创建的文件数目
set dfs.datanode.max.xcievers=8192;//限定一次最多打开的文件数
set hive.merge.mapfiles=true; //map端的结果进行合并
set mapred.reduce.tasks =20000; //设置reduce task个数
四 修改表
1 重命名表
alter table tb_name rename to new_table_name;
2 增加 / 修改 / 删除表分区
alter table tb_name add partition(month='201808'); 创建单个分区
alter table tb_name add partition(month='201808') partition (month='201809'); 同时创建多个分区
alter table tb_name drop partition(month='201807'); 删除单个分区
alter table tb_name drop partition(month='201802') partition(month='201803'); 删除多个分区
show partition tb_name; 查看分区表有多少个分区
desc formatted tb_name; 查看分区表结构
3 增加 / 修改 / 替换列信息
desc formatted tb_name; 查询表结构
alter table tb_name change column deptdesc desc int; 更新列
alter table tb_name add columns(deptdesc string); 添加列
alter table tb_name replace columns(deptno string, dname string, loc string); 替换列
4 删除表
drop table tb_name;