2016-03-21 34 views
6

Sto creando una tabella HBASE con un valore intero -17678. Ma quando lo recupero da pheonix mi dà un diverso valore positivo. RowKey è una riga di comando composta e non vi sono problemi con la riga di comando. inserimentoPhoenix non visualizza correttamente i valori interi negativi

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(); 
      } 

    } 
} 

Phoenix recupero:

selezionare CAST ("Value" AS INTEGER) da TEST;

+------------------------------------------+ 
|   TO_INTEGER(test."Value")   | 
+------------------------------------------+ 
| 2147465970        | 
+------------------------------------------+ 

Qualcosa non va? o un problema di fenice?

risposta

7

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

La rappresentazione binaria è un numero intero di 4 byte con il bit di segno capovolto (valori sorta modo che negative prima valori positivi).

Quindi per convertire dal formato di serializzazione HBase in formato Phoenix:

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

Così l'uscita è come previsto. È necessario essere consapevoli della rappresentazione binaria quando si inseriscono dati usando HBase.

La lettura diretta di HBase toByte in Phoenix è possibile solo con i tipi di dati CHAR e UNSIGNED_ *. Dovresti serializzare in modo appropriato per altri tipi di dati. vale a dire. impostazione i = 2147465970 quando si intende inserire -17678.

Si consiglia di utilizzare Phoenix per inserire i dati. Se sei preoccupato di mantenere la luce delle applicazioni sulle dipendenze, Phoenix offre un driver jdbc "sottile" (4mb anziché 86mb).

https://phoenix.apache.org/server.html


Se è assolutamente necessario utilizzare HBase, è possibile serializzare i numeri firmato utilizzando un XOR bit a bit.

Per i numeri interi, si desidera XOR il proprio i con una maschera di bit per capovolgere il bit di segno.

La maschera di bit da applicare a un numero intero di 4 byte è:

(10000000000000000000000000000000)2 = (-2147483648)10 

Da http://ideone.com/anhgs5, otteniamo 2147465970. Se lo inserisci usando HBase, quando leggi usando Phoenix, leggerai -17678).

Avrete bisogno di una maschera di bit diversa per Bigint (maschera di bit condivisa con i tipi di data e ora), Piccola, Float e Doppia.

+0

Grazie. Quindi quando interrogherò usando il driver JDBC otterrò il valore corretto? Non voglio inserire i dati usando phoenix, l'API del client hbase è la scommessa. –

+0

Non funzionerà così com'è perché i dati non sono stati serializzati nel formato previsto da Phoenix. Ho aggiornato la mia risposta con un esempio su come usare HBase per inserire dati che possono essere correttamente deserializzati da Phoenix. – kliew

+0

Quindi l'unica soluzione sarebbe inserire i dati usando pheonix stesso? –