目录
- 0 学习链接
- 1 什么是Hive
- 2 Hive的特点
- 3 和关系数据库的区别
- 4 hive架构原理
- 5 执行流程
- 6 Hive的数据模型
- 7 Hive的数据类型
- 8.mysql中int、bigint、smallint 和 tinyint的区别与长度的含义
- 1.bigint
- 2.int
- 3.smallint
- 4.tinyint
1 什么是Hive
- Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供完整的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。
- Hive是建立在 Hadoop 上的数据仓库基础构架。它为数据仓库提供了许多动能:ETL(抽取、转换、加载)、数据存储、大型数据集的查询和分析。
- Hive 定义了简单的类 SQL 查询语言,称为 HQL。它允许熟悉 SQL 的用户查询数据。同时,也允许熟悉 MapReduce 开发者的开发自定义的 mapper 和 reducer 来处理内建的 mapper 和 reducer 无法完成的复杂的分析工作。
2 Hive的特点
- 简单、容易上手 (提供了类似 sql 的查询语言 hql),使得精通 sql 但是不了解 Java 编程的人也能很好地进行大数据分析;
- 灵活性高,可以自定义用户函数 (UDF) 和存储格式;
- 为超大的数据集设计的计算和存储能力,集群扩展容易;
- 统一的元数据管理,可与 presto/impala/sparksql 等共享数据;
- 执行延迟高,不适合做数据的实时处理,但适合做海量数据的离线处理。
(说明:不完全支持SQL标准,如,不支持更新操作、索引和事务,其子查询和连接操作也存在很多限制)
3 和关系数据库的区别
(1)Hive是什么
基于Hadoop的开源数据仓库工具,用于存储和处理海量结构化数据
Hive把HDFS中结构化的数据映射成表
Hive通过把HiveSQL进行解析和转换,最终生成一系列基于hadoop的map/reduce任务,通过执行这些任务完成数据处理
(2)HiveSQL与传统SQL的比较(9个)
查询语言不同:HiveSQL是HQL语言,传统SQL是SQL语句;
数据存储位置不同:HiveSQL是把数据存储在HDFS上,而传统SQL数据是存储在块设备或者本地文件;
数据格式:HiveSQL数据格式可以用户自定义,传统SQL有自己的系统定义格式(不同的数据库有不同的存储引擎);如: 年龄字段age在Hive中可以定义为INT,STRING,DOUBLE,定义什么型都可以,即使为STRING也可以做运算(加减乘除),在SQL只能存为数值型,STRING型排序规则是按照第一个字符进行排序
数据更新:hive不支持数据记录更新,只可以读,不可以写,而sql支持数据更新;如: 只改某一条数据的某个字段值, 在Hive中是不可以的, 只能将整个表重新导入更新
索引:hive没有索引,因此查询数据的时候是通过mapreduce很暴力的把数据都查询一遍,也造成了hive查询数据速度很慢的原因,而mysql有索引;
延迟性:hive延迟性高,原因就是上边一点所说的,而mysql延迟性低;
数据规模:hive存储的数据量超级大,而mysql只是存储一些少量的业务数据;
底层执行原理:hive底层计算模型是用的mapreduce(启动需要时间准备),而mysql是excutor执行器;
可扩展性:HiveSQL高而传统SQL较低;Hive很容易扩展自己的存储能力和计算能力,这个是继承hadoop的.
补充:
- 1) 关系数据库里,表的加载模式是在数据加载时候强制确定的(表的加载模式是指数据库存储数据的文件格式),如果加载数据时候发现加载的数据不符合模式,关系数据库则会拒绝加载数据,这个就叫“写时模式”,写时模式会在数据加载时候对数据模式进行检查校验的操作。Hive在加载数据时候和关系数据库不同,hive在加载数据时候不会对数据进行检查,也不会更改被加载的数据文件,而检查数据格式的操作是在查询操作时候执行,这种模式叫“读时模式”。
在实际应用中,写时模式在加载数据时候会对列进行索引,对数据进行压缩,因此加载数据的速度很慢,但是当数据加载好了,我们去查询数据的时候,速度很快。但是当我们的数据是非结构化,存储模式也是未知时候,关系数据操作这种场景就麻烦多了,这时候hive就会发挥它的优势。 - 2)关系数据库一个重要的特点是可以对某一行或某些行的数据进行更新、删除操作,hive不支持对某个具体行的操作,hive对数据的操作只支持覆盖原数据和追加数据。Hive也不支持事务和索引。更新、事务和索引都是关系数据库的特征,这些hive都不支持,也不打算支持,原因是hive的设计是海量数据进行处理,全数据的扫描时常态,针对某些具体数据进行操作的效率是很差的,对于更新操作,hive是通过查询将原表的数据进行转化最后存储在新表里,这和传统数据库的更新操作有很大不同。
- 3)Hive也可以在hadoop做实时查询上做一份自己的贡献,那就是和hbase集成,hbase可以进行快速查询,但是hbase不支持类SQL的语句,那么此时hive可以给hbase提供sql语法解析的外壳,可以用类sql语句操作hbase数据库。
(3)Hive的优势
把海量数据存储于 hadoop 文件系统,而不是数据库,但提供了一套类数据库的数据存储和处理机制,并采用 HQL (类 SQL )语言对这些数据进行自动化处理
不仅提供了一个熟悉SQL的用户所能熟悉的编程模型,还消除了大量的通用代码,甚至那些有时是 不得不使用Java编写的令人棘手的代码
学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce 应用,十分适合数据仓库的统计分析,应用开发灵活而高效
4 hive架构原理
- 架构介绍
Hive依赖于Hadoop,使用hdfs作为数据存储,将数据运算转换成MapReduce作业在Hadoop集群执行;
Hive架构包括:CLI、JDBC/ODBC、Thrift Server、WEB GUI、Metastore和Driver(Complier、Optimizer和Executor)。 分为两大类:服务端组件和客户端组件 - 服务端组件
Driver组件:该组件包括Complier、Optimizer和Executor,它的作用是将我们写的HiveQL语句进行解析、编译优化,生成执行计划,然后调用底层的MapReduce计算框架。
Metastore组件:元数据服务组件,这个组件存储hive的元数据,hive的元数据存储在关系数据库里,hive支持的关系数据库有derby、mysql。元数据对于hive十分重要,因此hive支持把metastore服务独立出来,安装到远程的服务器集群里,从而解耦hive服务和metastore服务,保证hive运行的健壮性
Thrift服务:thrift用来进行可扩展且跨语言的服务的开发,hive集成了该服务,能让不同的编程语言调用hive的接口。 - 客户端组件
CLI:command line interface,命令行接口。
Thrift客户端:hive架构的许多客户端接口是建立在thrift客户端之上,包括JDBC和ODBC接口。
ODBC / JDBC are SQL-based APIs that to enable Windows software applications / Java applications to access databases via SQL.
WebGUI:hive客户端提供了一种通过网页的方式访问hive所提供的服务。这个接口对应hive的hwi组件(hive web interface),使用前要启动hwi服务。
5 执行流程
- 执行流程详细解析
(1)Step 1:UI(user interface)调用的Driver的execute接口
(2)Step 2:Driver为查询创建会话句柄,并将查询发送给compiler以生成执行计划,
(3)Step 3 and 4:compiler从metastore获取相关的元数据定义
(4)Step 5:元数据用于对查询树中的表达式进行类型检查,以及基于查询谓词调整分区,生成计划
(5)Step 6, 6.1, 6.2 and 6.3:由compiler生成的执行计划是阶段的DAG,每个阶段都会涉及到Map/Reduce job,元数据的操作或者HDFS文件的操作。在Map/Reduce阶段,执行计划包含Map 操作树(操作树在Mappers上执行)和reduce操作树(Reduce 操作树在 Reducers上执行),Execution Engine 将各个阶段提交个适当的组件执行。
(6)Step 7, 8 and 9:在每个任务(mapper / reducer)中,表或者中间输出相关的反序列化器从HDFS读取行,并通过相关的操作树进行传递。一旦这些输出产生,将通过序列化器生成零时的的HDFS文件(这个只发生在只有Map没有reduce的情况),生成的HDFS零时文件用于执行计划后续的Map/Reduce阶段。对于DML操作,零时文件最终移动到表的位置。该方案确保不出现脏数据读取(文件重命名是HDFS中的原子操作),对于查询,临时文件的内容由Execution Engine直接从HDFS读取,作为从Driver Fetch API的一部分 - 过程
- 我们通过 Hive 的 Client(Hive 的命令行工具,JDBC 等)向 Hive 提交 SQL 命令。
- 如果是创建数据表的 DDL(数据定义语言),Hive 就会通过执行引擎Driver 将数据表的信息记录在 Metastore 元数据组件中,这个组件通常用一个关系数据库实现,记录表名、字段名、字段类型、关联 HDFS 文件路径等这些数据库的 Meta 信息(元信息)。
- 如果我们提交的是查询分析数据的 DQL(数据查询语句),Driver 就会将该语句提交给自己的编译器 Compiler进行语法分析、语法解析、语法优化等一系列操作,最后生成一个MapReduce 执行计划。然后根据执行计划生成一个 MapReduce 的作业,提交给 Hadoop MapReduce 计算框架处理。
- Hive 内部预置了很多函数,Hive 的执行计划就是根据SQL 语句生成这些函数的 DAG(有向无环图),然后封装进MapReduce 的 map 和 reduce 函数中。
3.查询主要组件 - UI(user interface) –用户提交查询或者其他操作,现在标准UI有CLI(command line interface),Thrift Serve,Hive web interface(HWI)。
- Driver(驱动) –负责接收查询及其他操作,Driver 实现了会话句柄的概念,并提供在基于JDBC / ODBC的execute和fetch API。
- Compiler(编译器) – 解析查询的sql,对不同的块和不同的查询表达式进行语义分析,借助metastore中的表和分区的元数据定义生成执行计划。
- Metastore –存储所有表及分区的结构信息,包含列名,列的数据类型,读取和写入的序列化器和反序列化器以及相关的HDFS文件存储目录。
- Execution Engine(执行引擎) –执行compiler所产生的执行计划。该执行计划是一个阶段的DAG,执行引擎关联执行计划中不同阶段的之间依赖,并负责在不同的系统组件中执行不同的阶段。
6 Hive的数据模型
hive的数据模型包括:database、table、partition和bucket。下面我将一一论述这四种数据模型。
- Database:相当于关系数据库里的命名空间(namespace),它的作用是将用户和数据库的应用隔离到不同的数据库或模式中,该模型在hive 0.6.0之后的版本支持,hive提供了create database dbname、use dbname以及drop database dbname这样的语句。
- 表(table):hive的表逻辑上由存储的数据和描述表格中的数据形式的相关元数据组成。表存储的数据存放在分布式文件系统里,例如HDFS,元数据存储在关系数据库里,当我们创建一张hive的表,还没有为表加载数据的时候,该表在分布式文件系统,例如hdfs上就是一个文件夹(文件目录)。
Hive里的表友两种类型一种叫托管表,这种表的数据文件存储在hive的数据仓库里,一种叫外部表,这种表的数据文件可以存放在hive数据仓库外部的分布式文件系统上,也可以放到hive数据仓库里(注意:hive的数据仓库也就是hdfs上的一个目录,这个目录是hive数据文件存储的默认路径,它可以在hive的配置文件里进行配置,最终也会存放到元数据库里)。 - 分区(partition):hive里分区的概念是根据“分区列”的值对表的数据进行粗略划分的机制,在hive存储上就体现在表的主目录(hive的表实际显示就是一个文件夹)下的一个子目录,这个文件夹的名字就是我们定义的分区列的名字,没有实际操作经验的人可能会认为分区列是表的某个字段,其实不是这样,分区列不是表里的某个字段,而是独立的列,我们根据这个列存储表的里的数据文件。
目的:使用分区是为了加快数据分区的查询速度而设计的,我们在查询某个具体分区列里的数据时候没必要进行全表扫描。类似于传统数据库中划分列的索引。在Hive中,表中的一个Partition对应于表下的一个目录,所有的Partition数据都存储在对应的目录中。例如:zz表中包含ds和city两个Partition,则对应于ds=20140214,city=beijing的HDFS子目录为:/wh/zz/ds=20140214/city=Beijing - 桶(bucket):上面的table和partition都是目录级别的拆分数据,bucket则是对数据源数据文件本身来拆分数据。对指定列计算的hash,根据hash值切分数据,目的是为了便于并行,每一个Buckets对应一个文件。将user列分数至32个Bucket上,首先对user列的值计算hash,比如,对应hash=0的HDFS目录为:/wh/zz/ds=20140214/city=Beijing/part-00000;对应hash=20的,目录为:/wh/zz/ds=20140214/city=Beijing/part-00020。使用桶的表会将源数据文件按一定规律拆分成多个文件,要使用bucket,我们首先要打开hive对桶的控制,命令如下:set hive.enforce.bucketing = true
7 Hive的数据类型
- Hive包含基本数据类型和复杂数据类型:
int存储较短的整型,bigint存储较长的整型。 - Hive支持基本类型的转换:
低字节的基本类型可以转化为高字节的类型,例如TINYINT、SMALLINT、INT可以转化为FLOAT,而所有的整数类型、FLOAT以及STRING类型可以转化为DOUBLE类型,这些转化可以从java语言的类型转化考虑,因为hive就是用java编写的。当然也支持高字节类型转化为低字节类型,这就需要使用hive的自定义函数CAST了。
8.mysql中int、bigint、smallint 和 tinyint的区别与长度的含义
1.bigint
从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型数据(所有数字)。存储大小为 8 个字节。
P.S. bigint已经有长度了,在mysql建表中的length,只是用于显示的位数
2.int
从 -2^31 (-2,147,483,648) 到 2^31 – 1 (2,147,483,647) 的整型数据(所有数字)。存储大小为 4 个字节。int 的 SQL-92 同义字为 integer。
3.smallint
从 -2^15 (-32,768) 到 2^15 – 1 (32,767) 的整型数据。存储大小为 2 个字节。
4.tinyint
从 0 到 255 的整型数据。存储大小为 1 字节。
注释
- 在支持整数值的地方支持 bigint 数据类型。但是,bigint 用于某些特殊的情况,当整数值超过 int 数据类型支持的范围时,就可以采用 bigint。在 SQL Server 中,int 数据类型是主要的整数数据类型。
- 在数据类型优先次序表中,bigint 位于 smallmoney 和 int 之间。
- 只有当参数表达式是 bigint 数据类型时,函数才返回 bigint。SQL Server 不会自动将其它整数数据类型(tinyint、smallint 和 int)提升为 bigint。
- int(M) 在 integer 数据类型中,M 表示最大显示宽度。在 int(M) 中,M 的值跟 int(M) 所占多少存储空间并无任何关系。和数字位数也无关系 int(3)、int(4)、int(8) 在磁盘上都是占用 4 btyes 的存储空间。