大数据学习10之Hive高级
1.Hive高级
将大的文件按照某一列属性进行GROUP BY 就是分区,只是默认开窗存储;
分区是按行,如一百行数据,按十位上的数字分区,则有十个分区,每个分区里有十行;
分桶是根据某个字段哈希对桶数取余,相同值的放同一个桶里。
分桶里的数据不是某个字段都相同,分区是;
1.1分区
1.1.1静态分区
即手动将一个大数据量的文件,即表文件,按某个字段分成多个文件,多个表,默认最大是一百个分区
建表时使用 PARTITION BY(part int)指定分区字段,并且分区的字段不包含在建表字段中,但表创建后会包括分区字段,建表后根据分区路径载入手动分区后的表文件。
1.1.2动态分区
由MapReduce执行操作时根据数据内容的特点量级进行数据的分区
1.1.2.1严格分区
通过 hive.mapred.mode=(strict/nostrict)设置严格模式和非严格模式
严格模式:
因为分区后不带分区指定参数去查询全表数据,效率比直接查询全表数据更低,为了防止这种查询,严格模式就禁止了创建了分区的表进行不带分区参数的全表查询
1.1.2.2载入数据
-- 从本地载入
LOAD DATA LOCAL INPATH '/root/teacher.txt' INTO TABLE t_teacher_d;
-- 从 HDFS 载入
LOAD DATA INPATH '/teacher.txt' INTO TABLE t_teacher_d;
-- 通过查询载入
INSERT INTO OVERWRITE TABLE t_teacher_d PARTITION (grade, clazz) SELECT * FROM t_teacher;
1.1.3外部分区表
与内部分区表的分区操作相同,只是外部分区表在删除时只会删除元数据映射,而不会真的删除表的数据。
1.2分桶
1.2.1原理
如,分10桶,对id列计算hash值 然后 hash(id)%10 ,相同结果的放同一个桶里
计算公式: bucket num = hash_function(bucketing_column) mod num_buckets 。
1.2.2分桶优势
方便抽样
提高连表查询效率
1.2.3分桶实践
开启分桶功能:
SET hive.enforce.bucketing=true; 默认false;
设置 Reduce 的个数,默认是 -1,-1 时会通过计算得到 Reduce 个数,一般 Reduce 的数量与表中的 BUCKETS 数量一致,有些时候环境无法满足时,通常设置为接近可用主机的数量即可
SET mapred.reduce.tasks=-1;
语法:
CREATE TABLE 表名(字段1 类型1,字段2,类型2 )
CLUSTERED BY (表内字段)
SORTED BY (表内字段)
INTO 分桶数 BUCKETS
载入数据:
用外表全表查询走MapReduce覆盖插入至分桶表;
直接载入也可以。
1.3数据抽样(了解)
1.3.1块抽样
截取表数据,速度慢,不随机;
1.3.2分桶抽样
截取桶数据,速度快,不随机;
1.3.3随机抽样
随机查询,速度慢,真随机;
1.4事务(了解)
# 开启 hive 并发
SET hive.support.concurrency=true;
# 配置事务管理类
SET hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
完整事务需要创建事务表
1.5索引(了解)
注:3.x.y版本被移除
出于以下原因,Hive 3.0.0 移除了索引功能:
由于 Hive 是针对海量数据存储的,创建索引需要占用大量的空间,最主要的是 Hive 索引无法自动进行刷新,也就是当新的数据加入时候,无法为这些数据自动加入索引;
Hive 索引使用过程繁杂,且性能一般;
在可以预见到分区数据非常庞大的情况下,分桶和索引常常是优于分区的。而分桶由于 SMB Join 对关联键要求严格,所以并不是总能生效;
Hive 的索引与关系型数据库中的索引并不相同,比如,Hive 不支持主键或者外键;
很多时候会优先考虑使用物化视图和列式存储文件格式来加快查询速度,大表则分区分桶,使用 SMB Join。
1.6视图/物化视图
视图 view是虚表,可以比作封装查询语句,类似子查询;
物化视图 Materialized View是实际存在的表,由查询语句查询出结果后将结果储存;
物化视图会自动刷新查询结果,并且拥有查询重写机制,即物化视图结果包含当前查询内容的化,就会走物化视图查询,避免走MapReduce。
1.7高级查询*
1.7.1行转列
explode ()展开函数
EXPLODE() 可以将 Hive 一行中复杂的 Array 或者 Map 结构拆分成多行,那如何将某个列的数据转为数组呢?可以配置 SPLIT 函数一起使用。
1.7.2列转行
collection_list/set 集合函数
COLLECT_SET() 和 COLLECT_LIST() 可以将多行数据转成一行数据,区别就是 LIST 的元素可重复而 SET 的元素是去重的。
1.7.3URL解析
侧视图 LATERAL VIEW 配合 PARSE_URL_TUPLE 函数可以实现 URL 字段的一列变多列。
1.7.4JSNO解析
需要配置JSNO序列化器,Hive自带jsnoSerDe,但不推荐使用,推荐使用第三方序列化器。
1.7.5窗口函数(重点****)
OVER() 不是Hive独有。
分区PARTITION BY 写在OVER 里 表示按某字段分组
排序ORDER BY 写在OVER里 表示按某字段排序
与 GROUP BY 的区别:
结果数据形式:
窗口函数可以在保留原表中的全部数据
GROUP BY 只能保留与分组字段聚合的结果
排序范围不同
窗口函数中的 ORDER BY 只是决定着窗口里的数据的排序方式
普通的 ORDER BY 决定查询出的数据以什么样的方式整体排序
SQL 顺序
GROUP BY 先进行计算
窗口函数在 GROUP BY 后进行计算
移动窗口:
移动方向:CURRENT ROW:当前行
PRECEDING:向当前行之前移动
FOLLOWING :向当前行之后移动
UNBOUNDED :起点或终点(一般结合 PRECEDING,FOLLOWING 使用)
UNBOUNDED PRECEDING :表示该窗口第一行(起点)
UNBOUNDED FOLLOWING :表示该窗口最后一行(终点)
移动范围:
ROWS 定义窗口从哪里开始,与BETWEEN AND 搭配
OVER(ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)表示当前行与当前行的前一行,以表行数判定
OVER(RANGE BETWEEN 1 PRECEDING AND CURRENT ROW)表示当前行与当前行的前一行,以某字段连续整形数字判定
聚合行窗口函数:
SUM() :求和
MAX() :最大值
MIN() :最小值
AVG() :平均值
COUNT() :计算总数
分析型窗口函数:
RANK() :间断,相同值同序号,例如 1、2、2、2、5。
DENSE_RANK() :不间断,相同值同序号,例如 1、2、2、2、3。
ROW_NUMBER() :不间断,序号不重复,例如 1、2、3、4、5(2、3 可能是相同的值)。
取值型窗口函数:
LAG(COL, N, DEFAULT_VAL) :往前第 N 行数据,没有数据的话用 DEFAULT_VAL 代替。
LEAD(COL, N, DEFAULT_VAL) :往后第 N 行数据,没有数据的话用 DEFAULT_VAL 代替。
FIRST_VALUE(EXPR) :分组内第一个值,但是不是真正意义上的第一个,而是截至到当前行的第一个。
LAST_VALUE(EXPR) :分组内最后一个值,但是不是真正意义上的最后一个,而是截至到当前行的最后一个。
1.8自定义函数
过程:
创建Maven项目,
导入依赖,
创建方法类,并继承相应自定义方法类
实现自定义方法类的方法
生成jar包
Hive导入自定义函数jar包
重新加载函数