ITPub博客

首页 > 数据库 > 数据库开发技术 > Hive利用宏自定义简短的函数

Hive利用宏自定义简短的函数

原创 数据库开发技术 作者:HelloTech技术派 时间:2020-11-25 08:00:00 0 删除 编辑

背景

Hive SQL 代码的可读性一直是个问题哈,因为业务比较复杂,一般情况下写出来的代码也会很冗长,存在重复的逻辑,本篇通过一个工作过程中的示例来优化一下重复逻辑的问题,希望能够写出可读性更好的代码。

重复代码及问题

通过股票代码来判断所属市场,代码片段如下:

.....
 CASE 
  WHEN substr( a.symbol, 1, 3 ) = '000' THEN
  '深圳主板' 
  WHEN substr( a.symbol, 1, 3 ) = '001' THEN
  '深圳主板' 
  WHEN substr( a.symbol, 1, 3 ) = '002' THEN
  '中小企业板' 
  WHEN substr( a.symbol, 1, 3 ) = '003' THEN
  '中小企业板' 
  WHEN substr( a.symbol, 1, 3 ) = '004' THEN
  '中小企业板' 
  WHEN substr( a.symbol, 1, 3 ) = '688' THEN
  '科创板' 
  WHEN substr( a.symbol, 1, 2 ) = '30' THEN
  '创业板' 
  WHEN substr( a.symbol, 1, 2 ) = '60' THEN
  '上海主板' 
  WHEN substr( a.symbol, 1, 1 ) IN ( '4', '8' ) THEN
  '三板' 
 END AS mar_plate
.....

重复代码带来最大的问题就是可维护性,如果上面的代码在多个地方拷贝过,当逻辑需要修改时,要同时修改多处,如果有一处遗漏,就会出现 bug,排查起问题来是非常困难的,把自己坑死~

解决方案

自定义函数

重复的逻辑最先想到的是通过自定义函数来解决这个问题,此时就可以考虑使用用户自定义函数(UDF:user-defined function)

根据用户自定义函数类别分为以下三种:

  1. UDF(User-Defined-Function)一进一出

  2. UDAF(User-Defined Aggregation Function)聚集函数,多进一出,类似于:count/max/min

  3. UDTF(User-Defined Table-Generating Functions)一进多出,如 lateral view explore()

自定义函数编程步骤:

  • 第一步:创建 Maven Java 工程,导入 jar 包
  • 第二步:继承 org.apache.hadoop.hive.ql.UDF,并重载 evaluate 方法
  • 第三步:将项目打包,并上传到 Hive 的 lib 目录下
  • 第四步:添加上传后的 jar 包
  • 第五步:设置函数与自定义函数关联

但是像我们遇到的问题,并不是真正需要 UDF,而且 UDF 有更新维护也挺麻烦的,我们只是需要把一些繁琐、结构简单的逻辑封装起来以便重复在多个地方使用。

宏

宏可以看做是一个简短的函数,或者是对一个表达式取别名,同时可以将这个表达式中的一些值作为变量调用时传入,比较适合于需要用到很多次的表达式操作进行封装,然后取个简短点的别名来调用,省去了定义函数的复杂步骤哈。

创建一个宏,通过股票代码来判断所属市场

DROP TEMPORARY MACRO
IF
 EXISTS getMarPlate;
CREATE TEMPORARY MACRO getMarPlate ( symbol string )
CASE
  
  WHEN substr( symbol, 1, 3 ) = '000' THEN
  '深圳主板' 
  WHEN substr( symbol, 1, 3 ) = '001' THEN
  '深圳主板' 
  WHEN substr( symbol, 1, 3 ) = '002' THEN
  '中小企业板' 
  WHEN substr( symbol, 1, 3 ) = '003' THEN
  '中小企业板' 
  WHEN substr( symbol, 1, 3 ) = '004' THEN
  '中小企业板' 
  WHEN substr( symbol, 1, 3 ) = '688' THEN
  '科创板' 
  WHEN substr( symbol, 1, 2 ) = '30' THEN
  '创业板' 
  WHEN substr( symbol, 1, 2 ) = '60' THEN
  '上海主板' 
  WHEN substr( symbol, 1, 1 ) IN ( '4', '8' ) THEN
  '三板' 
 END

前面的 SQL 就可以简化成下面的样子

......
getMarPlate(a.symbol) AS mar_plate
......

使用宏对这段逻辑进行提炼,起到优化开发效率、提升程序可读性的效果。

工作中常用的宏的场景:有关空值的处理,时间处理,数值计算,只要发现有类似的逻辑被反复调用,就可以考虑这种方式。

如果觉得还有帮助的话,你的关注和转发是对我最大的支持,O(∩_∩)O:


原文作者:HelloTech技术派;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2017-12-05

  • 博文量
    181
  • 访问量
    73719