我在HDFS CSV中有一些加密的数据,我已经创建了一个蜂巢表,我想运行一个首先加密查询参数的蜂巢查询,然后进行查找。我有一个UDF进行加密如下:
public class ParamEncrypt extends UDF {
public Text evaluate(String name) throws Exception {
String result = new String();
if (name == null) { return null; }
result = ParamData.encrypt(name);
return new Text(result);
}
}
然后我将蜂巢查询运行为:
select * from cc_details where first_name = encrypt('Ann');
问题是,它在表中的每个记录中运行加密('ann')。我希望它进行一次加密,然后进行比赛。我尝试了:
select * from cc_details where first_name in (select encrypt('Ann') from cc_details limit 1);
但Hive不支持或在Whewer子句中选择查询。
我该怎么办?
我可以做类似的事情:
select encrypt('Ann') as ann from cc_details where first_name = ann;
也不起作用,因为查询解析器会引发错误,说 ann 不是已知的列
select * from cc_details ssn_tbl
right outer join ( select encrypt('850-37-8230','ssn') as ssn
from cc_details limit 1) ssn_tmp
on (ssn_tbl.ssn = ssn_tmp.ssn);
我认为您正在寻找的是UDF上的注释@UDFType(deterministic = true)
。它肯定在通用UDF上可用,您可以像创建的那样检查它是否适用于常规UDF。如果没有,只需将UDF转换为genericudf即可。您可以在我之前写的这篇博客文章中阅读有关它的信息。
另一种做到这一点的方法(实际上我最终使用的方式)是通过缓存加密的结果。它实际上是这样更快的,因为有了加入,您会得到一组单独的地图降低作业,这会减慢整个执行时间。
这样:
private static String result = null;
public Text evaluate(String data) {
if (result == null) {
result = Data.encrypt(data);
}
return new Text(result);
}