Phoenix不会正确显示负整数值

时间:2016-03-21 12:30:16

标签: java hadoop serialization hbase phoenix

我正在创建一个值为整数-17678的HBASE表。但是当我从pheonix中检索它时,它给了我一个不同的正值。 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                               | 
+------------------------------------------+

这里有什么不对吗?还是凤凰问题?

2 个答案:

答案 0 :(得分:7)

http://phoenix.apache.org/language/datatypes.html

  

二进制表示是一个4字节整数,符号位翻转(因此负值在正值之前排序)。

所以要从HBase序列化格式转换为Phoenix格式:

(-17678)10 = (11111111111111111011101011110010)2
=> (01111111111111111011101011110010)2 = (2147465970)10

因此输出符合预期。使用HBase插入数据时需要注意二进制表示。

直接HBase toByte到Phoenix读取只能使用CHAR和UNSIGNED_ *数据类型。您必须为其他数据类型进行适当的序列化。即。如果您要插入i = 2147465970,请设置-17678

我建议使用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,您将需要不同的位掩码。

答案 1 :(得分:0)

尝试类似的东西:

//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));