Hive知识总结
Posted 大数据DL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive知识总结相关的知识,希望对你有一定的参考价值。
本文是根据之前hive系列的文章进行整理。
知识大纲
Hive基础操作和数据类型
基础操作
数据类型
数据库操作
HiveQL
数据定义
数据操作
数据查询
where查询
JOIN
排序
视图
桶
HiveQL:索引
创建索引
使用索引
Hive优化
常见优化
hive数据倾斜
Hive压缩
一. Hive基础操作和数据类型
基础操作
数据类型
数据库操作
基础操作
指定数据仓库 目录
一般都是在hdfs上有这个目录,hive安装的时候元数据保存在关系数据库中,一般是mysql。hive启动命令:
hive默认,bin/hive启动的是client模式,bin/hive类似于bin/hive –service cli 后面的选项还有如下图,你也可以启动一个hwi,用web访问,执行sql可视化。
剩下的两个参数说明:添加额外jar包和指定配置文件
命令行界面,也就是CLI,是和Hive交互的常用方式,使用cli,用户可以创建表,检查模式,以及查询表等,cli选项如下:
各个选项使用说明:
-d可以设置变量,类似于:
可以简化成-d,-d是用来自定义变量的,需要注意的是定义的是hive,可以不加hivevar。
例如上面第一个写的,但是,如果是env、system必须要加前缀,如下:
-e 是直接执行sql语句。如下:bin/hive -e “sql语句”
-f 是执行文件里的sql语句,例如:
我们可以把hive sql执行的结果直接导入到本地文件中
注意-S可以去掉额外提示信息
启动hive shell的时候,如果想加载一下额外配置可以在命令里面写-d 配置=值,但这样比较麻烦,每次都得写。hive有一个hive shell每次启动的时候都会去加载的目录:
$HOME/hivec,比如/home/root/hiver
注意 hive.cli.print.current.db=true是显示数据库的名字,还有一个配置是hive.exec.mode.local.auto=true,即使在hadoop分布式环境中,配置之后,hive根据数据量判断是用自己的mr本地执行(本地执行快),还是用hadoop分布式环境执行。在hive shell 中可以直接执行hadoop命令,执行方式是去掉hadoop。例如:
hive不光可以配置提示数据库,还可以设置显示列,配置如下设置命令和显示的列名
数据类型
hive的数据类型和java的基本类型保持一致
它只有时间戳类型没有date类型,hive里面的类型强制转换用的是:cast(列 as 类型)。hive为了提高读取数据,把平时我们要分表做的事情,写到一张表里面,为了实现这个目的,它额外多出了集合类型,冗余存储
分别是结构体、key-value键值对、数组。注意里面都是引号引起来的,例如:
当我们设置了集合类型,我们的数据格式就一定限制了。
数据格式分割符,例如我们平时csv就是逗号分割。hive默认的分割符:
换行符是不能自定义的,其他都可以自定义:集合元素之间用^B,map的key value之间用^C、列与列之间用^A。这是hive默认的。例如数据:
用户可以不使用默认分割符,根据数据情况自定义分割符,比如:你的事csv,自定义fields
注意两点:
看一下上面例子各个自定义介绍(例子默认的是默认分隔符):
csv是逗号分隔符:
列与列之间用逗号
数据库操作
hive的数据库创建
我们都知道hive是数据仓库,因为它不能对单条数据进行更改和删除
hive的数据库的创建语句: hive> CREATE DATABASE financials
最好加上IF NOT EXISTS判断一下,例如:
hive > CREATE DATABASE IF NOT EXISTS FINANCIALS
否则如果库存在则会报错。
注意,数据库创建完,在数据库所在的目录位于属性
hive.metastore.warehouse.dir所指定的顶层目录之后
hive不管是数据库还是表创建,记录是在关系数据库里面,并且还要在hdfs文件系统中生成一个文件夹,表示数据库或者表。
如下所述:
你也可以去手动修改存储在hdfs位置(建议不要修改),例如:
查数据库的详细信息:
切换数据库:use {dbname}
删除数据库:
注意后面的cascade,加上之后及时数据库有表也可以删除(强制删除)。如果不加,当数据库有表时,删除是不成功的。
二.HiveQL
数据定义
表创建
表创建,hive表分为内部表和外部表:内部表删除后数据也随着删除,外部表删除了数据还在。
创建内部表:
其中,location指定表的创建位置。注意:
我们可以复制已存在的表结构(仅仅是表结构,不包含数据)创建出一张新表
创建一个同样有数据的表:
create table name as select * from name
创建外部表:
注意:外部表要指定location,因为外部表都是指向有数据目录,当外部表删除的时候,并不影响,复制一张外部表:
备注:
表分区partition
表分区partition,表分区可以加快查询,创建表分区:
我们可以把parition当成一个过滤条件。
SELECT * FROM employees默认情况下是非严格模式的,如果有partition,你不加where过滤,也可以执行。但如果是严格模式,你不加where会报错
查看表分区:
查看特定一个分区:
从本地文件目录加载数据到内部表中,例如:
去掉local:从hdfs上move数据;local:copy本地数据到hive表
外部表同样可以创建分区表。例如:
分区表,外部表需要先创建好分区,然后在hdfs拷贝数据到目录下:
表删除
表删除语句:
注:对于管理表,表的元数据信息和表内的数据都会被删除,对于内部表,表的元数据信息会被删除,但是表中的数据不会被删除。
表的修改:修改就是针对原数据,大多数修改可以通过ALTER TABLE语句
表重名: ALTER TABLE name RENAME TO new_name
增加分区:
修改分区:
删除分区:
修改表列:
修改列位置:
增加列:
删除列:
修改存储属性:
数据操作
表的数据加载,动态分区,数据导出
表的数据加载
向内部表加载数据,因为hive没有行级插入更新和事务。
第一种方法只能整个文件copy到表目录下:
overwrite:覆盖;去掉overwrite:新增。
第二种方法是通过查询语句插入到新表:
第三种加载数据方法:load ,select,hdfs命令。
hive插入到分区表的时候可以用动态分区:默认情况下动态分区没有开启,需要我们手动配置开启,例如:
动态分区
开启动态分区,然后按照非严格模式执行,非严格模式时可以没有静态分区。
注意:如果有静态分区,一定在动态分区前面。
动态分区例子:它是按照后两位来动态分区的。
单个查询语句中创建表并加载数据:
导出数据
导出数据:有两种方法。
第一种用hdfs命令,直接拷贝到本地目录
第二种就是用sql来导出数据:
数据查询
select * from name 都用过在hive中from name a select a.* 这样子写也是对的。
查询的时候集合显示与使用:
查询数组
查询map:
查询struct:
数组类型使用:
map类型使用:
struct类型使用:
这里我们可以使用.*来匹配列:
hive的函数
hive的函数:
内置函数
数学函数(窗口函数)
聚合函数
表函数
对于不同的函数,我们可以自定义。
总结上面的函数可以分为三大类:
内置函数,数学函数都是一列一个值
聚合函数都是多列一个值
表函数是一列多个值比如处理集合列
所以我们可以自定义三种函数类型。hive的函数操作符:
数学函数
一个列返回一个值,例如:round()
数学函数表:
聚合函数
针对的是多列多行求一个值,如:
聚合函数的表:
表生成函数
一个集合类型生成多行多列,例如:
表生成函数的表:
避免不必要的mr程序:最好开启本地模式,例如:
select * from name 是不会走mr程序的,如果是分区表,条件是分区条件也不走mr程序。例如:
where查询
例如:
where后面的操作符:
like和rlike(hive独有rlike),其中like:模糊查询;rlike:通过java正则表达式指定条件。例如:
关键字rlike后面的字符串表达式如下定义:
字符串中的点号(.)表示和热议的字符匹配,星号(*)表示重复‘左边的字符串零次到无数次,表达式(x|y)’表示和x或者y匹配。
group by:和聚合函数配合使用,并且可以用having做分组结果过滤。
JOIN
join:分为内连接、外连接、全连接,hive中一定要用on做连接过滤,如果用where做匹配连接容易出现笛卡尔积,导致执行很慢。
内连接
join优化
hive查询的执行顺序是从左到右,一般是把左表缓存到共享缓存中,在map中做join加快执行速度,需要设置:hive.auto.convert.join=true
默认大小:
hive.mapjoin.smalltable.filesize=25000000
外连接和全连接
外连接分为left join和right join,与其他数据库基本一致。
全连接是两张表的记录都输出。
hive有两个特殊连接:左半开连接,map端连接。
左半开连接:输出左表记录,在右表已经存在的
例如:平常的sql
hive只能用左半开实现
排序
order by和sort by
order by:排序,order by是对全表排序效率比较慢,也就是最后结果是一个reducer执行。
sort by:只会在每个reducer中对数据进行排序,执行一个局部排序过程,这样可以保证每个reducer的输出都是有序的,但是并非全局有序。如果需求没有必要全部排序,可以用sort by局部排序。sort by 多个reducer输出需要设置reducer个数:
一般用sort by加上distribute by,可以保证全局有序。例如:
如果只对一个列这样排序,可以简写cluster by:cluster by代替了distribute by和sort by 对一个列排序组合。
注意:distribute by和sort by 或者cluster by会剥夺sort by 的并行性,这样实现输出文件全局有序。
视图
hive可以创建视图,视图只是保存sql语句并不在hdfs上创建目录,例如:
可以用if not exists 做视图是否存在判断,例如:
注意:
查询视图的时候先执行视图,视图后面跟的sql语句真实select,当语句为select * from view时,此时使用视图和使用表是一样的,删除视图:drop view if exists shipments。
查看视图:show tables(没有show views 语句)
桶
创建分区的时候创建的太多分区目录,这对hdfs压力很大,这个时候需要做桶,实际桶比分区查询速度快;
概念:桶表是对数据进行哈希取值,然后放到不同文件中存储。数据加载到桶表时,会对字段取hash值,然后与桶的数量取模。把数据放到对应的文件中。
物理上,每个桶就是表(或分区)目录里的一个文件,一个作业产生的桶(输出文件)和reduce任务个数相同
作用:桶表专门用于抽样查询,是很专业性的,需要抽样查询时,才创建和使用桶表。
优势:桶比分区查询效率要高,分桶就是把大表拆成小表过程,然后可以进行map端执行,并且分桶是默认排序的。
例子:
比如你的分区是2017,2017里面有一年的数据一个大文件大小为100g,做查询join的时候可以做map端join,map端join需要默认是25M,可以结合着分区,在分区里面做分桶,也就是把那大文件分成一块一块小文件。
创建带桶的表:
上图表示创建四个桶,桶是要指定的,首先开启使用桶:
向桶里面插入数据:
一般情况下分区和桶都是配合使用的,分桶是相对分区进行更细粒度的划分。分桶将整个数据内容安装某列属性值得到hash值进行分区,如果安装name属性分为3个桶,就是对name属性值的hash值对3取模,按照取模结果对数据分桶。例如:取模结果为0的数据记录存放到一个文件,取模为1的数据存放到一个文件……
注意:
第一,分桶之前要执行hive.enforce.bucketiong=true
第二,要使用关键字clustered by指定分区依据的列名,还要指定分为多少桶,这里指定分为3个桶。
第三,与分区不同的是,分区依据不是真实数据表文件中的列,而是我们指定的伪列,但是分桶是依据数据表中真实的列而不是伪列。所以在指定分区依据的列的时候要指定列的类型,因为在数据表文件中不存在这个列,相当于新建一个列。而分桶依据的是表中已经存在的列,这个列的数据类型显然是已知的,所以不需要指定列的类型。
如何使用分桶查询:
要指定关键字tablesample。用桶查询数据tablesample(bucket下标从1开始out of到第3个桶on 你之前指定分桶字段)
三.HiveQL:索引
创建索引
使用索引
Hive支持索引,但是Hive的索引与关系型数据库中的索引并不相同。比如,Hive不支持逐渐或者外检。Hive索引比较麻烦,而且有些文件格式不支持,所以不常用,但是他缺失提高查询速度。
Hive索引目的是提高Hive表指定列的查询速度。没有索引时,类似“WHERE tab1.col1=10”的查询,Hive会加重整张表或分区,然后处理所有的rows,但是如果在字段col1上面存在索引时,那么只会加载和处理文件的一部分。与其他传统数据库一样,增加索引在提升查询速度时,会消耗额外资源去创建索引和需要更多的磁盘空间存储索引。Hive 0.7.0版本中,加入了索引。Hive 0.8.0版本中增加了bitmap索引。
创建索引
with defered rebuild 延迟重建,创建的时候并不赋值,后面通过:
hive的索引就是根据给定字段,放到一个新的索引表里面,保存表名,字段名和文件路径。
左边是你自己表,右边是生成的索引表,索引表中key:原表中key字段的值。
_bucketname:代表数据文件对于的HDFS文件路径,
_offsets:代表该key值在文件中的偏移量。可能有多个偏移量。所以字段类型为数组。所以利用索引可以直接定位到你想要的数据文件,不会扫描全表。
使用索引
使用索引,首先设置
然后查询:
注意
每次查询时候都要先用一个job扫描索引表,如果索引列的值非常稀疏,那么索引表本身也会非常大;
索引表不会自动rebuild,如果报有数据新增或删除,那么必须手动rebuild索引表数据。
查询索引列
首先扫描索引表知道列名对应值,然后知道对应文件路径,直接去加载文件,省去扫描全部表。加快查询速度
根据值直接插到路径,然后去加载对应文件就可以了
四.Hive优化
常见优化
hive数据倾斜
Hive压缩
常见优化
explain关键字:
hive优化实际上是hadoop的map reduce优化,首先我们需要知道一条sql语句执行了哪几个步骤,hive和传统关系数据库一样也有个执行计划,用explain关键字可以卡到完整的执行步骤。本地模式
当输入数据小于250M时候没人不调用mapreduce,直接在本地机器执行计算。
hive.exec.mode.local.auto=true并行模式
执行一条sql的时候分成步骤,有时候不是关联的,这种情况下可以并行执行。
开启:hive.exec.parallel=true,这个默认是关闭的。严格模式
hive默认情况下是不严格模式。严格模式是对sql执行有要求。对于表分区查询的时候必须where不分区字段,必须指定表分区限制
order by必须加limit限制
join的时候必须用on 关联,不能用where关联,用where会进行笛卡尔积
调整map和reduce个数
jvm重用
在hadoop2中是uber模式推测执行
最好关掉。默认是开启join优化:如果有小表,我们开启join优化,可以进行map端join。hive.auto.convert.join=ture,小表放在左边。
hive数据倾斜
Hive压缩
查看现有压缩包有哪几种
这里显示了四种:gzip,bzip,默认,snappy。最好的压缩格式是snappy,空间时间比较均衡,hive的压缩和hadoop是一样,有中间压缩和输出压缩。
压缩优点:减少空间
压缩缺点:不能分割和消耗cpu。如果想分割根据大小文件来压缩。
中间压缩
hive的中间压缩的设置:可以在hive中设置,也可以在hadoop中设置,如果hadoop设置了hive就不需要设置了。
我们来看在hive开启中间压缩hive-site.xml
开启以后如果不选择压缩格式就是没人压缩,一般情况下我们都要选择压缩格式。
如果hadoop里面配置了,就不需要再配置了。配置如下:hive-site.xml
这些配置也可以在执行sql的时候配置:配置hive环境变量用set
例如:
输出结果压缩
hive和hadoop一样都可以对输出结果进行压缩,如果hadoop设置了hive就不用设置了,如果没有,可以用hive进行设置,在hive-site.xml中添加:
这是在配置文件中添加,我们也可以在执行语句的时候添加:
直接在执行的set对这两个变量进行赋值,这种方法只对这个对话有效,配置文件对整个hive有效,如果设置hadoop中所有使用hadoop引擎的都有效。
hadoop内置的一种为了压缩可分割的文件格式是:sequence文件
用sequence文件我们可以指定压缩方法,比如按照行来压缩,按照block来压缩。
hadoop中可以设置的,hive的配置文件设置是:
按照block压缩也就是128压缩一次,这个同样可以用set执行语句的时候设置
parquet
现在有一种比较好的文件格式parquet,hadoop本身不支持,需要额外jar包。
Parquet是面向分析型业务的列式存储格式。
列式存储
列式存储和行式存储相比有哪些优势:
可以通过不符合条件的数据,只读取需要的数据,降低IO数据量
压缩编码可以降低磁盘存储空间,由于同一列的数据类型是一样的,可以使用更高效的压缩编码。进一步节约存储空间。
只读取需要的列,支持向量运算,能够获取更好的扫描性能。
大数据总结系列文章:
以上是关于Hive知识总结的主要内容,如果未能解决你的问题,请参考以下文章