Hive分布式SQL计算平台
图片无法加载请跳转CSDN:Hive分布式SQL计算平台-CSDN博客
一、Hive 概述
使用Hadoop MapReduce直接处理数据所面临的问题 ,人员学习成本太高 需要掌握java、Python等编程语言
MapReduce实现复杂查询逻辑开发难度太大
基于Hive为用户提供了分布式SQL计算的能力,写的是SQL、执行的是MapReduce
使用Hive处理数据的好处
- 操作接口采用类SQL语法,提供快速开发的能力(简单、容易上手)
- 底层执行MapReduce,可以完成分布式海量数据的SQL处理
什么是分布式SQL计算?
以分布式的形式,执行SQL语句,进行数据统计分析。Apache Hive是做什么的?
将SQL语句翻译成MapReduce程序,从而提供用户分布式SQL计算的能力。
传统MapReduce开发:写MR代码->得到结果
使用Hive开发:写SQL->得到结果
底层都是MR在运行,但是使用层面上更加简单了。
二、Hive架构
元数据管理,称之为Metastore服务
SQL解析器(Driver驱动程序),完成SQL解析、执行优化、代码提交等功能
用户接口:提供用户和Hive交互的功能

元数据存储:通常是存储在关系数据库如 mysql/derby中。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。
Hive提供了 Metastore 服务进程提供元数据管理功能
Driver驱动程序:包括语法解析器、计划编译器、优化器、执行器:完成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 HDFS 中,并在随后有执行引擎调用执行。
用户接口:包括 CLI、JDBC/ODBC、WebGUI。其中,CLI(command line interface)为shell命令行;Hive中的Thrift服务器允许外部客户端通过网络与Hive进行交互,类似于JDBC或ODBC协议。WebGUI是通过浏览器访问Hive。
Hive提供了 Hive Shell、 ThriftServer等服务进程向用户提供操作接口
三、Hive客户端
1、Hive有哪些客户端可以使用
执行:
bin/hive
,这是Hive提供的Shell环境,可以直接写SQL执行启动HiveServer2,
bin/hive --service hiveserver2
这是Hive的Thrift服务,对外提供接口(默认端口10000)可供其它客户端链接,如:bin/beeline(内置)、IntelliJ IDEA (第三方)DataGrip(第三方)、DBeaver(第三方) 等
Hive的客户端体系如下

启动:在hive安装的服务器上,首先启动metastore服务,然后启动hiveserver2服务。
1 |
|
通过beeline连接
1 |
|
2、Hive第三方客户端
IntelliJ IDEA 连接 hive
- 打开Database窗口 (在IDEA中,点击菜单栏中的
View
->Tool Windows
->Database
,打开Database工具窗口) - 在Database工具窗口中,点击上方的加号
+
,选择Data Source
->Apache Hive
- 填写Hive数据库的连接信息,包括JDBC URL(如
jdbc:hive2://localhost:10000
)、用户名和密码(如果Hive配置了认证)
连接需要驱动,点击可以下载驱动
连接成功后,你就可以在IDEA中通过SQL编辑器编写和执行HiveQL语句了。这些语句将直接发送到HiveServer2执行,并返回结果。
四、Hive使用语法
1、数据库操作
创建数据库
1 |
|
删除数据库
1 |
|
数据库和HDFS的关系
- Hive的库在HDFS上就是一个以.db结尾的目录
- 默认存储在:
/user/hive/warehouse
内 - 可以通过
LOCATION
关键字在创建的时候指定存储目录
2、内部表,外部表
创建表的语法
1 |
|
关键词:EXTERNAL,创建外部表、PARTITIONED BY, 分区表、CLUSTERED BY,分桶表、STORED AS,存储格式、LOCATION,存储位置
数据类型
分类 | 类型 | 描述 | 字面量示例 |
---|---|---|---|
原始类型 | BOOLEAN | true/false | TRUE |
TINYINT | 1字节的有符号整数-128~127 | 1Y | |
SMALLINT | 2个字节的有符号整数, -32768~32767 | 1S | |
INT |
4个字节的带符号整数 | 1 | |
BIGINT | 8字节带符号整数 | 1L | |
FLOAT | 4字节单精度浮点数 | 1.0 | |
DOUBLE |
8字节双精度浮点数 | 1.0 | |
DEICIMAL | 任意精度的带符号小数 | 1.0 | |
STRING |
字符串,变长 | “a” ‘b’ | |
VARCHAR |
变长字符串 | “a”, ‘b’ | |
CHAR | 固定长度字符串 | “a”, ‘b’ | |
BINARY | 字节数组 | ||
TIMESTAMP |
时间戳,毫秒值精度 | 122327493795 | |
DATE |
日期 | ‘2016-03-29’ | |
时间频率间隔 | |||
复杂类型 | ARRAY | 有序的的同类型的集合 | array(1,2) |
MAP | key-value,key必须为原始类型, value可以任意类型 | map(‘a’,1,’b’,2) | |
STRUCT | 字段集合,类型可以不同 | struct(‘1’,1,1.0), named_stract(‘col1’,’1’,’col2’,1, ‘clo3’,1.0) | |
UNION | 在有限取值范围内的一个值 | create_union(1,’a’ ,63) |
Hive中可以创建的表有好几种类型, 分别是:内部表、外部表、分区表、分桶表
内部表(CREATE TABLE table_name ……)
- 未被external关键字修饰的即是内部表, 即普通表。 内部表又称管理表,内部表数据存储的位置由hive.metastore.warehouse.dir参数决定(默认:/user/hive/warehouse),删除内部表会直接删除元数据(metadata)及存储数据,因此内部表不适合和其他工具共享数据。
外部表(CREATE EXTERNAL TABLE table_name ……LOCATION……)
- 被external关键字修饰的即是外部表, 即关联表。
- 外部表是指表数据可以在任何位置,通过LOCATION关键字指定。 数据存储的不同也代表了这个表在理念是并不是Hive内部管理的,而是可以随意临时链接到外部数据上的。
- 在删除外部表的时候, 仅仅是删除元数据(表的信息),不会删除数据本身。
创建 | 存储位置 | 删除数据 | 理念 | |
---|---|---|---|---|
内部表 | CREATE TABLE …… | Hive管理,默认/user/hive/warehouse | 删除 元数据(表信息)删除 数据 | Hive管理表持久使用 |
外部表 | CREATE EXTERNAL TABLE …… | 随意,LOCATION关键字指定 | 仅删除 元数据(表信息)保留 数据 | 临时链接外部数据用 |
数据分隔符
- 默认是特殊字符: ‘\001’ (^A soh)
- 可以通过row format delimited fields terminated by在创建表的时候修改
其它创建内部表的形式
1 |
|
外部表的创建
- 可以先有表,然后把数据移动到表指定的LOCATION中
- 也可以先有数据,然后创建表通过LOCATION指向数据
1 |
|
内部表外部表转换
1 |
|
3、数据的导入与导出
1)数据加载
1、使用 LOAD 语法,从外部将数据加载到Hive内(不会走MapReduce 小文件速度快)
1 |
|
- 使用
local
,数据不在HDFS,可以使用file://协议指定路径 - 不使用
local
,数据在HDFS,可以使用HDFS://协议指定路径 - 加
OVERWRITE
代表覆盖已有数据
注意:基于HDFS进行load加载数据,源数据文件会消失(本质是被移动到表所在的目录中)
2、可以通过SQL语句,从其它表中加载数据
1 |
|
注意:走MapReduct少了数据时不如直接导入
2)数据导出
1、将查询的结果导出
1 |
|
2、hive表数据导出 - hive shell
1 |
|
4、分区表
可以选择字段作为表分区
分区其实就是HDFS上的不同文件夹
分区表可以极大的提高特定场景下Hive的操作性能
分区表的分区列,在partitioned by 中定义,不在普通列中定义
左侧单分区表 右侧多分区表(三级分区)
分区表的使用
1、创建分区表,加载数据
1 |
|
2、查看,修改,删除分区
1 |
|
其余属性可参见 LanguageManual DDL - Apache Hive - Apache Software Foundation
5、分桶表
分桶和分区一样,也是一种通过改变表的存储模式,从而完成对表优化的一种调优方式
但和分区不同,分区是将表拆分到不同的子文件夹中进行存储,而分桶是将表拆分到固定数量的不同文件中进行存储。
分桶表创建
1 |
|
分桶表加载数据
桶表的数据加载,由于桶表的数据加载通过load data无法执行,只能通过insert select.
1 |
|
为什么不可以用load data,必须用insert select插入数据
- 一旦有了分桶设置,比如分桶数量为3,那么,表内文件或分区内数据文件的数量就限定为3
- 当数据插入的时候,需要一分为3,进入三个桶文件内。
- 数据的三份划分基于分桶列的值进行Hash取模来决定
- 由于load data不会触发MapReduce,也就是没有计算过程(无法执行Hash算法),只是简单的移动数据而已
所以无法用于分桶表数据插入。
什么是Hash取模?
- 基于Hash算法,对值进行计算,同一个值得到同样的结果
- 对结果进行取模(除以桶数量得到余数),确认当前数据应该去哪一个桶文件
- 同样key(分桶列的值)的数据,会在同一个桶中。
分桶表的性能提升
分区表的性能提升是:在指定分区列的前提下,减少被操作的数据量,从而提升性能。
分桶表的性能提升就是:基于分桶列的特定操作,如:过滤、JOIN、分组,均可带来性能提升。
- 基于分桶列,过滤单个值:根据Hash值
- 基于分桶列,进行双表JOIN:桶文件对桶文件
- 基于分桶列,group by 分组:自动归并为各个组了
6、复杂类型操作
array类型
array类型,主要存储:数组格式
保存一堆同类型的元素,如:1, 2, 3, 4, 5定义格式:
array<类型>
数组元素之间的分隔符:collection items terminated by ‘分隔符’在查询中使用
数组[数字序号],可以取出指定需要元素(从0开始)
size(数组),可以统计数组元素个数
array_contains(数组, 数据),可以查看指定数据是否在数组中存在
示例数据 和 代码
1 |
|
1 |
|
map类型
- map类型,主要存储:K-V键值对类型数据
保存一堆同类型的键值对,如:“a”:1, “b”: 2, “c”: 3- 定义格式:
map<key类型, value类型>
不同键值对之间:COLLECTION ITEMS TERMINATED BY ‘分隔符’ 分隔
一个键值对内,使用: MAP KEYS TERMINATED BY ‘分隔符’ 分隔K-V
如:father:xiaoming#mother:xiaohuang#brother:xiaoxu
不同KV之间使用#分隔,同一个KV内用:分隔K和V- 在查询中使用
map[key]来获取指定key的值
map_keys(map)取到全部的key作为array返回,map_values(map)取到全部values
size(map)可以统计K-V对的个数
array_contains(map_values(map), 数据) 可以统计map是否包含指定数据
示例数据 和 代码
1 |
|
1 |
|
struct类型
- struct类型,主要存储:复合格式
可以包含多个二级列,二级列支持列名和类型,如
“a”: 1, “b”: “foo”, “c”: “2000-01-01”- 定义格式:
struct<name:string, age:int>
struct的分隔符只需要:COLLECTION ITEMS TERMINATED BY ‘分隔符’ 只需要分隔数据即可(数据中不记录key,key是建表定义的固定的)- 在查询中使用
struct.key 即可取得对应的value
示例数据 和 代码
1 |
|
1 |
|
7、数据抽样
大数据体系下,表内容一般偏大,小操作也要很久,所以如果想要简单看看数据,可以通过抽样快速查看
桶抽样方式,
TABLESAMPLE(BUCKET x OUT OF y ON(colname | rand()))
,推荐,完全随机,速度略慢块抽样,使用分桶表可以加速1
2
3
4
5-- 10个抽3份 orderId Hash取模, 其他条件不变的话运行结果一致
select * from orders tablesample (bucket 3 out of 10 on orderId);
-- 完全随机,分10个桶随机抽3个
select * from orders tablesample (bucket 3 out of 10 on rand());块抽样方式,
TABLESAMPLE(num ROWS | num PERCENT | num(K|M|G))
,速度快于桶抽样方式,但不随机,只是按照数据顺序从前向后取。1
2
3select * from orders tablesample (100 rows); -- 抽取前100条
select * from orders tablesample (10 percent); -- 抽取前10%
select * from orders tablesample (1K); -- 抽取前1KB
8、Virtual Columns 虚拟列
虚拟列是Hive内置的可以在查询语句中使用的特殊标记,可以查询数据本身的详细参数。
1 |
|
虚拟列的作用
- 查看行级别的数据详细参数
- 可以用于WHERE、GROUP BY等各类统计计算中
- 可以协助进行错误排查工作
9、Hive函数
Hive的函数分为两大类:内置函数(Built-in Functions)、用户定义函数UDF(User-Defined Functions):
具体可查看:官方文档
1 |
|