Phoenix 无法正确显示负整数值
Posted
技术标签:
【中文标题】Phoenix 无法正确显示负整数值【英文标题】:Phoenix doesn't display negative integer values correctly 【发布时间】:2016-07-07 23:09:32 【问题描述】:我正在创建一个值为整数 -17678 的 HBASE 表。但是当我从凤凰取回它时,它给了我一个不同的积极价值。 RowKey是复合rowkey,rowkey没有问题。
Hbase 插入:
public class test
public static void main(String args[])
Configuration config = HBaseConfiguration.create();
Connection connection = ConnectionFactory.createConnection(config);
Table table = connection.getTable(TableName.valueOf("TEST"));
Integer i=-17678;
try
Put p = new Put(Bytes.toBytes("rowkey"));
p.addColumn(Bytes.toBytes("test"),Bytes.toBytes("test"),Bytes.toBytes(i));
table.put(p);
finally
table.close();
connection.close();
凤凰检索:
从 TEST 中选择 CAST("Value" AS INTEGER) ;
+------------------------------------------+
| TO_INTEGER(test."Value") |
+------------------------------------------+
| 2147465970 |
+------------------------------------------+
这里有什么问题吗?还是凤凰问题?
【问题讨论】:
【参考方案1】:http://phoenix.apache.org/language/datatypes.html
二进制表示是一个符号位翻转的 4 字节整数(因此负值排在正值之前)。
所以要从 HBase 序列化格式转换为 Phoenix 格式:
(-17678)10 = (11111111111111111011101011110010)2
=> (01111111111111111011101011110010)2 = (2147465970)10
因此输出符合预期。使用 HBase 插入数据时,您需要注意二进制表示。
只有 CHAR 和 UNSIGNED_* 数据类型才能将 HBase toByte 直接读取到 Phoenix 读取。您必须对其他数据类型进行适当的序列化。 IE。当您要插入 -17678
时设置 i = 2147465970
。
我推荐使用 Phoenix 插入数据。如果您担心让您的应用程序不依赖于依赖项,Phoenix 提供了一个“瘦” jdbc 驱动程序(4mb 而不是 86mb)。
https://phoenix.apache.org/server.html
如果您绝对必须使用 HBase,您可以使用按位 XOR 序列化有符号数。
对于整数,您可能希望使用位掩码对您的i
进行异或运算以翻转符号位。
应用于 4 字节整数的位掩码是:
(10000000000000000000000000000000)2 = (-2147483648)10
从http://ideone.com/anhgs5,我们得到2147465970
。如果您使用 HBase 插入,当您使用 Phoenix 阅读时,您将阅读 -17678)
。
您需要为 Bigint(与日期时间类型共享位掩码)、Smallint、Float 和 Double 使用不同的位掩码。
【讨论】:
谢谢。那么当我使用 JDBC 驱动程序查询时,我会得到正确的值吗?我不想使用 phoenix 插入数据,hbase 客户端 API 是最好的选择。 它不会按原样工作,因为数据没有按照 Phoenix 预期的格式序列化。我用一个关于如何使用 HBase 插入可以被 Phoenix 正确反序列化的数据的示例更新了我的答案。 所以唯一的解决方法是使用 pheonix 本身插入数据? 我使用 HBase 使用解决方法编辑了我的原始答案。此解决方案对您有用吗? 基本上你会想要在addColumn
中用i ^ -2147483648
替换Bytes.toBytes(i)
。 -2147483648
是当您与整数进行异或时将翻转符号位的位掩码,并且您需要为每个有符号数据类型使用不同的位掩码。【参考方案2】:
尝试类似:
//Add dependencies in your pom.xml
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
<version>$phoenix.core.version</version>
<scope>provided</scope>
</dependency>
比:
//Import these classes. More types available
import org.apache.phoenix.schema.types.PDecimal, PInteger, PVarchar
//and replace your addColumn method by this one:
p.addColumn(Bytes.toBytes("test"),Bytes.toBytes("test"),PInteger.INSTANCE.toBytes(i));
//Or if you wish a Decimal
p.addColumn(Bytes.toBytes("test"),Bytes.toBytes("test"),PDecimal.INSTANCE.toBytes(i));
【讨论】:
以上是关于Phoenix 无法正确显示负整数值的主要内容,如果未能解决你的问题,请参考以下文章