Hive如何比较复杂数据类型

本文探讨了Hive中如何比较复杂数据类型,如Array、Struct和Map。通过实验得出,Array和Struct在内部元素为基本数据类型时可以比较,但Map会抛出异常。深入Hive源码发现,比较逻辑主要针对基本数据类型,对于Array和Struct,比较基于元素顺序。了解这种比较机制有助于在特殊场景下优化查询,例如用struct的访问时间进行排序以找到用户第一条访问记录,但不能直接用于二级排序。

Hive中的复杂数据类型,比如array,struct, map能进行大小的比较吗,我们先来做实验看看结果。

Array

select
  max(arr)
from (
  select array(1,3,5) as arr
  union all 
  select array(2,4,1) as arr
  union all
  select array(2,3,5) as arr
  union all
  select array(2,4,0) as arr
  union all
  select array(2,4,1,0) as arr
)a

的到的结果是[2,4,1,0]
Struct

select
  max(str)
from (
  select named_struct('a', 1, 'b', 3, 'c', 5) as str
  union all 
  select named_struct('a', 2, 'b', 4, 'c', 1) as str
  union all
  select named_struct('a', 2, 'b', 3, 'c', 5) as str
  union all
  select named_struct('a', 2, 'b', 4, 'c', 0) as str
  -- union all (struct必须结构相同才能union在一起)
  -- select named_struct('a', 2, 'b', 4, 'c', 1, 'd', 0) as str
)a

得到的结果是{"a":2,"b":4,"c":1}
Map

select
  max(m)
from (
  select map('a', '1', 'b', '3', 'c', '5') as m
  union all 
  select map('a', '2', 'b', '4', 'c', '1') as m
  union all
  select map('a', '2', 'b', '3', 'c', '5') as m
  union all
  select map('a', '2', 'b', '4', 'c', '0') as m
  union all
  select map('a', '2', 'b', '4', 'c', '1') as m
)a

这个会抛出异常:UDFArgumentTypeException Cannot support comparison of map<> type or complex type containing map<>.

那么hive内部具体是怎么进行复杂数据类型的比较的呢,通过github上hive的仓库可以看到执行比较的逻辑只有一句话ObjectInspectorUtils.compare()
>
那我们就看一下ObjectInspectorUtils这个类里面具体的实现。
首先是compareSupported链接

可以看到这里面基础数据类型都是支持的,数组和结构体如果里面是基础数据类型可以支持,而MAP是不支持的,这和我们的实验结果是一致的。

Struct和Array的比较逻辑在下面一点的位置

它俩的逻辑是相似的,每个元素按照顺序进行比较,数组自然就是按照位置从小到大,结构体是按照Schema的定义顺序从左到右。如果出现不相等的情况就分出了大小;否则按照长度本身进行比较,长的大、短的小。

这一段逻辑还是非常有意思,因为平时很少会遇到对复杂数据类型进行比较的情况。了解了之后就能在一些特殊情况下应用起来,比如把每一行组装成一个struct,struct中的第一个元素放用户的访问时间,就可以用max()找到用户的第一条访问记录而不用row_number()窗口函数,执行效率就可能会有些许的提高。

注意这里虽然会对每一个元素进行比较,但是这里也是不行直接用来进行二级排序的~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值