1、hive的作用:
1.hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供完整的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。
2.Hive是建立在 Hadoop 上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储、查询和分析存储在 Hadoop 中的大规模数据的机制。Hive 定义了简单的类 SQL 查询语言,称为 HQL,它允许熟悉 SQL 的用户查询数据。同时,这个语言也允许熟悉 MapReduce 开发者的开发自定义的 mapper 和 reducer 来处理内建的 mapper 和 reducer 无法完成的复杂的分析工作。
2、hive的原理
Hive工作原理如图所示
Hive执行流程
•编译器将一个Hive QL转换操作符
•操作符是Hive的最小的处理单元
•每个操作符代表HDFS的一个操作或者一道MapReduce作业
3、hive内部概念
-
解释器、编译器、优化器。
Driver 调用解释器(Compiler)处理 HiveQL 字串,这些字串可能是一条 DDL、DML或查询语句。编译器将字符串转化为策略(plan)。策略仅由元数据操作 和 HDFS 操作组成,元数据操作只包含 DDL 语句,HDFS 操作只包含 LOAD 语句。对插入和查询而言,策略由 MapReduce 任务中的具有方向的非循环图(directedacyclic graph,DAG)组成,具体流程如下。
1)解析器(parser):将查询字符串转化为解析树表达式。
2)语义分析器(semantic analyzer):将解析树表达式转换为基于块(block-based)的内部查询表达式,将输入表的模式(schema)信息从 metastore 中进行恢复。用这些信息验证列名, 展开 SELECT * 以及类型检查(固定类型转换也包含在此检查中)。
3)逻辑策略生成器(logical plan generator):将内部查询表达式转换为逻辑策略,这些策略由逻辑操作树组成。
4)优化器(optimizer):通过逻辑策略构造多途径并以不同方式重写。优化器的功能如下:
将多 multiple join 合并为一个 multi-way join;
对join、group-by 和自定义的 map-reduce 操作重新进行划分;
消减不必要的列;
在表扫描操作中推行使用断言(predicate);
对于已分区的表,消减不必要的分区;
在抽样(sampling)查询中,消减不必要的桶。
此外,优化器还能增加局部聚合操作用于处理大分组聚合(grouped aggregations)和 增加再分区操作用于处理不对称(skew)的分组聚合。
4、hive的表与分区
表
Hive 没有专门的数据存储格式,也没有为数据建立索引,用户可以非常自由的组织 Hive 中的表,只需要在创建表的时候告诉 Hive 数据中的列分隔符和行分隔符,Hive 就可以解析数据,Hive 中的 Table 和数据库中的 Table 在概念上是类似的,每一个 Table 在 Hive 中都有一个相应的目录存储数据。
分区:
a) 分区表是把数据放在不同的磁盘文件中,hive数据库会对不同分区进行单独管理,优化,最终会加快数据查询速度。
b) 分区表分区的含义:也是把数据进行划分不同的区,hive中的区是指不同子文件夹中。
c) 分区表创建原因: 100M的学生信息,如果查询班级为1班的学生,在不使用分区表时,需要去100M中遍历查询,如果使用分区表,只需要去文件夹名称为1班的hdfs文件中查找即可。
d) 分区字段简介:
d.1) 分区字段就是文件夹的标识名称,
d.2) 在正常使用的时候,分区字段是作为正常字段被使用,但是在数据文件中不存在,仅作为虚拟列 (virtual column)存在
e) 分区过多的坏处:
如果分区过多,hive在扫描时,一级级的扫来扫去,会增加扫描成本, 在运行时,对于map端造成map任务增多。
相应的操作:
创建分区表:
create table table_name ( id int, dtDontQuery string, name string ) partitioned by (date string)
添加分区:
ALTER TABLE table_name ADD IF NOT EXISTS PARTITION (dt='20130101') LOCATION '/user/hadoop/warehouse/table_name/dt=20130101'; //一次添加一个分区
ALTER TABLE page_view ADD PARTITION (dt='2008-08-08', country='us') location '/path/to/us/part080808' PARTITION (dt='2008-08-09', country='us') location '/path/to/us/part080809'; //一次添加多个分区
删除分区:
ALTER TABLE page_view DROP IF EXISTS PARTITION (dt='2008-08-08', country='us');
修改分区:
ALTER TABLE table_name PARTITION (dt='2008-08-08') RENAME TO PARTITION (dt='20080808');
数据加载进分区的语法:
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)];
例如:
LOAD DATA INPATH '/user/pv.txt' INTO TABLE day_hour_table PARTITION(dt='2008-08-08',hour='08');
LOAD DATA local INPATH '/user/hua/*' INTO TABLE day_hour partition(dt='2010-07- 07');
当数据被加载至表中时,不会对数据进行任何转换。Load操作只是将数据复制至Hive表对应的位置。数据加载时在表下自动创建一个目录
分区查询:
select table_name.* from table_name where partition_name = '2014-02-25';
SELECT table_name.* FROM table_name WHERE table_name.dt>= '2017-02-22';
select table_name.* from table_name where table_name.year='2017' and table_name.month='02' and table_name.day='22'
查看分区:
show partitions table;