Hive特殊使用与函数知识点01:Hive回顾知识点02:本篇目标知识点03:Hive表结构:普通表结构知识点04:Hive表结构:分区表设计知识点05:Hive表结构:分区表实现知识点06:Hive表结构:分桶表设计及实现知识点07:Hive中的Join:Join逻辑知识点08:Hive中的Join:Join实现知识点09:Select语法:order by与sort by知识点10:Select语法:distribute by 与 cluster by知识点11:数据类型:Array知识点12:数据类型:Map知识点13:特殊案例:正则加载知识点14:Hive中的函数:内置函数知识点15:Hive中的函数:自定义函数知识点16:Hive中的函数:parse_url_tuple知识点17:Hive中的函数:lateral view知识点18:Hive中的函数:explode附录一:Hive Maven 依赖
Hive特殊使用与函数
苟有恒,何必三更眠五更起;
最无益,莫过一日曝十日寒。
知识点01:Hive回顾
Hive与HDFS的映射关系是什么?
Hive:数据库、表、表中的数据HDFS:数据库目录、表的目录、文件
元数据的功能是什么,存储在什么位置?
功能 存储了Hive所有对象的信息:数据库、表、列存储了Hive表与HDFS的映射关系 位置 默认:derby数据库自定义:MySQL 方式 嵌入式:直接访问Derby本地:直接访问MySQL远程:通过metastore服务来访问元数据
metastore服务的功能是什么,怎么启动,端口是什么,Hive的服务端如何启动,端口是什么?
metastore 功能:实现元数据的共享启动:hive --service metastore端口:9083 hiveserver2 功能:Hive的服务端启动:hiveserver2 / hive --service hiveserver2端口:10000
如何封装Hive的SQL脚本?
客户端
Hive Shell:Old Client:用于封装SQL脚本Beeline:一般作为交互式的查询客户端JDBC:一般用于封装查询接口
封装SQL
hive -e :执行命令行的SQL语句,少量的SQL语句
hive -f:执行SQL文件
传递参数:–hiveconf
Hive中load与insert的命令的功能是什么?
DDL、DQL:基本与MySQL一致的
DML
Hive支持行级的insert、update、delete
数据写入:将数据构建表的结构,通过SQL对数据进行处理
数据来源:大量的数据文件、分析处理的结果
写入方式
load:将文件关联到Hive表中
insert:保存Select语句的结果
Hive中表的类型有几种,关键字和特点分别是什么?
create [temporary] [external] table
管理表:默认表结构,必须手动删除,不会自动删除,如果删除,既删除元数据也删除对应的数据
临时表:temporary,如果创建的客户端断开,临时表会自动删除
外部表:external,如果删除,只删除元数据
为了保证数据安全以及共享数据文件,一般都建外部表
知识点02:本篇目标
表的结构==【重点】==
普通表结构分区表结构分桶表结构
Hive中特殊语法
Join逻辑:左外连接、右外连接、内连接、全连接full join实现:Map Join,Reduce Joinxxx Byorder by 、sort by 、distribute by 、cluster by 特殊数据类型 ArrayMap 特殊数据格式
Hive中的函数【重点】
内置函数:字符串函数、日期函数、聚合函数、特殊函数、窗口函数
自定义函数
URL解析函数
侧视图的使用
集合展开函数
知识点03:Hive表结构:普通表结构
引入:建表语句
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name(col1Name col1Type [COMMENT col_comment],co21Name col2Type [COMMENT col_comment],co31Name col3Type [COMMENT col_comment],co41Name col4Type [COMMENT col_comment],co51Name col5Type [COMMENT col_comment],……coN1Name colNType [COMMENT col_comment])[PARTITIONED BY (col_name data_type ...)]--分区表结构[CLUSTERED BY (col_name...) [SORTED BY (col_name ...)] INTO N BUCKETS] --分桶表结构[ROW FORMAT row_format] -- 指定数据文件的分隔符row format delimited fields terminated by '列的分隔符' -- 列的分隔符,默认为\001lines terminated by '行的分隔符' --行的分隔符,默认\n[STORED AS file_format] -- 指定文件的存储格式[LOCATION hdfs_path] -- 用于指定表的目录所在位置,默认表的目录在数据库的目录下面
目标:了解Hive中普通表结构的特点及应用场景
路径
step1:Hive与HDFS的映射关系step2:MapReduce处理的规则step3:普通表结构的特点
实施
Hive与HDFS的映射关系
MapReduce处理的规则
select count(*) from table where id > 30;
step1:检索元数据,找到表对应的HDFS目录
step2:将**表的最后一级目录作为MapReduce程序的输入**
TextInputFormat.setInputPaths(job,path1,path2……)
普通表结构的特点及应用
结构
Hive数据仓库目录/数据库目录/表的目录/数据文件/user/hive/warehouse/db_emp.db/tb_emp/emp.txt
- 特点- **表的最后一级目录是表的目录**- 问题:如果是一张普通表的结构,手动将文件通过HDFS命令放入表的目录下,在表中能否读到?- 可以- 应用- 默认创建的表都是普通表结构- 一般用于将原始的一个整体的数据文件构建成表的结构
小结
MapReduce处理Hive表数据的规则?
将Hive表的最后一级目录作为底层的输入目录
普通表结构的特点和应用是什么?
语法
create table ();
特点:表的最后一级目录是表的目录
应用:一般用于将原始的大数据文件映射成表的结构
知识点04:Hive表结构:分区表设计
目标:掌握Hive中分区表结构的特点及应用场景
路径
step1:普通表结构的问题step2:分区表结构的设计
实施
普通表结构的问题
需求:现在有一张普通表,记录一年365天的数据,每天一个1G文件,现在需要对其中某一天的数据进行处理
创建普通表,加载数据到普通表中
/user/hive/warehouse /db_nginx.db /tb_nginx /-01-01.log-01-02.log……-12-31.log
实现
select count(*) from tb_nginx where daystr='-05-01';
问题
底层MapReduce执行Input:/user/hive/warehouse /db_nginx.db /tb_nginx 365GBMap 过滤:日期等于5月1号输出:1GB Shuffle & Reduce & Output 聚合得到条数 Map阶段要做大量无意义的过滤操作,导致大量的资源浪费
解决思想:如果只读取5月1号的数据文件,就不用过滤,直接处理得到结果
分区表结构的设计
设计思想
将数据按照一定规则条件划分**不同的目录**进行分区存储在查询时,可以根据查询条件在目录层次进行过滤,直接由MapReduce加载需要处理的数据的目录
本质
提前将数据划分到不同的目录中存储通过查询条件减少底层MapReduce的输入的数据量,避免无用的过滤,提高性能
结构
普通表
数据仓库目录/数据库目录/表的目录/数据文件/user/hive/warehouse /db_nginx.db /tb_nginx /-01-01.log-01-02.log……-12-31.log
分区表
数据仓库目录/数据库目录/表的目录/分区目录/分区数据文件/user/hive/warehouse /db_nginx.db /tb_nginx /daystr=-01-01 /-01-01.log/daystr=-01-02 /-01-02.log……/daystr=-12-31 /-12-31.log
通过SQL进行过滤查询
select count(*) from tb_nginx where daystr='-05-01';
MapReduce:按照日期分区,过滤条件也是日期
Input:/user/hive/warehouse /db_nginx.db /tb_nginx /daystr=-05-01 1GB Map 1GB
特点
表的最后一级目录就是分区目录
应用
工作中离线数据仓库的业务一般是按照时间进行处理 这个小时处理上个小时的数据今天处理昨天的数据这个月处理上个月的数据今年处理去年的数据工作离线数据仓库最常用的表的结构:分区表结构最常用的表:分区外部表分区的划分:一般都是按照时间划分
小结
分区表的结构、特点和应用场景是?结构:数据仓库/数据库/表/分区/分区数据文件 特点:表的最后一级是分区目录 应用:最常见的表的结构
知识点05:Hive表结构:分区表实现
目标:实现分区表的构建及应用
路径
step1:静态分区step2:动态分区step3:多级分区
实施
静态分区
应用:数据文件本身就是按照分区的规则划分好的,直接创建分区表,加载每个分区的数据即可
步骤
step1:直接创建分区表step2:加载每个文件到对应的分区中即可
实现
当前已有按照每个部分分区好的数据文件
- 创建分区表```sqlcreate table tb_emp_part1(empno string,ename string,job string,managerno string,hiredate string,salary double,jiangjin double,deptno string) partitioned by (department int)row format delimited fields terminated by '\t';```- 加载对应数据文件到对应的分区```sqlload data local inpath '/export/data/emp10.txt' into table tb_emp_part1 partition (department=10);load data local inpath '/export/data/emp20.txt' into table tb_emp_part1 partition (department=20);load data local inpath '/export/data/emp30.txt' into table tb_emp_part1 partition (department=30);```- 查询数据- 观察HDFS存储结构
- 测试SQL的执行计划:explain- 普通表```explain extended select count(*) as numb from tb_emp where deptno = 20;```
- 分区表```explain extended select count(*) as numb from tb_emp_part1 where department = 20;```
- 查看元数据- PARTITIONS
- SDS
动态分区
应用:数据本身没有按照分区的规则划分,需要通过程序实现自动动态划分
步骤
step1:先创建一个普通表,加载整体的数据step2:再创建一个分区表step3:将普通表的数据写入分区表,实现动态分区
实现
创建普通表
tb_emp:普通表,所有部门的员工信息都在一个目录文件中
创建分区表
create table tb_emp_part2(empno string,ename string,job string,managerno string,hiredate string,salary double,jiangjin double) partitioned by (dept string)row format delimited fields terminated by '\t';
修改属性
--开启动态分区set hive.exec.dynamic.partition.mode=nonstrict;
- 写入分区表```sqlinsert into table tb_emp_part2 partition(dept)select * from tb_emp ;|insert into table tb_emp_part2 partition(dept)select ……,deptno from tb_emp ;
问题:上面这个代码是如何知道按照哪个字段进行自动分区的呢?
按照查询语句的最后一个字段
要求:查询语句一般不用select *,强制要求查询语句的最后一个字段作为分区字段的
查询数据
HDFS
- 数据
多级分区
创建多级分区表
create table tb_ds_source(id string,url string,referer string,keyword string,typestring,guidstring,pageId string,moduleIdstring,linkId string,attachedInfo string,sessionIdstring,trackerUstring,trackerType string,ip string,trackerSrc string,cookie string,orderCodestring,trackTimestring,endUserIdstring,firstLinkstring,sessionViewNo string,productIdstring,curMerchantId string,provinceId string,cityId string,fee string,edmActivity string,edmEmailstring,edmJobIdstring,ieVersionstring,platformstring,internalKeyword string,resultSumstring,currentPage string,linkPosition string,buttonPositionstring)partitioned by (daystr string,hourstr string)row format delimited fields terminated by '\t';
加载多级分区数据
load data local inpath '/export/data/082818' into table tb_ds_source partition (daystr='0828',hourstr='18');load data local inpath '/export/data/082819' into table tb_ds_source partition (daystr='0828',hourstr='19');
结果
查看分区的命令
show partitions tbname;
小结
如何实现构建分区表? 静态分区:数据本身就是按照分区规则分好的动态分区:数据本身没有分好,通过程序实现自动分区关键字:partitioned by (分区的字段) 分区是什么级别的设计? 目录级别的,一个目录代表一个分区目录的名称:分区字段 = 分区的值 分区的字段是逻辑还是物理的? 逻辑的
知识点06:Hive表结构:分桶表设计及实现
目标:理解分桶表的设计思想及实现分桶表的测试
路径
step1:Join的问题step2:分桶表的设计step3:分桶表的实现
实施
Join的问题
Map Join:性能比较好,适合于小表join大表Reduce Join:通过Shuffle的分组来实现的,适合于大表join大表问题:怎么解决Reduce Join性能非常差的问题?
分桶表的设计
思想:将大的数据按照规则划分为多份小数据,每份小的数据都走Map Join,减少每条数据的比较次数,提高性能
功能
优化大表join大表的问题分桶采样
本质:通过MapReduce底层的分区【Reduce的划分规则】将数据划分到多个文件中
每个文件 = 每个桶 = 每个Reduce划分规则:Hash取余
结构
数据仓库目录/数据库目录/表的目录/分桶的文件数据
设计
- 将两张大表按照相同的规则进行分桶- 实现分桶Join,桶与桶之间直接进行Map Join,减少比较次数,提高性能- 流程- step1:将两张表进行分桶- step2:实现Bucket Join- Hive会自动判断是否满足分桶Join的条件,如果满足就自动实现分桶Join
分桶表的实现
语法
clustered by col [sorted by col] into N buckets
clustered by :按照哪一列分桶
sorted by:每个桶的内部按照哪一列进行排序
N:分几个桶,代表底层写入数据就有几个reduce
实现
开启配置
set hive.optimize.bucketmapjoin = true;set hive.optimize.bucketmapjoin.sortedmerge = true;
创建分桶表
create table tb_emp_bucket(empno string,ename string,job string,managerno string,hiredate string,salary double,jiangjin double,deptno string) clustered by (deptno) into 3 BUCKETSrow format delimited fields terminated by '\t';
写入分桶表
insert overwrite table tb_emp_bucketselect * from tb_emp cluster by (deptno);
查看结果
小结
分桶表的功能和设计思想是什么? 功能:优化大表join大表的性能设计:将数据按照划分规则划【多个Reduce划分】分多个小文件中,每个小文件可以实现Map Join,降低了比较次数,提高性能 分桶表是什么级别的设计? 文件级别 分桶字段是物理的还是逻辑的? 物理的 注意:分桶表的数据不能使用load加载
知识点07:Hive中的Join:Join逻辑
目标:了解Hive中的join语法的使用
实施
inner join:内连接
selecta.empno,a.ename,b.deptno,b.dnamefromtb_emp a join tb_dept b on a.deptno = b.deptno;
两边都有结果才有
left outer join:左外连接
左边有,结果就有
selecta.empno,a.ename,b.deptno,b.dnamefromtb_emp a left join tb_dept b on a.deptno = b.deptno;
right outer join:右外连接
右边有,结果就有
selecta.empno,a.ename,b.deptno,b.dnamefromtb_emp a right join tb_dept b on a.deptno = b.deptno;
full join:全连接
两边任意一边又,结果就有
explain selecta.empno,a.ename,b.deptno,b.dnamefromtb_emp a full join tb_dept b on a.deptno = b.deptno;
笛卡尔积
select a.*,b.* from a,b;select a.*,b.* from a join b;
Hive中严禁产生大数据量的笛卡尔积
小结
基本与MySQL一致
知识点08:Hive中的Join:Join实现
目标:了解Hive中Join的底层实现路径step1:Map Joinstep2:Reduce Joinstep3:Bucket Join实施Map Join特点:将小表的数据放入分布式缓存,与大表的每个部分进行Join,发生在Map端,不用经过shuffle场景:小表 join 小表 ,小表 join 大表要求:必须有一张表是小表实现规则Hive中默认会优先判断是否满足Map Join的条件 判断表的文件大小:小于25MB 如果满足,就自动走Map Join如果不符合,自动走Reduce JoinReduce Join特点:利用Shuffle的分组来实现Join过程,发生在Reduce端,需要经过Shuffle场景:大表join大表要求:Hive中默认如果不满足Map Join,就自动走Reduce JoinBucket Join特点:将大的数据划分成多份小的数据,每个小数据就是一个桶,实现分桶join场景:大表join大表,优化这个过程,如果你的Join多次要求 Bucket Map Join:普通的分桶join 两张表都是桶表桶的个数成倍数Join字段 = 分桶的字段 Bucket Sort Merge Map Join:基于排序的分桶Join 两张表都是桶表桶的个数成倍数Join字段 = 分桶的字段 = 排序的字段小结了解Hive中底层Join实现的方案及各自的特点和场景知识点09:Select语法:order by与sort by
目标:掌握Select语法中order by与sort by的功能与区别
路径
step1:Hive中ReduceTask个数step2:order by的功能step3:sort by的功能
实施
Hive中ReduceTask个数
Number of reduce tasks not specified. Estimated from input data size: 1In order to change the average load for a reducer (in bytes):\#每个Reduce处理的数据量大小set hive.exec.reducers.bytes.per.reducer=<number>In order to limit the maximum number of reducers:#最多允许启动的reduce的个数set hive.exec.reducers.max=<number>In order to set a constant number of reducers:#设置reduce的个数set mapreduce.job.reduces=<number>
```set mapreduce.job.reduces = 2;```
order by的功能
功能:全局排序
select empno,ename,deptno,salary from tb_emp order by salary desc;
- 问题:如果Reduce有多个,能否实现全局排序?- 不能有多个Reduce,使用了order by,只会启动一个reduce
sort by的功能
功能:局部排序
多个Reduce的场景下,每个reduce内部有序
用法:与order by是一致的
select empno,ename,deptno,salary from tb_emp sort by salary desc;
```insert overwrite local directory '/export/data/sort' row format delimited fields terminated by '\t'select empno,ename,deptno,salary from tb_emp sort by salary desc;```
小结
order by与sort by的功能与区别是? order by:全局排序,只能有1个reducesort by:局部排序,多个reduce每个reduce局部排序
知识点10:Select语法:distribute by 与 cluster by
目标:了解distribute by与cluster by语法的使用
路径
step1:distribute bystep2:cluster by
实施
distribute by
功能:用于干预底层的MapReduce,指定某个字段作为K2
语法
insert overwrite local directory '/export/data/distby' row format delimited fields terminated by '\t'select empno,ename,deptno,salary from tb_emp distribute by deptno;
```insert overwrite local directory '/export/data/distby' row format delimited fields terminated by '\t'select empno,ename,deptno,salary from tb_emp distribute by deptno sort by salary desc;```
- 应用```distribute by 1=>用于将所有数据进入一个Reduce中distribute by rand()=> 实现随机分区,避免数据倾斜```
cluster by
功能:如果distribute by与sort by是同一个字段,可以使用cluster by代替
小结
distribute by的功能是? 用于干预MapReduce的K2,指定K2这一列
知识点11:数据类型:Array
目标:了解Hive表中数组类型的定义及使用
实施
数据
vim /export/data/array.txt
zhangsanbeijing,shanghai,tianjinwangwushanghai,chengdu,wuhan,haerbin
建表
create database db_complex;use db_complex;create table if not exists complex_array(name string,work_locations array<string>)row format delimited fields terminated by '\t'COLLECTION ITEMS TERMINATED BY ',';COLLECTION ITEMS TERMINATED BY ',' --用于指定数组中每个元素的分隔符
加载
load data local inpath '/export/data/array.txt' into table complex_array;
取值
--统计每个用户工作过的城市个数select name,size(work_locations) as numb from complex_array;--取出数组中单独的元素select name,work_locations[0],work_locations[1] from complex_array;
小结
了解基本的定义与使用即可
知识点12:数据类型:Map
目标:了解Hive表中Map集合类型的定义及使用
实施
数据
vim /export/data/map.txt
1,zhangsan,唱歌:非常喜欢-跳舞:喜欢-游泳:一般般2,lisi,打游戏:非常喜欢-篮球:不喜欢
建表
create table if not exists complex_map(id int,name string,hobby map<string,string>)row format delimited fields terminated by ','COLLECTION ITEMS TERMINATED BY '-' MAP KEYS TERMINATED BY ':';COLLECTION ITEMS TERMINATED BY '-' --用于划分每个KV对MAP KEYS TERMINATED BY ':';--用户划分K和V的
加载
load data local inpath '/export/data/map.txt' into table complex_map;
取值
--统计每个人有几个兴趣爱好select name,size(hobby) as numb from complex_map;--取出每个人对唱歌的喜好程度select name,hobby["唱歌"] as deep from complex_map;
小结
了解基本的定义与使用即可
知识点13:特殊案例:正则加载
目标:了解Hive中分隔符的问题及实现正则加载数据
路径
step1:分隔符的问题step2:处理方案step3:正则加载
实施
分隔符的问题
场景1:数据中的列的分隔符||,Hive不支持多字节分隔符
01||周杰伦||中国||台湾||男||七里香02||刘德华||中国||香港||男||笨小孩03||汪 峰||中国||北京||男||光明04||朴 树||中国||北京||男||那些花儿05||许 巍||中国||陕西||男||故乡06||张靓颖||中国||四川||女||画心07||黄家驹||中国||香港||男||光辉岁月08||周传雄||中国||台湾||男||青花09||刘若英||中国||台湾||女||很爱很爱你10||张 杰||中国||四川||男||天下
场景2:数据中每列的分隔符不一致
1 zhangsan,18-male2 lisi,20-female
场景3:数据字段中包含了分隔符
192.168.88.1 - - [24/Dec/:15:54:58 +0800] "POST /set/report/ HTTP/1.1" 404 1093
处理方案
方案一:先做ETL,需要先开发一个程序来实现数据的处理,将处理的结果再加载到Hive表中 通过程序替换分隔符 方案二:Hive官方提供了正则加载的方式 通过正则表达式来匹配每一条数据中的每一列
正则加载
数据
vim /export/data/regex.txt
-08-28 00:03:00 tom-08-28 10:00:00 frank-08-28 11:00:00 jack-08-29 00:13:23 tom-08-29 10:00:00 frank-08-30 10:00:00 tom-08-30 12:00:00 jack
建表
正常创建
create table regex1(timestr string,name string) row format delimited fields terminated by ' ';load data local inpath '/export/data/regex.txt' into table regex1;
- 正则加载```sqlcreate table regex2(timestr string,name string)ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'WITH SERDEPROPERTIES ("input.regex" = "([^}]*) ([^ ]*)")STORED AS TEXTFILE;```load data local inpath '/export/data/regex.txt' into table regex2;``````
```
小结
了解分隔符存在的问题及正则解决方案即可
知识点14:Hive中的函数:内置函数
目标:掌握Hive中常用的内置函数
路径
step1:查看函数step2:常用函数
实施
查看函数
列举
show functions;
查看函数的用法
desc function [extended] funName;
常用函数
聚合函数:count、sum、avg、max、min条件函数:if、case when字符串函数 截取:substring,substr拼接:concat、concat_ws分割:split查找:instr替换:regex_replace长度:length 日期函数 转换:unix_timestamp、from_unixtime日期:current_date,date_sub,date_add获取:year、month、day、hour 特殊函数 JSON:json_tuple,get_json_objectURL:parse_url,parse_url_tuple窗口函数 聚合窗口:sum、count……位置窗口:lag、lead、first_value,last_value分析函数:row_number、rank、dense_rank
小结
了解基本常用的内置函数
知识点15:Hive中的函数:自定义函数
目标:了解Hive中如何实现自定义函数
路径
step1:函数分类step2:自定义UDF函数step3:自定义UDAF与UDTF
实施
函数分类
UDF:一对一函数,类似于substrUDAF:多对一函数,类似于聚合函数:countUDTF:一对多函数,explode将一行中的每个元素变成一行
自定义UDF函数
需求:24/Dec/:15:55:01 -> -12-24 15:55:01
step1:自定义一个类,继承UDF类
step2:在类中至少实现一个evaluate方法定义处理数据的逻辑
step3:打成jar包,添加到hive的环境变量中
add jar /export/data/udf.jar;
step4:将类注册为函数
create temporary function transFDate as '.hive.udf.UserUDF';
step5:调用函数
select transFDate("24/Dec/:15:55:01");
自定义UDAF与UDTF
UDAF
step1:将类注册为函数
create temporary function userMax as '.hive.udaf.UserUDAF';
step2:调用函数
select userMax(cast(deptno as int)) from db_emp.tb_dept;
cast:强制类型转换函数
cast(列 as 类型)
UDTF
step1:将类注册为函数
create temporary function transMap as '.hive.udtf.UserUDTF';
step2:调用函数
select transMap("uuid=root&url=") as (userCol1,userCol2);
小结
Hive中的自定义函数分为几类? UDF:一对一UDAF:多对一UDTF:一对多 如何实现自定义UDF函数? step1:继承类实现方法step2:打成jar包,添加到Hive中step3:指定类创建函数即可
知识点16:Hive中的函数:parse_url_tuple
目标:掌握parse_url_tuple函数的使用
路径
step1:URL的分析需求step2:URL的组成step3:URL的解析
实施
URL的分析需求
一般需要对用户访问和来源的url来做分析访问分析:用户当前正在访问的页面是什么 分析当前网站热门访问的top10分类 对所有用户当前正在访问域名进行分组聚合排序 来源分析:用户是从哪个页面跳转到我们的平台的 分析网站所有用户都是从什么地方进入网站的
URL的组成
/index.jsp ?cu=true&utm_source=baidu-pinzhuan&utm_medium=cpc&utm_campaign=t_288551095_baidupinzhuan&utm_term=0f3d30c8dba7459bb52f2eb5eba8ac7d_0_d4905eaf846c46baa9a57cf05415fb29
URL的解析函数
数据
vim /export/data/lateral.txt
1/path/p1.php?query=12/news/index.jsp?uuid=frank3/index?source=baidu
create table tb_url(id int,url string) row format delimited fields terminated by '\t';--加载数据load data local inpath '/export/data/lateral.txt' into table tb_url;
函数
parse_url:用于解析URL,每次只能解析一个元素parse_url_tuple:用于解析URL,是一个UDTF函数,一次解析多个元素
使用
0: jdbc:hive2://node3:10000> select parse_url(url,'HOST') from tb_url;+----------------+--+| c0 |+----------------+--+| || |||+----------------+--+3 rows selected (0.22 seconds)0: jdbc:hive2://node3:10000> select parse_url(url,'PATH') from tb_url;+------------------+--+| c0 |+------------------+--+| /path/p1.php|| /news/index.jsp || /index |+------------------+--+3 rows selected (0.062 seconds)0: jdbc:hive2://node3:10000> select parse_url(url,'QUERY') from tb_url;+---------------+--+|c0 |+---------------+--+| query=1 || uuid=frank || source=baidu |+---------------+--+3 rows selected (0.09 seconds)0: jdbc:hive2://node3:10000> select parse_url_tuple(url,'HOST','PATH','QUERY') from tb_url;+----------------+------------------+---------------+--+| c0 | c1 |c2 |+----------------+------------------+---------------+--+| | /path/p1.php| query=1 || | /news/index.jsp | uuid=frank ||| /index | source=baidu |+----------------+------------------+---------------+--+3 rows selected (0.157 seconds)
小结
parse_url与parse_url_tuple函数的功能与区别? 功能:解析url区别:parse_url_tuple是一个UDTF函数,可以一次性解析多个元素
知识点17:Hive中的函数:lateral view
目标:掌握Hive中lateral view侧视图的使用
路径
step1:UDTF函数的问题step2:lateral view
实施
UDTF函数的问题
udtf只能直接select中使用不可以添加其他字段使用不可以嵌套调用不可以和group by/cluster by/distribute by/sort by一起使用
```select id,parse_url_tuple(url,'HOST','PATH','QUERY') from tb_url;```
lateral view
功能:UDTF的结果构建成一个类似于视图的表,然后将原表中的每一行和UDTF函数输出的每一行进行连接,生成一张新的虚拟表
语法
select …… from tabelA lateral view UDTF(xxx) 别名 as col1,col2,col3……
实现
select a.id, b.host,b.path,b.queryfrom tb_url a lateral view parse_url_tuple(url,'HOST','PATH','QUERY') b as host,path,query;
小结
lateral view的功能是? 搭配UDTF函数使用,将UDTF函数的结果变成类似于视图的表,方便与原表进行操作 UDTF函数用法 用法一:单独在select后面使用,select中不能包含别的字段用法二:搭配lateral view使用
知识点18:Hive中的函数:explode
目标:掌握explode函数的用法
实施
功能
将集合类型中集合的每个元素变成一行
语法
explode( Map | Array)
实现
单独使用
select explode(work_locations) as loc from complex_array;select explode(hobby) from complex_map;
- 侧视图连用```sqlselect a.id,a.name,b.*from complex_map a lateral view explode(hobby) b as hobby,deep;```
小结
explode的功能及语法?
附录一:Hive Maven 依赖
<properties><hadoop.version>2.7.5</hadoop.version><mysql.version>5.1.38</mysql.version><hive.version>2.1.0</hive.version></properties><dependencies><!--引入单元测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><!-- Hadoop Client 依赖 --><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>${hadoop.version}</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>${hadoop.version}</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>${hadoop.version}</version></dependency><!-- MySQL Client 依赖 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!-- Hive依赖 --><dependency><groupId>org.apache.hive</groupId><artifactId>hive-exec</artifactId><version>${hive.version}</version></dependency><dependency><groupId>org.apache.hive</groupId><artifactId>hive-common</artifactId><version>${hive.version}</version></dependency><dependency><groupId>org.apache.hive</groupId><artifactId>hive-cli</artifactId><version>${hive.version}</version></dependency><dependency><groupId>org.apache.hive</groupId><artifactId>hive-jdbc</artifactId><version>${hive.version}</version></dependency></dependencies>