2016-03-21 14 views
6

Tôi đang tạo bảng HBASE có giá trị là số nguyên -17678. Nhưng khi tôi lấy nó từ pheonix nó mang lại cho tôi một giá trị tích cực khác. RowKey là một rowkey tổng hợp và không có vấn đề với rowkey.Phoenix không hiển thị giá trị số nguyên âm một cách chính xác

HBase chèn:

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 hồi:

chọn CAST ("Giá trị" AS INTEGER) từ TEST;

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

Có gì sai ở đây? hoặc một vấn đề phượng hoàng?

Trả lời

7

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

Các đại diện nhị phân là một số nguyên 4 byte với bit dấu lật (giá trị các loại để tiêu cực trước những giá trị tích cực).

Vì vậy, để chuyển đổi từ định dạng serialization HBase sang định dạng Phoenix:

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

Do đó, sản lượng được như mong đợi. Bạn cần phải biết về biểu diễn nhị phân khi chèn dữ liệu bằng HBase.

Trực tiếp HBase toByte tới Phoenix đọc chỉ có thể với CHAR và UNSIGNED_ * loại dữ liệu. Bạn sẽ phải tuần tự hóa một cách thích hợp cho các loại dữ liệu khác. I E. thiết lập i = 2147465970 khi bạn muốn chèn -17678.

Tôi khuyên bạn nên sử dụng Phoenix để chèn dữ liệu. Nếu bạn đang lo lắng về việc giữ cho ứng dụng của bạn ánh sáng trên phụ thuộc, Phoenix cung cấp một trình điều khiển jdbc "mỏng" (4mb thay vì 86mb).

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


Nếu bắt buộc phải sử dụng HBase, bạn có thể serialize ký số bằng cách sử dụng một XOR trên bit.

Đối với số nguyên, bạn sẽ muốn XOR i bằng bitmask để lật bit dấu.

Các bitmask để áp dụng cho một Integer 4 byte là:

(10000000000000000000000000000000)2 = (-2147483648)10 

Từ http://ideone.com/anhgs5, chúng tôi nhận 2147465970. Nếu bạn chèn bằng HBase, khi bạn đọc bằng Phoenix, bạn sẽ đọc -17678).

Bạn sẽ cần một bitmask khác cho Bigint (bitmask chia sẻ với các loại ngày giờ), Smallint, Float và Double.

+0

Cảm ơn. Vì vậy, khi tôi truy vấn bằng cách sử dụng trình điều khiển JDBC tôi sẽ nhận được giá trị chính xác? Tôi không muốn chèn dữ liệu bằng cách sử dụng phượng, hbase client API là đặt cược. –

+0

Nó sẽ không hoạt động vì dữ liệu không được tuần tự hóa theo định dạng mà Phoenix mong đợi. Tôi cập nhật câu trả lời của tôi với một ví dụ về cách sử dụng HBase để chèn dữ liệu có thể được deserialized đúng cách bởi Phoenix. – kliew

+0

Vì vậy, cách giải quyết duy nhất sẽ được chèn dữ liệu bằng cách sử dụng pheonix chính nó? –

Các vấn đề liên quan