Hive主要是用来做统计分析的,函数就是把一些常用的复杂的计算逻辑封装,Hive之所以可以实现统计分析,很大一部分取决于Hive中函数的概念
abs/pow/sqrt/…
concat/concat_ws
split
字符串有关的特殊函数:解析URL类型的字符串的
parse_url
parse_url_tuple
数组/集合类型有关的函数
array(T...) | map(string key,string value,string key,string value.....)
explode(array/map)---UDTF
collect_set/collect_list(col) --UDAF
split/concat_ws
侧视图函数lateral view
侧视图函数都是要和UDTF函数结合使用的
lateral view udtf(x...) tableAlias as columnAlias
侧视图的作用就是将普通列的数据和UDTF函数执行完成之后的多行多列的数据做笛卡尔乘积,实现一些普通HQL无法实现的功能
select xxxx from tableA lateral view udtf(x...) tableAlias as columnAlias
开窗函数
over(partition by 字段 order by 字段 asc|desc rows between 上边界 and 下边界)
开窗函数的作用就是把表中的数据构建出多个虚拟窗口(窗口其实就是分组),查询表中数据的时候,会识别到数据属于哪个窗口,得到这个窗口相关的一些信息和普通数据列一些返回。
partition by 的作用就是用来规定以哪个字段进行分组(开窗)
order by的作用就是对划分的窗口的以指定的字段进行排序
rows between的作用是为了划分窗口的边界的,每一个窗口默认的边界是 分组中的所有数据,但是窗口也可以是分组的部分行数据。 默认情况下 我们不写边界,默认边界(默认无上边界也无下边界)就是一个组中的所有数据
开窗函数不能单独使用,开窗函数需要集成一些特殊函数一起使用
first_value(col),last_value(col)
获取一个窗口中某一列的第一个值或者最后一个值
排名函数
row_number()
rank()
dense_rank()
根据当前行数据在窗口的排名 赋予一个排名编号
聚合函数:
sum/avg/count/max/min——————获取一个窗口的一个聚合值
【注意】开窗函数要和一些其他函数结合使用,而其他函数在使用的时候,大部分函数默认的边界都是无上边界和无下边界,而有少部分函数如果没有写窗口边界默认不是无边界,而是有边界的 所以以后大家在使用窗口函数的时候,建议大家最好把窗口边界也给声明上。
Hive底层会转换成为MapReduce运行,MapReduce阶段中间都是可以进行压缩的。因此Hive也支持设置压缩机制(也是设置转换的MR程序底层是Map阶段压缩 还是reduce阶段压缩)
Hive底层也可以转换成为Spark或者TEZ程序运行,Spark和TEZ的压缩和Mapreduce的压缩是不一样的。
在大部分常见的软件中,比如淘宝、拼多多…,网站都会产生大量的数据 电商网站:订单数据、商品数据、分类数据、用户信息数据、用户行为数据等等 课程网站:订单数据、视频数据、课程数据、用户信息数据等等 … 虽然说不同领域的数据格式和数据含义不一样,但是他们都有一个公共点:数据大部分都是在RDBMS关系型数据库进行存放的。如果我们要对某一个领域的数据进行大数据的统计分析,首先我们必须先把数据从非大数据环境同步到大数据环境中。 大部分数据都是在RDBMS存放的,大数据环境大部分都是HDFS、Hive、HBase。我们需要把RDBMS的数据同步到大数据环境中。
SQOOP软件是Apache开源的顶尖项目,sqoop 被设计用来在RDBMS和Hadoop(Hive、HDFS、HBase)之间进行数据传输的工具 因此sqoop的适用场景限制就非常大,因此这个技术基本很少更新了。软件基本已经从apache退役
指的是将数据从RDBMS(MySQL\ORACLE\SQL SERVER)导入到Hadoop环境(HDFS、HBASE、Hive)中
导入的作用就是将数据从非大数据环境导入到大数据环境通过大数据技术做统计分析的
指的是将数据从Hadoop环境(HDFS、Hive、HBase)导出到RDBMS中
将数据统计分析完成得到结果指标,指标在大数据环境存放的,如果对指标做可视化展示,数据在大数据环境下很难进行可视化展示的,因此我们需要把数据从大数据环境导出到非大数据环境RDBMS中进行可视化展示等后续操作
sqoop技术也是Hadoop生态的一部分,因为Sqoop进行导入和导出数据时,需要编写针对的导入和导出命令,但是这个命令底层也会转换成为MapReduce程序进行运行。
SQOOP运行基于MapReduce和YARN进行运行
因此sqoop底层是基于Hadoop的,因此sqoop也是安装一个单节点的即可,sqoop也是提供了一个可以导入和导出数据的命令行客户端
sqoop list-databases
sqoop list-tables
sqoop eval --query "sql"
需要跟数据库的连接参数
–connect jdbcurl
–username 用户名
–password 密码
指的是将数据从RDBMS关系型数据库导入到Hadoop环境中(HDFS、Hive、HBase)
将RDBMS的数据导入到HDFS中 不常用
HDFS导入时连接的RDBMS的参数
参数 | 说明 |
---|---|
–driver | |
–connect | |
–username | |
–password | |
[–table] | 导入哪张数据表的数据 |
[–columns] | 导入指定数据表的指定列的数据 |
[–query] | 根据查询语句的结果导入数据 |
[–where] | 筛选条件,根据指定的条件导入数据 |
HDFS导入的参数
参数名 | 说明 |
---|---|
–target-dir | 导入到HDFS上的路径 |
–delete-target-dir | 如果HDFS的路径存在 提前删除 |
[–as-textfile|sequencefile…] | 导入到HDFS上的文件的格式 |
–num-mappers | 指定导入的时候底层MapReduce启动多少个Map Task运行 |
–fields-terminated-by | 指定导入的文件列和列的分隔符 |
–lines-terminated-by | 指定导入的文件的行和行的分割符 |
导入数据表的所有数据到HDFS:
sqoop import --driver com.mysql.cj.jdbc.Driver --connect 'jdbc:mysql://single:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8' --username root --password Root123456.. --table student --target-dir /import --delete-target-dir --fields-terminated-by '=' --num-mappers 1 --as-sequencefile
导入数据表的指定列的数据到HDFS:
sqoop import --driver com.mysql.cj.jdbc.Driver --connect 'jdbc:mysql://single:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8' --username root --password Root123456.. --table student --columns student_name,student_age --target-dir /import --delete-target-dir --fields-terminated-by ',' --num-mappers 1 --as-textfile
根据查询语句导入指定的数据到HDFS:
--table table_name --where "条件"
只能导入一张表的数据
sqoop import --driver com.mysql.cj.jdbc.Driver --connect 'jdbc:mysql://single:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8' --username root --password Root123456.. --table student --columns student_name,student_age --where "student_age<40" --target-dir /import --delete-target-dir --fields-terminated-by ',' --num-mappers 1 --as-textfile
--query ""
可以通过连接查询同时导入多张表的数据
sqoop import --driver com.mysql.cj.jdbc.Driver --connect 'jdbc:mysql://single:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8' --username root --password Root123456.. --query 'select * from student where student_age<40 and $CONDITIONS' --target-dir /import --delete-target-dir --fields-terminated-by ',' --num-mappers 1 --as-textfile
将RDBMS的数据导入到Hive数据表中常用
导入参数
HDFS导入时连接的RDBMS的参数
参数名 | 说明 |
---|---|
–driver | |
–connect | |
–username | |
–password | |
[–table] | 导入哪张数据表的数据 |
[–columns] | 导入指定数据表的指定列的数据 |
[–query] | 根据查询语句的结果导入数据 |
[–where] | 筛选条件,根据指定的条件导入数据 |
导入到Hive中的参数
参数名 | 说明 |
---|---|
–hive-import | 指定将数据导入到Hive的数据表,而非HDFS或者HBase |
–hive-database | 指定将数据导入到Hive的哪个数据库中 |
–hive-table | 指定将数据导入到Hive的哪个数据表中 |
–create-hive-table | 如果Hive表没有提前存在,那么这个选项必须添加,会根据导入的数据自动推断创建Hive数据表,但是如果Hive中的数据表已经存在,那么这个参数一定不能添加 |
如果我们将RDBMS中的数据导入到Hive中,有两种导入模式
全量导入
第一次导入RDBMS的数据到Hive中
--hive-overwrite
将上述指定的数据全部到Hive对应的数据表,数据表会清空增量导入 非第一次导入RDBMS数据到Hive
将RDBMS数据表对应增加的新的数据导入到Hive中
增量导入又分为两种方式:一种根据自增id导入,第二种根据一个时间戳增量导入
根据RDBMS数据表的自增id导入:
参数名 | 说明 |
---|---|
–check-column rdbms | 数据表的自增列名 |
–incremental append | |
–last-value | 上一次导入的自增的值的最后一个 |
根据RDBMS数据表的一个时间字段导入:
参数名 | 说明 |
---|---|
–check-column rdbms | 数据表的时间列 |
–incremental lastmodified | |
–last-value | “上一次导入的最后一条数据的时间戳” |
全量导入
如果要做全量导入,Hive的数据表可以不用提前存在,使用create-hive-table
自动创建即可
sqoop import --driver com.mysql.cj.jdbc.Driver --connect 'jdbc:mysql://single:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8' --username root --password Root123456.. --table student --hive-import --hive-database test --hive-table student --create-hive-table
增量导入如果要做增量导入,Hive数据表必须提前存在,而且还具备RDBMS对应数据表的历史数据
按照自增id增量导入
sqoop import --driver com.mysql.cj.jdbc.Driver --connect 'jdbc:mysql://single:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8' --username root --password Root123456.. --table student --hive-import --hive-database test --hive-table student --check-column student_id --incremental append --last-value 5
按照创建时间增量导入hive-import
目前还不支持时间戳增量的方式
注意:如果将数据导入到Hive中,sqoop一共做了两步操作:
1、先通过MR程序把数据上传到HDFS上
2、使用hive的load装载命令将上传到HDFS上的数据文件加载到数据表中 sqoop操作Hive的时候,需要Hive的依赖,但是sqoop默认是没有hive的编程依赖的,因此sqoop迁移数据到hive会报错,如果不想报错,那么我们需要把hive-common.jar包复制到sqoop的lib目录下。
-- 时间日期函数
select date_sub("2022-10-1",2);
create table student_score(
student_id int,
student_name string,
student_class int,
student_score double
);
insert into student_score values(1,"zs",1,80.0),
(2,"ls",1,90.0),
(3,"ww",1,100.0),
(4,"ml",1,85.0),
(5,"zsf",2,80.0),
(6,"zwj",2,70.0),
(7,"qf",2,60.0);
select * from student_score;
-- 查询每一个学生的成绩,并且还要获取同一个班级的学生和前一个学生的成绩的差值
select
a.*,
abs(a.student_score-a.front_score) as score_diff
from(
select *,
first_value(student_score) over(partition by student_class order by student_id asc rows between 1 preceding and current row) as front_score
from student_score
) as a
-- 查询每一个学生的成绩,同时还要获取同一个班级每一个学生和班级最高分的差值。
-- 对于这个案例,窗口的边界是一组中的所有数据,而非一个组中的部分数据。
-- 如果窗口的边界是族中的所有数据,那么我们需要设置窗口的上边界和下边界都是无边界状态
select
* ,
abs(student_score-(max(student_score) over(partition by student_class rows between UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING))) as score_diff
from student_score;
select
* ,
last_value(student_score) over(partition by student_class rows between UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING) as score_diff
from student_score;