我有一个hive / hbase集成表,定义如下。
create table user_c(user_id int, c_name string, c_kind string, c_industry string,
c_jobtitle string, c_workyear int, c_title string, c_company string)
stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf1:c_name,cf1:c_kind,cf1:c_industry,cf1:c_jobtitle,cf1:c_workyear,cf1:c_title,cf1:c_company")
TBLPROPERTIES ("hbase.table.name" = "user_c");
在我的java代码中,我创建了一个Put
并用从db读取的值填充它。代码如下所示:
final Put to = new Put(getByte(from, keyColumn));
for (final IColumn column : table.getColumns()) {
if (column.equals(keyColumn)) continue;
to.add(Bytes.toBytes(column.getColumnFamily()), Bytes.toBytes(column.getDestName()), getByte(from, column));
}
return to;
getByte
是一种将值转换为byte[]
的方法。
它看起来像
byte[] getByte(final Map<String, Object> map, IColumn column) {
final Object val = map.get(column.getName());
if (val instanceof Integer) {
return Bytes.toBytes((Integer) val);
}
...
}
然后把它放入hbase。
我可以从hbase shell扫描记录。
hbase(main):001:0> scan 'user_c'
ROW COLUMN+CELL
\x00\x0A\x07\x0D column=cf1:c_workyear, timestamp=1350298280554, value=\x00\x00\x07\xD8
\x00\x0A\x07\x0D column=cf1:c_industry, timestamp=1350298280554, value=120
...
行键是Integer
类型,在int
方法处理时,应自动取消对原始getByte
类型的设置。不仅行键,而且其他数字类型列(cf1:c_workyear)显示为\x00\x0A\x07\x0D
,一个字节数组。
同时,String
类型列(cf1:c_industry)仅显示其值。
这没关系吗?
当我从配置单元查询记录时,它只给我一个NULL
而不是数字类型列的值。
hive> select c_industry, c_workyear from user_c limit 1;
Total MapReduce CPU Time Spent: 10 seconds 370 msec
OK
120 NULL
Time taken: 46.063 seconds
似乎hive无法识别c_workyear值。我猜是因为那种类型不正确。但是,int
字节数组不应该存储为int
值而不是字节数组吗?
任何人都知道如何解决这个问题?
非常感谢。
答案 0 :(得分:5)
在表格定义中尝试此操作
"hbase.columns.mapping" = ":key,cf1:c_name,cf1:c_kind,cf1:c_industry#b,cf1:c_jobtitle,cf1:c_workyear#b,cf1:c_title,cf1:c_company"
请注意在二进制字段后使用#b
。我们已经成功地使用了这段时间了
答案 1 :(得分:0)
我们遇到了同样的问题,并且在列映射参数中使用#b解决了-(“ hbase.columns.mapping” =“:key,C1:Name,C1:marks#b”)
“标记”列存储为字节数组,它是实际的长型。
@scarcer,以字符串类型存储所有字段将不是一种有效的解决方案。