对hive的简介和理解
在公司,基本上大部分的查询都是在hive上进行的。基于自己天天和hive打交道,有感而发,所以有了想写这篇文章的意愿。
如果用一句话来解释hive是什么和能做什么,那就是:hive是基于Hadoop的一个数据仓库。因此,要理解hive,就要先去了解Hadoop和它相关的MapReduce,以及数据仓库。对于Hadoop和MapReduce,读者可以先去网上查一下。对于数据仓库的理解,我之前写了一篇关于数据仓库的文章,读者也可以去看一下。
具体而言,hive就是在Hadoop上架了一层SQL接口,可以将SQL翻译成MapReduce,然后拿到Hadoop上去执行。这样就使得数据开发和分析人员能很方便地使用SQL来完成海量数据的统计和分析,而不必使用编程语言开发MapReduce那么麻烦了。
hive的内部表和外部表
hive中的表分为内部表和外部表。内部表的数据由hive自身管理,而外部表由HDFS管理。关于内部表和外部表的区别,具体如下:
区别 | 内部表 | 外部表 |
---|---|---|
存储位置 | 内部表数据的存储位置是hive.metastore.warehouse.dir | 外部表数据的存储位置由自己决定 |
修改 | 对内部表的修改将直接同步给元数据 | 对外部表的表结构和分区进行修改,则需要修复 |
删除 | 删除内部表会直接删除元数据(metadata)及存储数据 | 删除外部表仅仅会删除元数据,HDFS上的文件并不会删除 |
适用场景 | 内部表适用于Hive中间表、结果表,一般不需要从外部(如本地文件、HDFS上load数据) | 外部表适用于源表,需要定期将外部数据映射到表中 |
一般来说,hive内部表和外部表的分工是这样的:
1、我们每天将收集到的网站日志定期流入HDFS文本文件,一天一个目录;
2、在Hive中建立外部表作为源表,通过添加分区的方式,将每天HDFS上的原始日志映射到外部表的天分区中;
3、在外部表(原始日志表)的基础上做大量的统计分析,用到的中间表、结果表使用内部表存储,数据通过SELECT+INSERT进入内部表。
hive和hbase的对比
总的来说,hbase和Hive在大数据架构中处在不同位置,hbase主要解决实时数据查询问题,hive主要解决数据处理和计算问题。他们两的区别如下:
1、Hbase: Hadoop database 的简称,也就是基于Hadoop数据库,是一种NoSQL数据库,主要适用于海量明细数据(十亿、百亿)的随机实时查询,如日志明细、交易清单、轨迹行为等。
2、Hive:Hive是Hadoop数据仓库,严格来说,不是数据库,主要是让开发人员能够通过SQL来计算和处理HDFS上的结构化数据,适用于离线的批量数据计算。
hive中的数据类型
hive中的数据类型分为基本数据类型和复合数据类型。
基本数据类型包括:
hive中的基本数据类型 | |
---|---|
整型 | TINYINT ; SMALLINT ; INT ;BIGINT |
布尔型 | BOOLEAN — TRUE/FALSE |
浮点型 | FLOAT– 单精度浮点数;DOUBLE– 双精度浮点数 |
字符串型 | STRING– 不设定长度 |
日期型 | date |
hive中的复合数据类型包括三种:
1、Structs:一组由任意数据类型组成的结构。比如,定义一个字段C的类型为STRUCT {a INT; b STRING},则可以使用a和C.b来获取其中的元素值;
2、Maps:和Java中的Map没什么区别,就是存储K-V对的;
3、Arrays:就是数组而已;
这里列举一个在hive上建表的例子:
create table tmp_table(
id int,
name string,
score map<string,int>)partitioned by(day date)
stored as orc
在hive上建表需要注意两点:
1、关键字stored as :
指定表在HDFS上的文件存储格式,可选的文件存储格式有:
(1)TEXTFILE :文本,默认值
(2)SEQUENCEFILE :二进制序列文件
(3)RCFILE :列式存储格式文件
(4)ORC :列式存储格式文件,比RCFILE有更高的压缩比和读写效率,Hive0.11以后开始支持
2、关键字partitioned by :
表示该表为分区表,分区字段为day,类型为date.
hive的使用
常用的hive语句和函数
hive中对表的操作
1、增加字段:
ALTER TABLE table name add columns(字段名 字段类型) – (不能指定位置,只能添加到最后,分区字段之前)
alter table tmp_table
add columns(teacher string)
2、修改字段名:
ALTER TABLE table name change 修改前字段名 修改后字段名 字段类型 after 前一个字段名
alter table tmp_table
change name student_name string
after id
3、修改表名:
ALTER TABLE XXX rename to XX
4、删除分区字段:
ALTER TABLE table_name DROP IF EXISTS PARTITION(分区字段 =值)
alter table tmp_table
drop if exists partition(day='2020-07-29')
hive中的常用函数
其实,很多MySQL上能用的函数,在hive也能使用,不过可以具体的语法有些差异。因此,对于MySQL和hive都能使用的函数,这里就不再赘述。我这里主要列举一些在hive上的特有函数。
1、拼接函数:
(1)concat(str1,str2,str3)——将str1、str2和str3拼接起来;
select concat('2016','-','11','24')
输出:'2016-1124'
(2)concat_ws(del,str1,str2,str3)——以指定分隔符del将将str1、str2和str3拼接起来;
select concat_ws('-','2016','11','24')
输出:'2016-11-24'
2、替换函数:regexp_replace(str,需替换内容,替换内容)
select regexp_replace('xiao|mi','\\|','&')
输出:'xiao&mi'
hive中实现行列转置
1、hive中行转列:explode()
2、hive中列转行:
**collect_set()**列去重之后,转行
collect_list():列不去重之后,转行
对于这三个函数的用法,这里我会举一个例子来说明他们是如何使用的:
首先,这里在hive建了一个分区表,表的结构和内容如下:
create table t_student(
name string,
course string)partitioned by (day date)
stored as orc
表的内容:
'张三' '英语' '2020-07-29'
'张三' '语文' '2020-07-29'
'张三' '英语' '2020-07-30'
'李四' '数学' '2020-07-30'
'李四' '英语' '2020-07-30'
collect_list()函数可以实现列转行,且不去重,具体用法如下:
select name,collect_list(course) from t_student
group by name
输出:
'张三' ['英语','语文','英语']
'李四' ['数学','英语']
select collect_list(course) from t_student
输出:
['英语','语文','英语','数学','英语']
collect_set()函数可以实现列转行,且去重,具体用法如下:
select name,collect_set(course) from t_student
group by name
输出:
'张三' ['英语','语文']
'李四' ['数学','英语']
explode()函数可以实现行转列,具体用法如下:
select explode(course_1)
from(
select collect_list(course) as course_1
from t_student
) t
输出:
'英语'
'语文'
'英语'
'数学'
'英语'
hive中json的解析
hive中关于json解析的函数,主要有以下四个:
(1)get_json_object(json串字段,需要获取的内容)
--line={"email":'xiaoming@163.com',"owner":'xiaoming'}
select get_json_object(line,'$.owner')
输出:'xiaoming'
这里只列举了get_json_object最简单的用法,更多更复杂的用法可以自行百度。
(2)json_tuple(json串,字段1,字段2,……) :一次性解析json串中的多个内容
(3)parse_url(url,内容) : 提取url中的内容 Partname: HOST, PATH, QUERY, REF, PROTOCOL, AUTHORITY, FILE, USERINFO, QUERY:<KEY_NAME>
具体用法如下:
select parse_url('http://facebook.com/path/p1.php?query=1&name=3', 'QUERY')
输出:'query=1&name=3'
(4)parse_url_tuple(url,内容1,内容2,……) : 同时解析url中的多个内容
参考:
1、https://blog.csdn.net/qq_36743482/article/details/78393678
2、https://www.zhihu.com/question/21677041/answer/185664626