Hive介绍
hive是基于 Hadoop平台操作 HDFS 文件的插件工具
可以将结构化的数据文件映射为一张数据库表
可以将 HQL 语句转换为 MapReduce 程序
1.hive 是由驱动器组成,驱动器主要由4个组件组成(解析器、编译器、优化器、执行器)
2.hive本身不存储数据,数据是存储在hdfs上
3.hive的元数据默认是存储在detby数据库中,但是它支持一个客户端进行连接,为了支持多客户端连接,可将元数据存储在关系型数据库中(如mysql)
4.hive本身不参与数据计算,数据计算交由计算引擎,hive支持的计算引擎由3种(MapReduce默认、Tez、Spark )
库
Hive的数据都是存储在 hdfs 上的,默认有一个根目录。由文件 hive-site.xml 中的参数是hive.metastore.warehouse.dir指定。默认为 /user/hive/warehouse
比如名为itcast的数据库存储路径为:/user/hive/warehouse/itcast.db
表
表所对应的数据是存储 在HDFS上的,而表相关的元数据是存储在关系型数据库中
hive有两种类型的表:内部表(默认表)和外部表
1.内部表:在创建表的时候没有设置external关键字,则创建的是一张内部表
表结构中:table_type:managed_table
特点:在删除表的时候,不光删除表结构,会同步将hdfs上对应的文件夹一起删除。
使用场景:由于内部表在删除表的时候会将数据文件同步删除,所以在实际的工作中,一些核心表是不会采用内部表,
如果要临时保存一些数据,或者是一些临时的计算结果则可以使用内部表
2.外部表:在创建表的时候指定了external关键字,则创建的属于一张外部表
表结构中:table_type:external_table
特点:在删除表的时候,只删除表结构,不会删除hdfs上对应的文件夹
使用场景:在实际的工作中,绝大部分的表都会采用的是外部表。
修改外部表emp为内部表(emp为表名)
alter table emp set tblproperties ('EXTERNAL'='FALSE');
修改内部表emp为外部表
alter table emp set tblproperties ('EXTERNAL'='TRUE');
内部表和外部表之间允许相互转换
语法:alter table 表名 set tblproperties('EXTERNAL'='FALSE|TRUE')
EXTERNAL=FALSE:代表设置为内部表
EXTERNAL=TRUE:代表设置为外部表
如果要删除外部表的数据文件方式:
1.先将表结构转换成内部表,然后删除内部表
2.先删除表结构,然后使用hdfs的命令来删除:hdfs dfs -rm -r 文件地址
分区
分区是hive的一种优化手段。分区是指根据表的字段(例如“日期day”)将表划分为不同分区
一个分区表示一个文件夹
分区:将一个大的文件夹进行拆分
分桶:将一个大的文件进行分桶
hive 静态分区
静态分区
指的是分区字段值在加载数据时,是由用户手动指定的
创建分区表
(1)关键语句:
partitioned by (field string)
(2)分区字段不能是表中已经存在
的字段
(3)分区字段是虚拟字段,其数据并不存储在底层的文件中
(4)分区不同,对应数据存放的文件夹不同
静态分区:手工分区,分区的名称和分区额数据都是用户来直接添加,并且一次只能向一个分区中添加数据。
添加数据的方式:
1.load data [local] inpath '文件地址' into table 表名 partition(分区列名=值)
--静态分区数据加载
load data local inpath '/root/EMP.txt' into table emp_partition partition (deptno=20);
2.insert into|overwrite table 表名 partition(分区列名=值) select 列名,列名,....from 表;
如果是静态分区加载数据,使用insert into则查询出来的数据中不能包含分区列的值。
~单分区查询
select * from emp_partition where dept=20;
~多分区查询
select * from emp_partition where dept=20
union
select * from emp_partition where dept=30
增加分区
alter table emp_partitionadd partition(dept=40);
hive msck 修复分区
dfs -mkdir -p /user/hive/warehouse/emp_partition/dept=50;
1.上传数据到分区
dfs -put /opt/modules/input/emp.txt /user/hive/warehouse/emp_partition/dept=50;
2.查询数据
select * from emp_partition where dept=50;
3.修复关系:
msck repair table emp_partition;
删除分区数据
-- 这将删除该分区的数据和元数据
alter table emp_partition drop partition(dept=50);
- 删除多个分区
alter table dept_partition drop partition ( month = '2021-02-11' ), partition(month = '2021-02-12');
alter table dept_partition drop partition ( month <= '2021-02-12' );
重命名分区表名
-- dept_partition 旧表名 ---> dept_partition2 是新表名
alter table emp_partition rename to emp_partition2;
更改分区文件存储格式
alter table table_name partition (dt='2008-08-09') set fileformat file_format;
更改分区位置
alter table table_name partition (dt='2008-08-09') set location "new location";
hive 动态分区
动态分区
指的是分区的字段值是基于查询结果自动推断出来的。要借助核心语法(
insert+select)
开启动态分区功能(默认 true,开启)
hive (default)> set hive.exec.dynamic.partition=true;
设置为非严格模式
- 动态分区的模式,默认 strict,表示必须指定至少一个分区为静态分区
- nonstrict 模式表示允许所有的分区字段都可以使用动态分区
hive (default)>set hive.exec.dynamic.partition.mode=nonstrict;
1.创建分区表
create table dept_par
(
deptno string, -- 部门编号
dname string -- 部门名
)
partitioned by (change_dt string) -- 部门改头换面日期
row format delimited fields terminated by '\t';
2、从 表dept 中查询数据,动态插入到 表dept_par 的不同分区中
insert into table dept_par partition (change_dt)
select deptno ,
dname ,
change_dt
from dept;
① 从表dept 中查询出 列deptno,列dname 中的数据,然后插入到 表dept_par 中
② 再从 表dept 中 查询出 列change_dt,让这一列作为 表dept_par 的分区字段
Hive 分桶
分桶表 分区表 区别与联系
分区针对的是数据的存储路径
(分区是根据表的某一列得到的,分区不同,HDFS上的文件夹不同);分桶针对的是数据文件
(分桶是根据表的某一列下数据值,经hash取余得到的)
分区字段不能是
表中已经存在的字段;分桶的字段必须是
表中已经存在的字段
2者都是hive的一种优化手段,为了提高查询效率
设置分桶
create [external] table 表名(
列名,......
)partitioned by (....)
clustered by (分桶列) into n buckets
......
注意:1.分桶的列是从表中的列中选出来一个作为分桶列,不需要单独定义。
2.n代表数字,表示要分的桶的数量
3.在加载数据的时候如果没有设置redu