hive 虽然自带了很多函数,但是毕竟有限,无法满足所有业务场景,用户可以自定义函数来实现特定功能
UDF
user define function,用户自定义函数
可以分为 3 类
UDF:一进一出
UDAF:聚集函数,多进一出,user define aggregation function
UDTF:炸裂函数,一进多出
UDF 可以用多种语言实现,如 java、python、hive
准备工作
建表
create external table person( name string, idcard string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED as TEXTFILE;
外建表,还记得吗?
外建表不能 truncate 清空,如果是 drop 删表,只删除元数据,hdfs 中的数据还在
写入如下数据
neil 411326199402110030 pony 41132519950911004x jcak 12312423454556561 tony 412345671234908
Hive Function
即用 hql 来实现 function,这是最简单的,写完 function 直接运行 sql 就行了
select idcard, case when length(idcard) = 18 then case when substring(idcard,-2,1) % 2 = 1 then '男' when substring(idcard,-2,1) % 2 = 0 then '女' else 'unknown' end when length(idcard) = 15 then case when substring(idcard,-1,1) % 2 = 1 then '男' when substring(idcard,-1,1) % 2 = 0 then '女' else 'unknown' end else '不合法' end from person;
Python UDF
python 也毕竟简单,类似于 mapreduce
# -*- coding: utf-8 -*- import sys for line in sys.stdin: detail = line.strip().split("\t") if len(detail) != 2: continue else: name = detail[0] idcard = detail[1] if len(idcard) == 15: if int(idcard[-1]) % 2 == 0: print("\t".join([name,idcard,"女"])) else: print("\t".join([name,idcard,"男"])) elif len(idcard) == 18: if int(idcard[-2]) % 2 == 0: print("\t".join([name,idcard,"女"])) else: print("\t".join([name,idcard,"男"])) else: print("\t".join([name,idcard,"身份信息不合法!"]))
输入就是 hive 表的每一行
本地测试 UDF
直接在 hive 上测试比较麻烦,我们可以在本地测试下 UDF 写的是否正确,直接命令行即可
cat person.txt|python person.py
hive 中使用 UDF
在 hive 中使用 python 编写的 UDF 需要借助 transform 函数,语法如下
SELECT TRANSFORM (<columns>) USING 'python <python_script>' AS (<columns>) FROM <table>;
顾名思义,就是用 python 脚本来转换 某列 生成新的列作为输出
第一步:加载 py 文件
在 hive 中执行如下代码
add file /xxx/udf1.py
xxx 为本地路径;
注意在每次启动 hive 后都要重新加载
第二步:使用 UDF 查询
select transform(name,idcard) USING 'python udf1.py' AS (name,idcard,gender) from person;
neil 411326199402110030 男 pony 41132519950911004x 女 jcak 12312423454556561 身份信息不合法! tony 412345671234908 女
vs1
select transform(name,idcard) USING 'python udf1.py' AS (name,idcard) from person;
neil 411326199402110030 pony 41132519950911004x jcak 12312423454556561 tony 412345671234908
vs2
select transform(name) USING 'python udf1.py' AS (name,idcard,gender) from person;
可执行,但是无输出
转换的列和输出的列在一定程度上保持一致
python UDF 是效率比较低的,因为python 直接向系统请求资源,而不是通过 yarn 的 rm 申请,对资源的利用率较低
Java UDF
见官网
参考资料:
https://cwiki.apache.org/confluence/display/hive/hiveplugins 官网 java 用法
https://blog.csdn.net/qq_26937525/article/details/54136317
https://blog.csdn.net/liu82327114/article/details/80670415 讲述了 python udf 的缺点
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)