第一章.函数

1.系统内置函数

  1. # 查看系统自带的函数
  2. show function;
  3. # 显示自带函数的用法
  4. desc function upper;
  5. # 详细显示自带的函数用法
  6. desc function extended upper;
  1. # 常用内置函数
  2. NVL :给值为null的数据赋值
  3. 语法格式 : NVL(value,default_value)
  4. # 案例
  5. select NVL(null,1);
  1. # case when then else end
  2. # 案例

$04[Hive函数_压缩和存储] - 图1

需求: 求出不同部门男女各多少人,结果如下

$04[Hive函数_压缩和存储] - 图2

  1. # 创建hive表并导入数据
  2. create table emp_sex(
  3. name string,
  4. dept_id string,
  5. sex string)
  6. row format delimited fields terminated by "\t";
  7. load data local inpath '/home/atguigu/data/emp_sex.txt' into table emp_sex;
  8. # 按需求查询数据
  9. select dept_id,
  10. sum (case sex when '男' then 1 else 0 end) male_count,
  11. sum (case sex when '女' then 1 else 0 end) female_count
  12. from emp_sex
  13. group by dept_id;

2.行转列和列转行

1.行转列

  1. # 相关函数说明
  2. - CONCAT(string A/col, string B/col…):返回输入字符串连接后的结果,支持任意个输入字符串;
  3. - CONCAT_WS(separator, str1, str2,...):它是一个特殊形式的 CONCAT()。第一个参数剩余参数间的分隔符。分隔符可以是与剩余参数一样的字符串。如果分隔符是 NULL,返回值也将为 NULL。这个函数会跳过分隔符参数后的任何 NULL 和空字符串。分隔符将被加到被连接的字符串之间;
  4. - COLLECT_SET(col):函数只接受基本数据类型,它的主要作用是将某字段的值进行去重汇总,产生array类型字段。
  5. - COLLECT_LIST(col):函数只接受基本数据类型,它的主要作用是将某字段的值进行不去重汇总,产生array类型字段。
  1. 数据准备
  1. 孙悟空 白羊座 A
  2. 大海 射手座 A
  3. 宋宋 白羊座 B
  4. 猪八戒 白羊座 A
  5. 凤姐 射手座 A
  6. 苍老师 白羊座 B
  1. 需求

把星座和血型一样的人归类到一起

  1. # 创建表并导入数据
  2. create table person_info(
  3. name string,
  4. constellation string,
  5. blood_type string)
  6. row format delimited fields terminated by "\t";
  7. load data local inpath "/home/atguigu/data/constellation.txt" into table person_info;
  8. # 按需求查询数据
  9. select t1.c_b,concat_ws("|",collect_set(t1.name))
  10. from(
  11. select name,concat_ws(',',constellation,blood_type) c_b
  12. from person_info
  13. ) t1
  14. group by t1.c_b;

$04[Hive函数_压缩和存储] - 图3

2.列转行

  1. # 相关函数说明
  2. - Split(str, separator):将字符串按照后面的分隔符切割,转换成字符array。
  3. - EXPLODE(col):将hive一列中复杂的array或者map结构拆分成多行。
  4. - LATERAL VIEW
  5. 1. 用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias
  6. 2. 解释:lateral view用于和split, explode等UDTF一起使用,它能够将一行数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。
  7. 3. lateral view首先为原始表的每行调用UDTF,UTDF会把一行拆分成一或者多行,lateral view再把结果组合,产生一个支持别名表的虚拟表。
  1. 数据准备
  1. 《疑犯追踪》 悬疑,动作,科幻,剧情
  2. 《Lie to me》 悬疑,警匪,动作,心理,剧情
  3. 《战狼2》 战争,动作,灾难[
  1. 需求

将电影分类中的数组数据展开

  1. # 创建本地Hive表并导入数据
  2. create table movie_info(
  3. movie string,
  4. category string)
  5. row format delimited fields terminated by "\t";
  6. load data local inpath "/home/atguigu/data/movie_info.txt" into table movie_info;
  7. # 按照需求查询数据
  8. select movie,category_name
  9. from movie_info
  10. lateral view
  11. explode(split(category,",")) movie_info_tmp as category_name;

$04[Hive函数_压缩和存储] - 图4

3.窗口函数

  1. # 相关函数说明
  2. - OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化。
  3. - CURRENT ROW:当前行
  4. - n PRECEDING:往前n行数据
  5. - n FOLLOWING:往后n行数据
  6. - UNBOUNDED:无边界
  7. UNBOUNDED PRECEDING 前无边界,表示从前面的起点,
  8. UNBOUNDED FOLLOWING后无边界,表示到后面的终点
  9. - LAG(col,n,default_val):往前第n行数据
  10. - LEAD(col,n, default_val):往后第n行数据
  11. - FIRST_VALUE (col,true/false):当前窗口下的第一个值,第二个参数为true,跳过空值
  12. - LAST_VALUE (col,true/false):当前窗口下的最后一个值,第二个参数为true,跳过空值
  13. - NTILE(n):把有序窗口的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回此行所属的组的编号。注意:n必须为int类型。
  1. 数据准备
  1. jack,2017-01-01,10
  2. tony,2017-01-02,15
  3. jack,2017-02-03,23
  4. tony,2017-01-04,29
  5. jack,2017-01-05,46
  6. jack,2017-04-06,42
  7. tony,2017-01-07,50
  8. jack,2017-01-08,55
  9. mart,2017-04-08,62
  10. mart,2017-04-09,68
  11. neil,2017-05-10,12
  12. mart,2017-04-11,75
  13. neil,2017-06-12,80
  14. mart,2017-04-13,94
  1. 创建Hive表并导入数据
  1. create table business(
  2. name string,
  3. orderdate string,
  4. cost int
  5. )
  6. row format delimited fields terminated by ',';
  7. load data local inpath '/home/atguigu/data/business.txt' into table business;
  1. 按需求查询数据
  1. 查询在2017年4月份购买过的顾客和总人数
  1. select name,count(name) over()
  2. from business
  3. where month(orderdate) = 4
  4. group by name;

$04[Hive函数_压缩和存储] - 图5

  1. 查询顾客的购买明细和购买总额
  1. select name,orderdate,cost,
  2. sum(cost) over(partition by name,month(orderdate)) name_month_cost
  3. from business;

$04[Hive函数_压缩和存储] - 图6

  1. 将每个顾客的cost按照日期进行累加
  1. select name,orderdate,cost,
  2. sum(cost) over(partition by name order by orderdate rows between unbounded preceding and current row),
  3. sum(cost) over(partition by name order by orderdate rows between 1 preceding and 1 following)
  4. from business;

$04[Hive函数_压缩和存储] - 图7

  1. 查询顾客购买明细以及上次的购买时间和下次购买时间
  1. select name,orderdate,cost,
  2. lag(orderdate,1,'1990-01-01') over(partition by name order by orderdate) prev_time,
  3. lead(orderdate,1,'1970-01-01') over(partition by name order by orderdate) next_time
  4. from business;

$04[Hive函数_压缩和存储] - 图8

  1. 查询顾客每个月第一次的购买部时间和每个月的最后一次购买时间
  1. select name,orderdate,cost,
  2. first_value(orderdate) over(partition by name,month(orderdate) order by orderdate
  3. rows between unbounded preceding and unbounded following) first_time,
  4. last_value(orderdate) over(partition by name,month(orderdate) order by orderdate
  5. rows between unbounded preceding and unbounded following) last_time
  6. from business;

$04[Hive函数_压缩和存储] - 图9

  1. 查询前20%时间的订单信息
  1. select t1.name,t1.orderdate,t1.cost,t1.number
  2. from(
  3. select name,orderdate,cost,ntile(5) over(order by orderdate) number from business ) t1
  4. where t1.number = 1;

$04[Hive函数_压缩和存储] - 图10

4.Rank

  1. # 相关函数说明
  2. - Rank() 排序相同时会重复(考虑并列,会跳号),总数不会变
  3. - Dense_Rank() 排序相同时会有重复(考虑并列,不跳号),总数会减少
  4. - Row_Number 会根据顺序计算(不考虑并列,不跳号,行号)
  1. 数据准备
  1. 孙悟空 语文 87
  2. 孙悟空 数学 95
  3. 孙悟空 英语 68
  4. 大海 语文 94
  5. 大海 数学 56
  6. 大海 英语 84
  7. 宋宋 语文 64
  8. 宋宋 数学 86
  9. 宋宋 英语 84
  10. 婷婷 语文 65
  11. 婷婷 数学 85
  12. 婷婷 英语 78
  1. 需求

计算每门学科成绩排名

  1. # 创建hive表并导入数据
  2. create table score(
  3. name string,
  4. subject string,
  5. score int
  6. )
  7. row format delimited fields terminated by "\t";
  8. load data local inpath '/home/atguigu/data/score.txt' into table score;
  9. # 按照 需求查询数据
  10. select name,
  11. subject,
  12. score,
  13. rank() over(partition by subject order by score desc) rp,
  14. dense_rank() over(partition by subject order by score desc) drp,
  15. row_number() over(partition by subject order by score desc) rmp
  16. from score;

$04[Hive函数_压缩和存储] - 图11

5.自定义函数(UDF)

  1. Hive自带了一些函数,比如max/min等,但是数量有限,自己可以通过自定义UDF来方便的扩展
  2. 根据用户自定义函数类别分为以下三种
  3. UDF(User-Defined-Function) 一进一出
  4. UDAF(User-Defined Aggregation Function) 用户自定义聚合函数,多进一出
  5. UDTF(User-Defined Table-Generating Functions) 用户自定义表生成函数,一进多出

需求: 自定义一个UDF实现计算给定字符串的长度

  1. 在idea中创建一个maven工程
  2. 导入依赖
  1. <dependencies>
  2. <dependency>
  3. <groupId>org.apache.hive</groupId>
  4. <artifactId>hive-exec</artifactId>
  5. <version>3.1.2</version>
  6. </dependency>
  7. </dependencies>
  1. 创建一个类
package com.atguigu.hive;


import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;

public class MyLen extends GenericUDF{
    /**
    * @Description:  初始化  1.判断函数传入参数的个数   2.判断函数传入的参数的类型  3.定义返回值的类型
    * @Param: [objectInspectors]
    * @return: org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector
    * @Author: jcsune
    * @Date: 2021/7/26
    */
    @Override
    public ObjectInspector initialize(ObjectInspector[] objectInspectors) throws UDFArgumentException {
        //判断函数传入的参数的个数
        if(objectInspectors.length != 1){
            throw new UDFArgumentLengthException("参数个数错误");
        }
        //判断函数传入的参数的类型
        if(!objectInspectors[0].getCategory().equals(ObjectInspector.Category.PRIMITIVE)){
            //判断是否为基本数据类型
            throw new UDFArgumentTypeException(0,"参数的类型错误");

        }
        //定义返回值的类型
        return PrimitiveObjectInspectorFactory.javaIntObjectInspector;//返回类型为int
    }

    /** 
    * @Description:  在该方法中实现函数的功能: 返回内容的长度
    * @Param: [deferredObjects] 
    * @return: java.lang.Object 
    * @Author: jcsune
    * @Date: 2021/7/26 
    */ 
    @Override
    public Object evaluate(DeferredObject[] deferredObjects) throws HiveException {
        //获取第一个参数的内容
        Object o = deferredObjects[0].get();
        //返回内容的长度
        return o.toString().length();
    }
    /** 
    * @Description: 回显字符串在这不用管,返回一个空串即可
    * @Param: [strings] 
    * @return: java.lang.String 
    * @Author: jcsune
    * @Date: 2021/7/26 
    */ 
    @Override
    public String getDisplayString(String[] strings) {
        return "";
    }
}
  1. 打成jar包上传至服务器 (/home/atguigu)
  2. 将jar包添加到hive的classpath,临时生效
beeline -u jdbc:hive2://hadoop102:10000 -n atguigu
add jar /home/atguigu/UDFDemo.jar;
  1. 创建临时函数与开发好的java class关联
create temporary function my_len as "com.atguigu.hive.MyLen";
  1. 测试自定义函数(临时生效)
select my_len("abc");

$04[Hive函数_压缩和存储] - 图12

第二章.压缩和存储

1.MR支持的压缩编码

压缩格式 算法 文件扩展名 是否可切分
DEFLATE DEFLATE .deflate 否
Gzip DEFLATE .gz 否
bzip2 bzip2 .bz2 是
LZO LZO .lzo 是
Snappy Snappy .snappy 否

为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器

压缩格式 对应的编码/解码器
DEFLATE org.apache.hadoop.io.compress.DefaultCodec
gzip org.apache.hadoop.io.compress.GzipCodec
bzip2 org.apache.hadoop.io.compress.BZip2Codec
LZO com.hadoop.compression.lzo.LzopCodec
Snappy org.apache.hadoop.io.compress.SnappyCodec

压缩性能的比较

压缩算法 原始文件大小 压缩文件大小 压缩速度 解压速度
gzip 8.3GB 1.8GB 17.5MB/s 58MB/s
bzip2 8.3GB 1.1GB 2.4MB/s 9.5MB/s
LZO 8.3GB 2.9GB 49.3MB/s 74.6MB/s

[$04[Hive函数_压缩和存储] - 图13

2.开启MAP输出阶段压缩

开启map输出阶段压缩可以减少job中map和reduce task间数据传输量

# 案例实操
(1)开启hive中间传输数据压缩功能
set hive.exec.compress.intermediate=true;
(2)开启mapreduce中map输出压缩功能
set mapreduce.map.output.compress=true;
(3)设置MapReduce中map输出数据的压缩格式
set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
(4)执行查询语句
select count(ename) name from emp;

3.开启Reduce输出阶段压缩

当Hive将输出写入到表中时,输出内容同样可以进行压缩。属性hive.exec.compress.output控制着这个功能。用户可能需要保持默认设置文件中的默认值false,这样默认的输出就是非压缩的纯文本文件了。用户可以通过在查询语句或执行脚本中设置这个值为true,来开启输出结果压缩功能。

# 案例实操
(1)开启hive最终输出数据压缩功能
set hive.exec.compress.output=true;
(2)开启MapReduce最终输出数据压缩
set mapreduce.output.fileoutputformat.compress=true;
(3)设置MapReduce最终数据输出压缩格式
set mapreduce.output.fileoutputformat.compress.codec  =org.apache.hadoop.io.compress.SnappyCodec;
(4)设置mapreduce最终数据输出压缩为块压缩
set mapreduce.output.fileoutputformat.compress.type=BLOCK;
(5)测试一下输出结果是否是压缩文件
insert overwrite local directory '/opt/module/hive/datas/compress/' select * from emp distribute by deptno sort by empno desc;