
1)用户接口:Client
2)元数据:Metastore (hive和HDFS之间的映射关系),包括:表名、表所属的数据库、字段等
· 元数据将hive中的表和HDFS中的路径做一个映射。
· 默认存储在自带的 derby 数据库(erby默认只能单用户)中,推荐使用 MySQL 存储 Metastore;
3)Hadoop
使用 HDFS 进行存储,使用 MapReduce 进行计算。
4)驱动器:Driver ★
(1)解析器:将 SQL 转换成MR的任务需要的对应的元数据等准备工作;
(2)编译器:进一步生成逻辑执行计划(MR任务的执行流程)。
(3)优化器:对逻辑执行计划进行优化。如果直接根据SQL生成执行计划的化,效率可能不高。
(4)执行器:真正触发MR任务的执行。把逻辑执行计划转换成可以运行的物理计划。对于 Hive 来 说,就是 MR/Spark。
用户输入SQL语句给hive:
hive根据映射信息(元数据)找到对应的HDFS的路径上的数据,
hive经过Driver(解析器、编译器、优化器、执行器),将这些指令翻译成 MR程序,提交到 Yarn上执行;
最后返回结果。
Hive和数据库除了拥有类型的查询语言外,无其他相似
存储位置:Hive数据存储在HDFS上。数据库保存在块设备或本地文件系统
数据操作:Hive一般不改、删(数据量太大,只做增、查),而数据库通常需要经常修改
执行引擎:Hive通过MapReduce来实现。数据库用自己的执行引擎
执行速度:Hive没有索引 !需要扫描整个表,执行延迟高,但它数据规模远超过数据库处理能力时,Hive的并行计算能力就体现优势了。数据库执行延迟较低
数据规模:hive大规模的数据计算。数据库能支持的数据规模较小
因为默认derby中时只能打开一个hive客户端,而放在MySQL可以同时打开多个客户端。
管理:外部表数据由HDFS管理;内部表数据由hive自身管理
存储:外部表数据存储位置由自己指定(没有指定location则在默认地址下新建);内部表数据存储在hive.metastore.warehouse.dir(默认在/uer/hive/warehouse)
创建:被external修饰的就是外部表;没被修饰默认是内部表
删除:删除内部表会删除元数据和存储数据;删除外部表仅仅删除元数据,HDFS路径下的文件依然还在,即外部表更安全;
场景:如果一个表不止hive使用,被共享的情况下用外部表,外部表用的的较多;
临时表,中间表用内部表,内部表用的较少。
可以修改内部表为外部表:
alter table 表名 set tblproperties ('EXTERNAL'='TRUE'); // true即外部表,false为内部表
向表中装载数据(load)
load data local inpath ‘test.txt’ into table test04;
如果是HDFS上就不加local
通过查询语句向表中插入数据(Insert)
insert into /overwrite table student select * from emp;
将sql写入脚本文件,在hive外部运行脚本(-e 命令行 -f 文件)
bin/hive -f bjpowernode.txt
将查询的结果导出到本地
insert overwrite local directory '/opt/module/hive/data/export/student ’ select * from student;
将查询的结果导出到HDFS
insert overwrite directory ‘/test5’ ----------- // HDFS上就不写local!
row format delimited
fields terminated by ‘\t’
select * from teacher;
用HDFS命令导出到本地
dfs -get /user/hive/warehouse/student/student.txt
/opt/module/data/export/student3.txt;
1. sort by 区内排序
有些情况下,我们需要控制某个特定行应该到哪个 reducer,通常是为了进行后续的聚集操作;
一般和distribute by 连用! 先distribute再sort!
一般sort by 会指定分区规则 ! 如果有多个reduce而 没有分区规则就随机分区了!(为了防止数据倾斜)
2. 分区(Distribute By)
一般和sort by 连用!
distribute by 类似 MR 中 partition;
例:
set mapreduce.job.reduces=3; 设置reducer 数
select deptno,ename , sal from emp distribute by deptno sort by sal; -----// 即按照deptno分区,在区内按照sal区内排序;

正好10 20 30三种deptno,对应3个reuducer !
引入:
由于Hive没有索引,查询时全表扫描效率低;
通过分区可以直接查询目录而不用全表扫描,提高效率;
概念:
分区表实际上就是对应一个 HDFS 文件系统上的独立的文件夹,该文件夹下是该分区所有的数据文件。
Hive 中的分区就是分目录文件, 每一个分区就是一个文件;
注意:分区字段不能是表中已经存在的字段 ! 可以将分区字段看作表的伪列。
1. 静态分区
创建分区表:
create table dept01( deptno int, dname string, loc string) partitioned by (day string) ------// ①建表时加入分区字段
倒数数据到分区表:
load data local inpath ‘dept1.txt’ into table dept01 partition(day =‘2020-10-25’) ;
查询: 限定分区字段 !提高效率 !
select * from dept01 where day =‘2020-10-25’;
查询时,分区字段当作普通字段使用即可。
增加分区(使用现有的分区字段)
alter table dept01 add partition(day=‘2020-10-27’);
2. 动态分区
注意:分区字段不能是表中已经存在的数据 !
创建分区表: 与静态分区相同
设置动态分区:
set hive.exec.dynamic.partition.mode=nonstrict;
传入数据:
insert into deptnum partition(deptno) select dname,loc, deptno from dept;
动态分区字段就在select语句中!select的最后一个字段是动态分区字段!
partition(deptno)可省略;
UDF :(一进一出)
UDAF : user defined aggregation function 聚合函数(多进一出)
UDTF :炸裂函数(一进多出) 比如wordcount,将一行数据切分成多行
NVL: MySQL中的ifnull(x,y)