Hive入门概述

Hive入门概述,第1张

11 什么是Hive

Hive:由Facebook开源用于解决海量结构化日志的数据统计。

Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能。本质是:将HQL转化成MapReduce程序

Hive处理的数据存储在HDFS

Hive分析数据底层的实现是MapReduce

执行程序运行在Yarn上

12 Hive的优缺点

121 优点

*** 作接口采用类SQL语法,提供快速开发的能力(简单、容易上手)。

避免了去写MapReduce,减少开发人员的学习成本。

Hive的执行延迟比较高,因此Hive常用于数据分析,对实时性要求不高的场合。

Hive优势在于处理大数据,对于处理小数据没有优势,因为Hive的执行延迟比较高。

Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。

122 缺点

1.Hive的HQL表达能力有限

(1)迭代式算法无法表达

(2)数据挖掘方面不擅长

2.Hive的效率比较低

(1)Hive自动生成的MapReduce作业,通常情况下不够智能化

(2)Hive调优比较困难,粒度较粗

13 Hive架构原理

1.用户接口:Client

CLI(hive shell)、JDBC/ODBC(java访问hive)、WEBUI(浏览器访问hive)

2.元数据:Metastore

元数据包括:表名、表所属的数据库(默认是default)、表的拥有者、列/分区字段、表的类型(是否是外部表)、表的数据所在目录等;

默认存储在自带的derby数据库中,推荐使用MySQL替代derby存储Metastore

3.Hadoop

使用HDFS进行存储,使用MapReduce进行计算。

4.驱动器:Driver

(1)解析器(SQL Parser):将SQL字符串转换成抽象语法树AST,这一步一般都用第三方工具库完成,比如antlr;对AST进行语法分析,比如表是否存在、字段是否存在、SQL语义是否有误。

(2)编译器(Physical Plan):将AST编译生成逻辑执行计划。

(3)优化器(Query Optimizer):对逻辑执行计划进行优化。

(4)执行器(Execution):把逻辑执行计划转换成可以运行的物理计划。对于Hive来说,就是MR/Spark。

Hive通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的Driver,结合元数据(MetaStore),将这些指令翻译成MapReduce,提交到Hadoop中执行,最后,将执行返回的结果输出到用户交互接口。

14 Hive和数据库比较

由于 Hive 采用了类似SQL 的查询语言 HQL(Hive Query Language),因此很容易将 Hive 理解为数据库。其实从结构上来看,Hive 和数据库除了拥有类似的查询语言,再无类似之处。本文将从多个方面来阐述 Hive 和数据库的差异。数据库可以用在 Online 的应用中,但是Hive 是为数据仓库而设计的,清楚这一点,有助于从应用角度理解 Hive 的特性。

141 查询语言

由于SQL被广泛的应用在数据仓库中,因此,专门针对Hive的特性设计了类SQL的查询语言HQL。熟悉SQL开发的开发者可以很方便的使用Hive进行开发。

142 数据存储位置

Hive 是建立在 Hadoop 之上的,所有 Hive 的数据都是存储在 HDFS 中的。而数据库则可以将数据保存在块设备或者本地文件系统中。

143 数据更新

由于Hive是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。因此,Hive中不建议对数据的改写,所有的数据都是在加载的时候确定好的。而数据库中的数据通常是需要经常进行修改的,因此可以使用 INSERT INTO … VALUES 添加数据,使用 UPDATE … SET修改数据。

144 索引

Hive在加载数据的过程中不会对数据进行任何处理,甚至不会对数据进行扫描,因此也没有对数据中的某些Key建立索引。Hive要访问数据中满足条件的特定值时,需要暴力扫描整个数据,因此访问延迟较高。由于 MapReduce 的引入, Hive 可以并行访问数据,因此即使没有索引,对于大数据量的访问,Hive 仍然可以体现出优势。数据库中,通常会针对一个或者几个列建立索引,因此对于少量的特定条件的数据的访问,数据库可以有很高的效率,较低的延迟。由于数据的访问延迟较高,决定了 Hive 不适合在线数据查询。

145 执行

Hive中大多数查询的执行是通过 Hadoop 提供的 MapReduce 来实现的。而数据库通常有自己的执行引擎。

146 执行延迟

Hive 在查询数据的时候,由于没有索引,需要扫描整个表,因此延迟较高。另外一个导致 Hive 执行延迟高的因素是 MapReduce框架。由于MapReduce 本身具有较高的延迟,因此在利用MapReduce 执行Hive查询时,也会有较高的延迟。相对的,数据库的执行延迟较低。当然,这个低是有条件的,即数据规模较小,当数据规模大到超过数据库的处理能力的时候,Hive的并行计算显然能体现出优势。

147 可扩展性

由于Hive是建立在Hadoop之上的,因此Hive的可扩展性是和Hadoop的可扩展性是一致的(世界上最大的Hadoop 集群在 Yahoo!,2009年的规模在4000 台节点左右)。而数据库由于 ACID 语义的严格限制,扩展行非常有限。目前最先进的并行数据库 Oracle 在理论上的扩展能力也只有100台左右。

148 数据规模

由于Hive建立在集群上并可以利用MapReduce进行并行计算,因此可以支持很大规模的数据;对应的,数据库可以支持的数据规模较小。

统计 谷粒视频 网站的常规指标,各种 TopN 指标:

对将要处理的数据先进行一次数据清洗,过滤掉不合格的脏数据,同时调整数据的格式

pomxml

ETLUtilMapperjava

ETLUtilDriverjava

处理前数据

处理后数据

gulivideo_ori

guli_user_ori

321 将表中category字段数组行转列

select views,hot from

gulivideo_orc lateral view explode (category) category_t as hot;t1

322 统计每个类别的观看总数

select hot,count()

from t1

group by hot;t2

323 获取观看前10的类别

select hot,total_view

from ()t2

order by total_view desc limit 10;

331 观看数top20视频

select views,category

from gulivideo_orc

order by views desc

limit 20;t1

332 所属类别

select views,category

from t1 lateral view explode(category)ct as category_name;

341 观看数top10,关联视频

select

videoid,views,category,relatedid

from

gulivideo_orc

order by

views desc

limit 50;t1

342 关联视频行转列

select distinct(r_id)

from

t1 lateral view explode(relatedid) relatedtable as r_id;t2

343 视频所属类别

select r_id,gcategory

from

t2join gulivideo_orc g on r_id = gvideoid;t3

select r_id,gcategory

from

t2 join gulivideo_orc g on r_id = gvideoid;t3

344 类别展开

select category_name

from ()t3 lateral view explode(category)t as category_name;t4

345 统计类别个数

select category_name,count() hot

from

t4 group by category_name,t_sum;t5

346 所属类别排名

select from

t5

order by hot desc;t6

1找出上传前10的用户

select uploader,

videos

from

guli_user_orc

order by videos desc

limit 10;t1

2找到上传的所有视频

select t1uploader,

videoid,

views

from

()t1 join gulivideo_orc g

on

tuploader=guploader

order by uploader,views desc; t2

1统计所有类别对应的视频

select

category_name,videoid,views

from

gulivideo_orc

lateral view explode(category) t as category_name;t1

2对每个类观看数排名

select ,rank() over(partition by category_name order by views desc) rank_no

from

()t1;t2

3取前十

select from

()t2

where rank_no<=10;

传送门

hadoop入门系列--hive基础

hadoop入门系列--hive的三种集合数据类型array、map、struct以及自定义分隔符示例

hadoop入门系列--hive中array(或map集合类型)的行转多列LATERAL VIEW explode用法

传送门

在做hive相关练习时,遇到这个看不懂。lateral view explode(category) t_catetory as category_name

示例数据:

练习:

1143 统计出视频观看数最高的 20 个视频的所属类别以及类别包含

Top20 视频的个数

思路:

类别1: 7

类别2: 3

explode称之为Hive爆炸函数,意思就是将一行数据炸开。

Usage:explode(array/map) explode函数传递的参数必须是一个array或者是map。

一、具体例子进行实践

现在有一张表有以下字段

需要将cureses转成列的形式。

二、扩展

上面可以看到表中还有一个用户ID,正常情况下肯定是用户对应课程的。正常的想法是以下的SQL

但是执行会报错

通常工作中,explode会结合laderal view使用。因为我们不可能只取explode里面的值,还要取其他的字段。

那么正常SQL应该是下面的

大家好呀,这节课学习 HiveSQL 的常用优化技巧。由于 Hive 主要用来处理非常大的数据,运行过程由于通常要经过 MapReduce 的过程,因此不像 MySQL 一样很快出结果。而使用不同方法写出来的 HiveSQL 语句执行效率也是不一样的,因此为了减少等待的时间,提高服务器的运行效率,我们需要在 HiveSQL 的语句上进行一些优化。

本节课的主要内容

引言

1、技巧一:列裁剪和分区裁剪

(1)列裁剪

(2)分区裁剪

2、技巧二:排序技巧——sort by代替order by

3、技巧三:去重技巧——用group by来替换distinct

4、技巧四:聚合技巧——grouping sets、cube、rollup

(1)grouping sets

(2)cube

(3)rollup

5、技巧五:换个思路解题

6、技巧六:union all时可以开启并发执行

7、技巧七:表连接优化

8、技巧八:遵循严格模式

Hive 作为大数据领域常用的数据仓库组件,在平时设计和查询时要特别注意效率。影响Hive效率的几乎从不是数据量过大,而是数据倾斜、数据冗余、job 或 I/O 过多、MapReduce 分配不合理等等。对 Hive 的调优既包含对HiveSQL 语句本身的优化,也包含 Hive 配置项和 MR 方面的调整。

列裁剪就是在查询时只读取需要的列。当列很多或者数据量很大时,如果select 所有的列或者不指定分区,导致的全表扫描和全分区扫描效率都很低。Hive中与列裁剪优化相关的配置项是 hiveoptimizecp ,默认是 true 。

分区裁剪就是在查询时只读需要的分区。Hive中与分区裁剪优化相关的则是 hiveoptimizepruner ,默认是 true 。

HiveSQL中的 order by 与其他 SQL 语言中的功能一样,就是将结果按某个字段全局排序,这会导致所有map端数据都进入一个 reduce 中,在数据量大时可能会长时间计算不完。

如果使用 sort by ,那么就会视情况启动多个 reducer 进行排序,并且保证每个 reducer 内局部有序。为了控制 map 端数据分配到 reduce 的 key,往往还要配合 distribute by 一同使用。如果不加 distribute by 的话,map 端数据就会随机分配给 reducer。

这里需要解释一下, distribute by 和 sort by 结合使用是如何相较于 order by 提升运行效率的。

假如我们要对一张很大的用户信息表按照年龄进行分组,优化前的写法是直接 order by age 。使用 distribute by 和 sort by 结合进行优化的时候, sort by 后面还是 age 这个排序字段, distribute by 后面选择一个没有重复值的均匀字段,比如 user_id 。

这样做的原因是,通常用户的年龄分布是不均匀的,比如20岁以下和50岁以上的人非常少,中间几个年龄段的人又非常多,在 Map 阶段就会造成有些任务很大,有些任务很小。那通过 distribute by 一个均匀字段,就可以让系统均匀地进行“分桶”,对每个桶进行排序,最后再组合,这样就能从整体上提升 MapReduce 的效率。

取出 user_trade 表中全部支付用户:

原有写法的执行时长:

优化写法的执行时长:

考虑对之前的案例进行优化:

注意: 在极大的数据量(且很多重复值)时,可以先 group by 去重,再 count() 计数,效率高于直接 count(distinct ) 。

如果我们想知道用户的性别分布、城市分布、等级分布,你会怎么写?

通常写法:

缺点 :要分别写三次SQL,需要执行三次,重复工作,且费时。

那该怎么优化呢?

注意 :这个聚合结果相当于纵向地堆在一起了(Union all),分类字段用不同列来进行区分,也就是每一行数据都包含 4 列,前三列是分类字段,最后一列是聚合计算的结果。

GROUPING SETS() :在 group by 查询中,根据不同的维度组合进行聚合,等价于将不同维度的 group by 结果集进行 union all。聚合规则在括号中进行指定。

如果我们想知道用户的性别分布以及每个性别的城市分布,你会怎么写?

那该怎么优化呢?

注意: 第二列为NULL的,就是性别的用户分布,其余有城市的均为每个性别的城市分布。

cube:根据 group by 维度的所有组合进行聚合

注意 :跑完数据后,整理很关键!!!

rollup:以最左侧的维度为主,进行层级聚合,是cube的子集。

如果我想同时计算出,每个月的支付金额,以及每年的总支付金额,该怎么办?

那应该如何优化呢?

条条大路通罗马,写SQL亦是如此,能达到同样效果的SQL有很多种,要学会思路转换,灵活应用。

来看一个我们之前做过的案例:

有没有别的写法呢?

Hive 中互相没有依赖关系的 job 间是可以并行执行的,最典型的就是

多个子查询union all。在集群资源相对充足的情况下,可以开启并

行执行。参数设置: set hiveexecparallel=true;

时间对比:

所谓严格模式,就是强制不允许用户执行3种有风险的 HiveSQL 语句,一旦执行会直接报错。

要开启严格模式,需要将参数 hivemapredmode 设为 strict 。

好啦,这节课的内容就是这些。以上优化技巧需要大家在平时的练习和使用中有意识地去注意自己的语句,不断改进,就能掌握最优的写法。

1:启动集群中所有的组件

cd /export/onekey

/start-allsh

2:使用终端连接Hive

3:打开 beeline 前先输入以下命令

:star2: 在大数据中,最常用的一种思想就是分治,分区表实际就是对应hdfs文件系统上的的独立的文件夹,该文件夹下是 该分区所有数据文件。

:star2:分区可以理解为分类,通过分类把不同类型的数据放到不同的目录下。

:star2:Hive中可以创建一级分区表,也可以创建多级分区表

:star2:根据内外部表可区分出==分区内部表==、==分区外部表==

1创建分区表

2加载数据

1可见分区字段会显示在表中,但是它并不是真实存在于表的字段

2加载同一等级不同分区的数据

3这时可以指定分区字段值当作筛选条件分区表和where联动

1创建多级分区表

2加载数据

1加载同一等级不同分区的数据

2指定分区字段值当作筛选条件分区表和where联动

定义 :Array是数组类型,Array中存放相同类型的数据。

语法: concat_ws(string SEP, string A, string B…)

说明:返回输入字符串连接后的结果,SEP表示各个字符串间的分隔符

举例:

语法:

substr(string A, int start, int len), --start是顺序

substring(string A, int start, int len) -- start可以是逆序即负数

返回值:

string 说明:返回字符串A从start位置开始,长度为len的字符串

举例:

语法: year(string date)

说明:返回日期中的年。

举例:

语法: date_add(string startdate, int days)

说明:返回开始日期startdate增加days天后的日期。

举例:

语法: date_sub (string startdate, int days)

返回值: string 说明:返回开始日期startdate减少days天后的日期。

举例:

行转列是指多行数据转换为一个列的字段。

Hive行转列用到的函数:

concat_ws(sep, str1,str2) --以分隔符拼接每个字符串

collect_set(col) --将某字段的值进行去重汇总,产生array类型字段

示例:

生产中只用rank和dense_rank,row_number不合理

rank() 输出的排名 (1,2,3,3,5)

dense_rank() 输出的排名 (1,2,3,3,4)

示例:

用于== 实现分组内所有和连续累积的统计 ==

Apache Zeppelin是一款基于Web交互式框架,支持多种语言,提供了== 数据分析 ==、 ==数据可视化== 功能。

使用Zeppelin来连接到Spark SQL的Thrift Server,可以以更直观的方式来查看Hive中的数据。而且Zeppelin也可以以图表的方式展示数据。

使用Zeppelin来连接到Spark SQL的Thrift Server的好处有两个:

1原始日志数据会存放在临时存储层ODS层

2预处理数据会放在数据仓库DW层

3分析得到的结果数据放在应用层APP层

case有两种写法,但是只用记住第二种写法

case when then

end

:star:

解决办法来自: >

大家好呀,这节课我们学习 Hive 核心技能中最难的部分——窗口函数。窗口函数我们之前在学 MySQL 的时候有学过一些,但是只学了三个排序的窗口函数。这节课我们会学习更多的窗口函数,包括累计计算、分区排序、切片排序以及偏移分析。

在正式学习之前,我们需要先明确一下窗口函数和GROUP BY分组的区别。二者在功能上有相似之处,但是它们存在本质区别。

1 分组会改变表的结构,而窗口函数不会改变表的结构。比如原表有10行数据,分成两组后只有两行,而窗口函数仍然返回十行数据。

2 分组只能查询分组后的字段,包括分组字段(组名)和聚合函数字段。而窗口函数对查询字段没有限制,也就是可以查询原表的任意字段,再加上窗口函数新增的一列值。

好啦,现在让我们一起进入窗口函数的世界吧~

本节课主要内容:

1、累计计算窗口函数

(1)sum(…) over(……)

(2)avg(…) over(……)

(3)语法总结

2、分区排序窗口函数

(1)row_number()

(2)rank()

(3)dense_rank()

3、切片排序窗口函数

(1)ntile(n) over(……)

4、偏移分析窗口函数

5、重点练习

大家在做报表的时候,经常会遇到计算截止某月的累计数值,通常在EXCEL里可以通过函数来实现。

那么在HiveSQL里,该如何实现这种累计数值的计算呢?那就是利用窗口函数!

关于窗口函数的几点说明:

需求分析 :既然要进行按月累计,我们就先要把2018年的每笔交易时间转换成月并按月分组聚合计算,得出一个2018年每月支付金额总合表,再基于这张表用窗口函数进行累计计算。

2018年每月支付金额总和表:

再用窗口函数进行月度累计:

年度进行汇总。

这个需求比需求1多了一个需求,那就是年度汇总。那我们只需要在上个需求的子查询中加一个 year 字段即可。

说明:

1、over 中的 partition by 起到了窗口内将数据分组的作用。事实上,加上partition by之后,可以理解为分成了多个窗口,并在每个窗口内进行累加计算或者分区。

如果不加 partition by ayear 的话,运行结果就是这样单纯按月份进行分组的:

2、order by 按照什么顺序进行累加,升序ASC、降序DESC,默认是升序。

大家看股票的时候,经常会看到这种K线图,里面经常用到的就是7日、30日移动平均的趋势图,那如何使用窗口函数来计算移动平均值呢?

需求分析 :这个需求要求每个月近三个月的移动平均支付金额,这里我们要用到一个新知识点,在窗口函数 avg over 的 order by amonth 之后加一句 rows between 2 preceding and current row 来设定计算移动平均的范围,这个语句的含义就是包含本行及前两行。其他部分的写法跟前面的需求类似,先取出2018年每个月的支付金额总和,再用窗口函数求移动平均。

注意:

sum(…A…) over(partition by …B… order by …C… rows between …D1… and …D2…)

avg(…A…) over(partition by …B… order by …C… rows between…D1… and …D2…)

A:需要被加工的字段名称

B:分组的字段名称

C:排序的字段名称

D:计算的行数范围

rows between unbounded preceding and current row

——包括本行和之前所有的行

rows between current row and unbounded following

——包括本行和之后所有的行

rows between 3 preceding and current row

——包括本行以内和前三行

rows between 3 preceding and 1 following

——从前三行到下一行(5行)

max(……) over(partition by …… order by …… rows between ……and ……)

min(……) over(partition by …… order by …… rows between ……and ……)

row_number() 、rank()、dense_rank()

用法:这三个函数的作用都是返回相应规则的排序序号

row_number() over(partition by …A… order by …B… )

rank() over(partition by …A… order by …B… )

dense_rank() over(partition by …A… order by …B… )

A:分组的字段名称

B:排序的字段名称

注意: 这3个函数的括号内是不加任何字段名称的!

row_number :它会为查询出来的每一行记录生成一个序号,依次排序且不会重复。

rank&dense_rank :在各个分组内, rank() 是跳跃排序,有两个第一名时接下来就是第三名, dense_rank() 是连续排序,有两个第一名时仍然跟着第二名。

实例练习:

再眼熟一下 user_trade 的表结构:

需求分析 :先限定时间范围,然后根据 user_name 进行分组,接着选出 分组去重后的 user_name,并计算每个用户 goods_category 的数量(记得 distinct 去重),再然后就是用窗口函数对 goods_category 的数量进行排序,当然选择哪一种排序方法要看具体要求,这里我们可以三种方法都试一下看看结果:

注意 :窗口函数中的 order by 字段不能用 select 中字段的重命名,因为二者是同时执行的。

需求分析 : 先用窗口函数将2019年每个用户的支付总金额算出来并进行排序,再以此作为子查询,从中取出排名在第10、20、30名的用户名、支付总金额以及排名次序。企业一般会使用 dense_rank 进行排序,所以我们这里直接用 dense_rank。

2019年每个用户的支付总金额排名:

2019年支付金额排名在第10、20、30名的用户:

ntile(n) over(partition by …A… order by …B… )

n:切分的片数

A:分组的字段名称

B:排序的字段名称

需求分析 :这个需求很简单,把需求5第一步的排序窗口函数变成切片即可。注意时间筛选条件变成2019年1月。

需求分析 : 排名前10%,也就是一共分成10组,取第1组。那么我们先切片分组:

然后再取第一组:

说明:Lag和Lead分析函数可以在同一次查询中取出同一字段的前N行的数据(Lag)和后N行的数据(Lead)作为独立的列。

在实际应用当中,若要用到取今天和昨天的某字段差值时,Lag和Lead函数的应用就显得尤为重要。当然,这种 *** 作可以用表的自连接实现,但是LAG和LEAD与left join、right join等自连接相比,效率更高,SQL语句更简洁。

lag(exp_str,offset,defval) over(partion by ……order by ……)

lead(exp_str,offset,defval) over(partion by ……order by ……)

lag() 函数示例:

lead() 函数示例:

需求分析: 先要从 user_trade 表中取出每个用户的支付时间,把每个用户放到一个窗口中,按照支付时间进行排序,取出偏移列: lead(dt,1,dt) over(partition by user_name order by dt)。接着基于该子查询,筛选出时间间隔大于100天的用户,并计算数量。

注意 : 如果上面偏移分析函数写成 lead(dt,1,dt) 就不用加后面的 dt is not null 了,因为有默认值的话,间隔就是0,肯定是不满足条件的。

需求分析

第一步 :这个需求要用到 user_trade 和 user_info 两张表,前者取支付时间和金额,后者取城市和性别。先对这两张表基于 user_name 进行左连接,并取出相应字段,用窗口函数进行分组排序:

这一步的运行结果是这样的:

第二步 :基于上述结果取出TOP3:

需求分析:

第一步 :这个需求同样要用到两张表 user_refund 和 user_info。我们先把每个退款用户的退款金额和手机品牌取出来,并用窗口函数进行切片排序,25%就是分成4片:

注意 :这里之所以要加 WHERE dt is not null 是因为 user_refund 是一个分区表,分区表要对分区字段进行限制,否则 hive 会报错。

第二步 :选择前25%,也就是第一片:

最后补充一个从 hive 导出结果数据的命令:

以上就是这节课的全部内容了。做完整个练习,真的半条命都没了。窗口函数果然很难,不过掌握方法、多多练习,学会拆解需求,一步一步来做,就能明显降低难度。希望以后有机会能用到这么复杂的技能,哈哈~!

以上就是关于Hive入门概述全部的内容,包括:Hive入门概述、Hive实战项目——影音网站数据分析、hadoop入门系列--hive中array(或map集合类型)的行转多列LATERAL VIEW explode用法等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9675085.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-30
下一篇2023-04-30

发表评论

登录后才能评论

评论列表(0条)

    保存