一、Hive基本概念
1.1Hive简介
- 什么是Hive
Hive是由Facebook实现并开源,是基于Hadoop的一个数据仓库工具,可以将结构化的数据映射为一张数据库表,并提供HQL(Hive SQL)查询功能,底层数据是存储在HDFS上,Hive的本质是将HQL语句转换为MapReduce任务运行,使不熟悉MapReduce的用户很方便地利用HQL处理和计算HDFS上的结构化的数据,适用于离线的批量数据计算
数据仓库之父比尔·恩门(Bill Inmon)在 1991 年出版的“Building the Data Warehouse”(《建立数据仓库》)一书中所提出的定义被广泛接受——数据仓库(Data Warehouse)是一个面 向主题的(Subject Oriented)、集成的(Integrated)、相对稳定的(Non-Volatile)、反映历史变化(Time Variant)的数据集合,用于支持管理决策(Decision Making Support)。
即:Hive是基于Hadoop的一个数据仓库工具,实质是一款基于HDFS的MapReduce计算框架,对存储在HDFS中的数据进行分析和管理 - 为什么使用hive
(1)友好的接口:操作接口采用类sql语法,提供快速开发的能力
(2)低学习成本:避免了写MapReduce,减少开发人员的学习成本
(3)更好的扩展性:可以自由扩展集群规模二无需重启服务,还支持用户自定义函数 - hive特点
优点:
(1)可横向扩展和纵向扩展,Hive可以自由的扩展集群的规模,一般情况下不需要重启服务
(2)延展性好,Hive支持自定义函数,用户可以根据自己的需求来实现自己的函数
(3)良好的容错性,可以保障即使有节点出现问题,SQL语句仍可完成执行
缺点:
(1)Hive不支持记录级别的增删改操作,但是用户可以通过查询生成新表或者将查询结果导入到文件中
(2)Hive的查询延时严重,因为MR的启动过程消耗很长时间,所以不能用在交互查询系统中
(3)Hive不支持事务(因为不支持增删改,所以主要用来做OLAP(联机分析处理),而不是OLTP(联机事务处理))。
二、Hive和RDBMS(传统关系型数据库)的对比
对比项 | Hive | RDBMS |
---|---|---|
查询语言 | HQL | SQL |
数据存储 | HDFS Raw Device or Local FS | |
执行器 | MR | Executor |
数据插入 | 支持批量/单条插入 | 支持单条或者批量导入 |
数据操作 | 覆盖追加 | 行级更新删除 |
处理数据规模 | 大 | 小 |
执行延迟 | 高 | 低 |
分区 | 支持 | 支持 |
索引 | 0.8版本之后加入简单索引 | 支持复杂的索引 |
扩展性 | 好 | 差 |
数据加载模式 | 读时模式(快) | 写时模式(慢) |
应用场景 | 海量数据查询 | 实时查询 |
即:Hive具有SQL数据库的外表,但Hive只适合用来做海量离线数据的统计分析,即数据仓库。
三、Hive架构
基本组成:
-
用户接口
CLI,Shell终端命令行,采用交互形式使用hive命令行与hive进行交互,学习,调试,生产中最常用
JDBC/ODBC,是Hive的基于JDBC操作提供的客户端,用户通过这连接Hive server服务
Web UI,通过浏览器访问Hive -
Thrift Server
Thrift 是Facebook开发的一个软件框架,可以用来进行可以扩展切跨语言的服务的开发,Hive继承了该服务,能让不同的编程语言调用hive的接口 -
元数据存储
元数据:描述数据的数据
Hive中的元数据通常包括:表名,表的列和分区及其属性(内部表和外部表),表数据所在的HDFS目录
Metastore默认存在自带的Derby数据库中,该数据库很轻量级,用于测试Hive的安装,缺点是不适合多用户操作,并且数据存储目录不固定,数据库跟着hive走,管理极不方便。一般使用Mysql -
驱动引擎
Hive的核心是驱动引擎,驱动引擎由4部分组成:
(1)Parser(解释器):将HQL语句转化为抽象语法树(AST)
(2)Compiler(编译器):将语法树编译为逻辑执行计划
(3)Optimizer(优化器):对逻辑执行计划进行优化
(4)Executor(执行器):调用底层的运行框架执行逻辑执行计划
Driver组件完成HQL查询语句从语法分析,编译,优化,以及逻辑执行计划的生成。生成的逻辑执行计划存储在HDFS中,随后由MR调用执行 -
执行流程
HQL通过命令行或者客户端提交,经过Compiler(编译器),运用MetaStore中的元数据进行类型检测和语法分析,生成一个逻辑方案(Logical Plan),然后通过Optimizer(优化器)优化处理,产生一个MR任务
四、Hive的数据存储
- Hive的存储结构包括数据库、表、视图、分区和表数据等。数据库,表,分区等等都对应HDFS上的一个目录,表数据对应HDFS对应目录下的文件
- Hive中所有数据都存储在HDFS中,没有专门的数据存储格式,因为Hive是读模式(Schema On Read),可支持TextFile,SequenceFile,RCFile或者自定义格式等。插入数据时可以插入任何数据,只有在读取数据时才会进行校验,如果没有通过校验则会报错
- 创建表时指定解析数据的行分隔符和列分隔符,表创建好后不可更改——默认列分隔符:控制符Ctrl+A,\x01,默认行分隔符:换行符,\n
- hive中包含以下数据模型:
(1)database:在HDFS中表现为设置的${hive.metastore.warehouse.dir}目录下一个文件夹
(2)table:在HDFS中表现所属的database目录的下一级文件夹
(3)external table:与table类似,不过其数据存放位置可以指定任意HDFS目录路径
(4)partition:在HDFS中表现为table目录下的子目录
(5)bucket:在HDFS中表现为同一个表目录或者分区目录下根据某个字段的值进行hash散列之后的多个文件
(6)view:与传统数据库类似,只读,基于基本表创建 - Hive的元数据存储在RDBMS中,除了元数据之外的其他所有数据都存储在HDFS中。
默认情况下,Hive元数据保存在内嵌的Derby数据库中,只能允许一个会话连接,只适合简单的测试,实际生产环境中为了支持多用户会话,需要一个独立的元数据库,而Hive内部对MySql提供了很好的支持,所以一般使用MySql作为元数据库 - Hive中的表分为内部表,外部表,分区表和分桶表(bucket表)
五、DDL和DML
官网链接:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL
DDL(data definition language) 数据定义语言
- 库操作
库操作 | 命令 |
---|---|
创建普通库 | create database dbname |
创建库的时候检查是否存在(避免报错) | create database if not exists dbname |
创建库时带注释 | create database dbname comment ‘ xxxxxx’ |
创建带属性的库 | create database dbname with dbproperties(‘a’ =‘aaa’) |
查看库 | show database |
显示数据库详细信息 | desc database [extended/formatted] dbname |
查看当前正在使用的库 | select current_database() |
删除库(空库) | drop database dbname restrict(默认自带该关键字) |
删除数据库(非空) | drop database dbname cascade |
切换库 | use dbname |
- 表操作(摘自官方)
(1)创建表
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name – (Note: TEMPORARY available in Hive 0.14.0 and later)
[(col_name data_type [column_constraint_specification] [COMMENT col_comment], … [constraint_specification])]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], …)]
[CLUSTERED BY (col_name, col_name, …) [SORTED BY (col_name [ASC|DESC], …)] INTO num_buckets BUCKETS]
[SKEWED BY (col_name, col_name, …) – (Note: Available in Hive 0.10.0 and later)]
ON ((col_value, col_value, …), (col_value, col_value, …), …)
[STORED AS DIRECTORIES]
[
[ROW FORMAT row_format]
[STORED AS file_format]
| STORED BY ‘storage.handler.class.name’ [WITH SERDEPROPERTIES (…)] – (Note: Available in Hive 0.6.0 and later)
]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, …)] – (Note: Available in Hive 0.6.0 and later)
[AS select_statement]; – (Note: Available in Hive 0.5.0 and later; not supported for external tables)
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
LIKE existing_table_or_view_name
[LOCATION hdfs_path];
CREATE TABLE:创建一个指定名字的表
EXTERNAL:关键字,创建外部表,不使用该参数时默认创建内部表。内部表被删除的时候元数据和数据都会被删除,外部表被删除时只会删除外部表的元数据,不删除数据。
PARTITIONED BY:通过col分区,该col不可以是建表时的表中的字段。Hive中 select 查询一般会扫描整个表的内容,会消耗很多时间做没必要的工作。因此建表时引入分区的概念
LIKE:允许用户复制现有的表结构,该操作只复制表结构,不复制数据
COMMENT:为表与字段增加描述
ROW FORMAT:用户建表时可以自定义SerDe或者使用自带的SerDe,如果没有指定ROW FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的SerDe
STORED AS TEXTFILE | SEQUENCEFILE | RCFILE :如果文件数据是纯文本,可以使用第一个,默认是textfile格式,可以通过set hive.default.fileformat 命令进行查看,更改则在后面加上 ‘=文件格式’即可。如果数据需要压缩,使用STORED AS SEQUENCEFILE。RCFILE是一种行列存储结合的存储方式
CLUSTERED BY :对于每一个表或者分区,Hive可以进一步组织成桶。Hive也是通过col进行桶的组织。与分区不同,该col必须是建表时表中的字段。Hive采用对列的值进行哈希,之后除以桶的个数求余的方式决定该条记录存放在哪个桶中(和MR中分区组件默认分区逻辑相同)
LOCATION:指定数据文件存放的HDFS目录,不指定就在默认的仓库路径
(2)修改表
操作 | 命令 |
---|---|
重命名表 | alter table tblname rename to new_tblname |
修改表属性 | alter table tbname set tblproperties tbl_properties |
修改表的注释 | alter table tbl_name set tblproperties (‘comment’ = new_comment) |
增加分区 | alter table tbl_name add partition (partition_column = partition_col_value,…) |
删除分区 | alter table tbl_name drop partition (partition_column = partition_col_value) |
(3)删除表和清空表
drop table tbl_name; //删除表
truncate table tbl_name; //清空表
(4)辅助命令
操作 | 命令 |
---|---|
使用正则表达式显示所有stu开头的数据库 | show database like ‘stu*’ |
查看hive函数列表 | show functions |
查看表的详细信息 (元数据信息) | desc tbl_name |
查看表的详细信息 (元数据信息) | desc [extended/formatted] tbl_name |
DML(data manipulation language)数据操纵语言
(1)装载数据
LOAD DATA [LOCAL] INPATH ‘filepath’ [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 …)]
(2)插入数据
插入一条数据:
insert into table tbl_name values(1,2,3)
将查询结果导入新表
insert into table tbl_name [partition(partcol1=val1, partcol2=val2 …)] select_statement1 from from_statement;
多重插入
FROM from_statement
insert table table_name1 [partition (partcol1=val1, partcol2=val2 …)] select_statement1
insert table table_name2 [partition(partcol1=val1, partcol2=val2 …)] select_statement2…
(3)导出数据
insert local directory ’ xxxx’ select_statement
(4)查询数据
SELECT [ALL | DISTINCT] select_expr, select_expr, …
FROM table_reference
[WHERE where_condition]
[GROUP BY col_list]
[ORDER BY col_list]
[CLUSTER BY col_list
| [DISTRIBUTE BY col_list] [SORT BY col_list]
]
[LIMIT [offset,] rows]
Hive中的select基础语法和标准sql语法基本一致,支持where,group by,having,order by,limit子查询等
五、数据类型
1. 原子数据类型
数据类型 | 长度 | 备注 |
---|---|---|
Tinyint | 1字节的有符号整数 | -128~127 |
SmallInt | 2字节的有符号整数 | -32768~32767 |
Int | 4字节的有符号整数 | -2147483648~2147483647 |
BigInt | 8字符的有符号整数 | 9223372036854775808~9223372036854775807 |
Boolean | 布尔类型,true或者false | true、false |
Float | 单精度浮点数 | |
Double | 双精度浮点数 | |
String | 字符串 | |
TimeStamp | 整数 | 支持Unix timestamp ,可以达到纳秒精度 |
(1)Hive支持日期类型(老版本不支持),在Hive里日期一般都是用字符串来表示,常用的日期格式转化操作则是通过自定义函数进行操作,当然也可以直接指定为日期类型
(2)Hive是用JAVA开发的,Hive里的基本数据类型和JAVA的基本数据类型也是一一对应的,除了String 类型
(3)有符号的整数类型:TINYINT,SMALLINT,INT,BIGINT分别等价于java的Byte,Short,Int,Long原子类型;浮点数据类型FLOAT,DOUBLE对应java的基本类型Float和Double类型;BOOLEAN类型相当于Java的基本数据类型Boolean。
(4)Hive的String类型相当于数据库的Varchar类型,该类型是一个可变的字符串,不过它不能声明其中最多能存储多少个字符,理论上可存储2GB的字符数
2. 复杂数据类型
复杂数据类型包括:数组(ARRAY),映射(MAP),结构体(STRUCT)
ARRAY:ARRAY类型是由一系列相同数据类型的元素组成,可以通过下标来访问这些元素,数组的下标从0开始。例如有数组array[‘a’,‘b’,‘c’],则arry[1]则为元素b
MAP:MAP包含<KEY,VALUE>键值对,可以通过key来访问元素。例如有一个map类型的userlist,其中username是key,password是value,则可以通过userlist[‘username’]来得到这个用户对应的password
STRUCT:STRUCT可以包含不同数据类型的元素,这些元素可以通过‘点语法’的方式得到所需要的元素。例如user是一个STRUCT类型,则可以通过user.id得到这个用户的id
CREATE TABLE student(
name STRING, favors ARRAY,
scores MAP<STRING, FLOAT>,
address STRUCT<province:STRING, city:STRING, detail:STRING, zip:INT>
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’
COLLECTION ITEMS TERMINATED BY ‘;’
MAP KEYS TERMINATED BY ‘:’ ;
说明:
(1)name是基本类型,favors是数组类型,可以保存很多爱好;scores是映射类型,可以保存课程和相应课程的成绩;address是结构类型,可以存储地址信息。
(2)ROW FORMAT DELIMITED指明后面的关键词是列和元素分隔符
(3)FIELDS TERMINATED BY是字段分隔符
(4)COLLECTION ITEMS TERMINATED BY是元素分隔符(Array,Struct,Map之间的元素)
(5)MAP KEYS TERMINATED BY是Map中key与value的分隔符
(6)LINES TERMINATED BY 是行之间的分隔符
(7)STORED AS TEXTFILE指数据文件上传后的保存格式
即:关系型数据库中,需要三张表来定义学生基本表,爱好表,成绩表。现在Hive只需要一张表就可以搞定。复合数据类型把多表关系通过一张表就可以实现了
六、视图
- 概念:
(1)Hive只有逻辑视图,没有物理视图
(2)视图只能查询,不能LOAD/INSERT/UPDATE/DELETE数据
(3)视图在创建的时候,只是保存了一份元数据,当查询视图的时候,才开始执行视图对应的子查询
操作 | 命令 |
---|---|
创建视图 | create view view_name as select_statement |
查看视图 | show tables |
具体查看某个视图的信息 | desc view_name |
删除视图 | drop view view_name |
七、函数
函数分为内置函数和自定义函数。
- 内置函数
查看内置函数:show functions;
显示函数的详情信息:desc function abs;
显示函数的扩展信息:desc function extended abs;
- 自定义函数
UDAF(user-defined function):用户定义函数,作用于单个数据行,产生一个数据行作为输出
UDAF(user-defined aggregation function):用户定义聚合函数,接收多个输入数据行,产生一个输出数据行
UDTF(user-defined table function):接收一行输入,输出多行(内置函数中的explode)
自定义函数的使用:开发简单的java类,继承org.apache.hadoop.hive.ql.exec.UDF,重载evaluate方法,完成后将jar包打包上传到服务器,之后将jar包添加到hive的classpath(add JAR ‘path’),之后创建临时函数和开发好的class关联起来(create temporary function tolowercase as 主类),之后就可以愉快的使用自定义函数啦。