Hive概念
Hive是一个数据仓库。
数据仓库,是为企业所有级别的决策制定过程,提供所有类型数据支持的战略集合。它是单个数据存储,出于分析性报告和决策支持目的而创建。 为需要业务智能的企业,提供指导业务流程改进、监视时间、成本、质量以及控制。
数据仓库与数据库的区别:
- 数据仓库面向主题,数据库面向业务级别的事务
- 数据仓库不按模块、系统区分,是企业数据合集,数据库针对某一具体业务
- 数据仓库一般不更新,只新增,而且是按时序新增。数据库数据可以随时更新删除。
- 数据仓库的数据是汇总的,非规范化的数据,体量大
Hive使用场景:
它是提供了以SQL的方式,对HDFS数据的查询和统计。
在没有Hive的情况下,如果要对Hadoop进行数据级的查询和统计,需要编写mapReduce输出结果,不同的统计,需要编写不同的mapReduce,工作量很大且重复。
有了Hive的情况下,通过编写sql,就可以对Hadoop的HDFS数据进行统计查询,Hive会根据sql自己组装mapReduce。

Hive架构
Hive将数据分为两类,元数据和数据源。
元数据:由Hive自己维护(通常存于mysql),用于对数据源的数据进行描述,包括库、表、字段等信息
数据源:数据存储系统(HDFS),Hive主要实现了对数据源的查询统计,数据的管理只提供了简单的操作。
元数据与HDFS的对应关系:
库: HDFS的一个目录,目录名为库名+.db
表:HDFS的一个目录,目录名为表名,位于库目录下
字段:HDFS文件内数据,创建表时会定义数据分隔符
当通过hive,创建表时, 等于在mysql插入元数据。
insert时, 等于在HDFS 写入数据
select时,等于从HDFS读取数据,如果有聚合,就执行mapreduce spark计算数据。
hive --service metaStoreConf 开启hive元数据服务(针对元数据库,以及某个HDFS工作目录)
通过hive --service serviceConf 开启hiveJDBC服务,为元数据服务提供远程访问, 远程客户端可以通过JDBC连接hive

Meta Store: 元数据存储,hive通过关系型数据库存储自己的元数据(表 字段等),常用mysql
Command Line: 提供了在服务器本地,通过hive指令操作, 类似mysql本地指令操作
执行引擎: 将查询意图转为mapreduce、tez、spark等,对HDFS进行计算产生结果。
配置
hive-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- jdbc 连接的 URL -->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop01:3306/metastore?useSSL=false</value>
</property>
<!-- jdbc 连接的 Driver-->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.cj.jdbc.Driver</value>
</property>
<!-- jdbc 连接的 username-->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<!-- jdbc 连接的 password -->
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
</property>
<!-- Hive 元数据存储版本的验证 -->
<property>
<name>hive.metastore.schema.verification</name>
<value>false</value>
</property>
<!--元数据存储授权-->
<property>
<name>hive.metastore.event.db.notification.api.auth</name>
<value>false</value>
</property>
<!-- Hive 默认在 HDFS 的工作目录 -->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<!-- 指定存储元数据要连接的地址 -->
<property>
<name>hive.metastore.uris</name>
<value>thrift://hadoop02:9083</value>
</property>
<!-- 指定 hiveserver2 连接的 host -->
<property>
<name>hive.server2.thrift.bind.host</name>
<value>hadoop02</value>
</property>
<!-- 指定 hiveserver2 连接的端口号 -->
<property>
<name>hive.server2.thrift.port</name>
<value>10000</value>
</property>
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>
</configuration>
为什么用hive而不用关系型数据库?
hive的本质是Hadoop,hive只是给Hadoop提供了一种使用方式。
那么这个问题就成了为什么用Hadoop而不是关系型数据库。
答案是扩展性,关系型数据的扩展性远远比不上Hadoop,Hadoop可以达到5000个节点的集群,而关系型数据库最强的Oracle最多也只能100个。
而且关系型数据库所需的资源远远大于Hadoop。
Hive数据结构
基本数据类型
tinyint 1byte
smallint 2byte
int 4byte
bigint 8byte
boolean boolean
float 4byte
double 8byte
string 变长
timestamp
binary
高级数据类型
array 定义 xx: array 数据 xx: a_b
map 定义 xx:map 数据 xx: a:'a'_b:1
struct 定义 xx:struct 数据 xx: A_B
通过hive insert数据, hive会通过mapreduce将sql中的数据集转为文件存储到HDFS中。这个过程由于调用了mapreduce,会变的非常慢。所以通常的做法是用户自己直接通过HDFS将文件上传上去。然后再通过hive定义表结构时,同时定义文件中数据的分隔符。让hive去匹配目标数据。
#表结构定义
create table test3(
name string,
friends array<string>,
children map<string, int>,
address struct<street:string, city:string>
)
#分隔符定义
row format delimited fields terminated by ','
collection items terminated by '_'
map keys terminated by ':'
lines terminated by '\n';
# 数据
roy,bob_john,yula:6_sophia:17,lugu_changsha
mike,lea_jacky,rita:7_king:20,chao yang_beijing