什么是Hive
Hive:由Facebook开源用于解决海量结构化日志的数据统计。
Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能。
本质是:将HQL转化成MapReduce程序。
1)Hive处理的数据存储在HDFS
2)Hive分析数据底层的实现是MapReduce
3)执行程序运行在Yarn上
Hive的优缺点
- 优点
- 操作接口采用类SQL语法,提供快速开发的能力(简单、容易上手)。
- 避免了去写MapReduce,减少开发人员的学习成本。
- Hive的执行延迟比较高,因此Hive常用于数据分析,对实时性要求不高的场合。
- Hive优势在于处理大数据,对于处理小数据没有优势,因为Hive的执行延迟比较高。
- Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。
- 缺点
1.Hive的HQL表达能力有限
(1)迭代式算法无法表达
(2)数据挖掘方面不擅长
2.Hive的效率比较低
(1)Hive自动生成的MapReduce作业,通常情况下不够智能化
(2)Hive调优比较困难,粒度较粗
Hive架构原理
Hive | 数据库 | |
存储位置 | HDFS | 本地文件系统或块设备 |
数据更新 | 读多写少,不建议经常改写 | 可以经常对数据进行修改 |
索引 | 有限的索引功能,不建议使用 | 可以提高效率 |
执行引擎 | Map Reduce(默认)/Spark/Tez | 自己的引擎 |
数据规模 | 大规模 | 小规模 |
执行延迟 | 延迟高 | 数据规模小的时候,延迟低 |
可过展性 | 扩展性高 | 扩展能力弱 |
视图 | 只有逻辑视图,没有物化视图 | 有物化视图(oracle和mysql),可提高查询速度 |
Hive数据类型
基本数据类型
Hive数据类型 | Java数据类型 | 长度 | 例子 |
TINYINT | byte | 1byte有符号整数 | 20 |
SMALINT | short | 2byte有符号整数 | 20 |
INT | int | 4byte有符号整数 | 20 |
BIGINT | long | 8byte有符号整数 | 20 |
BOOLEAN | boolean | 布尔类型,true或者false | TRUE FALSE |
FLOAT | float | 单精度浮点数 | 3.14159 |
DOUBLE | double | 双精度浮点数 | 3.14159 |
STRING | string | 字符序列。可以指定字符集,可以使用单引号或者双引号 | ‘TriumPhSK’ “TriumPhSK” |
TIMESTAMP | 时间类型,整数,浮点数或者字符串 | 1327882394(Unix新纪元秒)1327882394.123456789(Unix新纪元秒并跟随有纳米秒数)‘2019-06-06 16:18:58.123456789’(JDBC所兼容的Java.sql.Timestamp时间格式) | |
BINARY | 字节数组 |
集合数据类型
数据类型 | 描述 | 语法示例 |
STRUCT | 和c语言中的struct类似,都可以通过“点”符号访问元素内容。例如,如果某个列的数据类型是STRUCT{first STRING, last STRING},那么第1个元素可以通过字段.first来引用。 | struct(‘John’,‘Doe’) |
MAP | MAP是一组键-值对元组集合,使用数组表示法可以访问数据。例如,如果某个列的数据类型是MAP,其中键->值对是’first’->’John’和’last’->’Doe’,那么可以通过字段名[‘last’]获取最后一个元素. | map(‘first’,‘Join’,’‘last’,‘Doe’) |
ARRAY | 数组是一组具有相同类型和名称的变量的集合。这些变量称为数组的元素,每个数组元素都有一个编号,编号从零开始。例如,数组值为[‘John’, ‘Doe’],那么第2个元素可以通过数组名[1]进行引用。 | array(‘Join’,‘Doe’) |
类型转化
1.隐式类型转换规则如下
(1)任何整数类型都可以隐式地转换为一个范围更广的类型,如TINYINT可以转换成INT,INT可以转换成BIGINT。
(2)所有整数类型、FLOAT和STRING类型都可以隐式地转换成DOUBLE。
(3)TINYINT、SMALLINT、INT都可以转换为FLOAT。
(4)BOOLEAN类型不可以转换为任何其它的类型。
2.可以使用CAST操作显示进行数据类型转换
例如CAST(‘1’ AS INT)将把字符串’1’ 转换成整数1;如果强制类型转换失败,如执行CAST(‘X’ AS INT),表达式返回空值 NULL。
内部表(管理表)和外部表
EXTERNAL关键字可以让用户创建一个外部表
Hive创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。
相互转换:
内部表转为外部表:
alter table managedTable set tblproperties('EXTERNAL'='TRUE');
外部表转为内部表
alter table externalTable set tblproperties('EXTERNAL'='FALSE');
分区表(动态分区)
Hive默认是静态分区
使用动态分区的时候必须开启动态分区(动态分区默认是关闭的),语句如下:
set hive.exec.hynamic.partition=true;
用动态方式加载数据到目标表 ,加载之前先设置一下下面的参数:
set hive.exec.dynamic.partition.mode=nonstrict;
这个属性默认是strict,即限制模式,strict是避免全分区字段是动态的,必须至少一个分区字段是指定有值即静态的,且必须放在最前面。设置为nonstrict之后所有的分区都可以是动态的了。
set hive.exec.max.dynamic.partitions.pernode;
允许创建的动态分区的最大数量(100)
set hive.exec.max.dynamic.partitions;
允许创建的所有动态分区的最大数量(1000)
set hive.exec.max.created.files;
允许创建的文件的最大数量(100000)
动态分区插入数据
insert overwrite table par_tab partition(country, state)
select name, country, state from tab;
混合使用动态和静态分区:
静态分区键必须在动态分区键之前
insert overwrite table par_tab partition(country="China", state)
select name, country, state from tab;
country="China"表示静态分区;state表示动态分区
静态分区一 定会创建分区,不管SELECT语句的结果有没有数据。而动态分区,只有在SELECT结果的记录数>0的时候,才会创建分区。
排序
- 全局排序(Order By)
所有数据都通过一个reduce进行处理,所以可能消耗太漫长的时间来执行
-局部排序(Sort By)
对每个reduce排序,每个reduce的输出数据都是有序的,(并非全局有序)
-Distribute By
依据map输入的键计算相应的哈希值,然后按照得到的哈希值将键-值对均分发到多个reduce中去。
如果和Sort by合用,Distribute By 要写在Sort By 前面
- Cluster By
cluster by除了具有distribute by的功能外还兼具sort by的功能。但是排序只能是升序排序,不能指定排序规则为ASC或者DESC。
Hive优化