我在HDFS csv中有一些加密数据,我为它创建了一个Hive表,我想运行一个首先加密查询参数的Hive查询,然后进行查找。我有一个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);
}
}
然后我将Hive查询运行为:
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不支持 IN 或在where子句中选择查询。
我该怎么办?
我可以这样做:
select encrypt('Ann') as ann from cc_details where first_name = ann;
这也不起作用,因为查询解析器抛出错误,说 ann 不是已知列
答案 0 :(得分:1)
最后用右外连接作为
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);
答案 1 :(得分:0)
我认为您正在寻找的是UDF上的注释@UDFType(deterministic = true)
。它绝对可以在Generic UDF上使用,您可以检查它是否可用于您创建的常规UDF。如果没有,只需将您的UDF转换为GenericUDF即可。您可以在this blog post上阅读我之前写过的内容。
答案 2 :(得分:0)
另一种方法(实际上我最终使用的方式)是通过缓存加密的结果。这种方式实际上更快,因为通过连接,您将获得一组单独的map-reduce作业,这会减慢总体执行时间。
就像这样:
private static String result = null;
public Text evaluate(String data) {
if (result == null) {
result = Data.encrypt(data);
}
return new Text(result);
}