一、存入數據類型
Hbase里面,rowkey是按照字典序進行排序。存儲的value值,當用filter進行數據篩選的時候,所用的比較算法也是字典序的。
1、當存儲的value值是float類型的時候,錄入數據可以錄入,但是讀取出來的數據會存在問題會出問題
例如:
存入數據的代碼:
p = new Put(Bytes.toBytes(“66”));
p.add(Bytes.toBytes("value"),Bytes.toBytes("null"), (Long.valueOf(“668”) ), Bytes.toBytes(Float.valueOf(533.0)));
...
在hbase shell里面取出的數據:
hbase(main):007:0> get 'DATA‘, '66'
COLUMN CELL
value:null timestamp=668, value=D\x05@\x00
1 row(s) in 0.1100 seconds
可以看到取出來的value值是不可讀的。
在java程序里面則沒有返回結果,如果想強制類型轉換讀取這個數據,則會報錯,說格式錯誤:
try {
Result rr = table.get(g);
for (KeyValue kvv : rr.raw()) {
float f = Float.parseFloat(new String(kvv.getValue()));
System.out.println(f);
tempList.add(kvv.getTimestamp() + "," + new String(kvv.getValue()));
}
} catch (IOException e) {
e.printStackTrace();
}
java.lang.NumberFormatException: For input string: "D@"
根據hbase都是按照字典序進行排序的前提,(字典序多少針對字符串的),可以推測hbase不支持float類型數據的存儲
2、如果把錄入數據改成int型
存入數據的代碼:
p = new Put(Bytes.toBytes(“66”));
p.add(Bytes.toBytes("value"),Bytes.toBytes("null"), (Long.valueOf(“668”) ), Bytes.toBytes(Integer.valueOf(533.0)));
...
取出的數據
hbase(main):007:0> get 'DATA‘, '66'
COLUMN CELL
value:null timestamp=668, value=\x00\x00\x00\x00\x00\x00\x02\x15
1 row(s) in 1.4510 seconds
在java程序里面則沒有返回結果,當試圖把取出的數據強制類型轉換的時候,同樣報錯
3、 如果把錄入數據改成long型
存入數據的代碼:
p = new Put(Bytes.toBytes(“66”));
p.add(Bytes.toBytes("value"),Bytes.toBytes("null"), (Long.valueOf(“668”) ), Bytes.toBytes(Long.valueOf(533.0)));
...
取出的數據
hbase(main):007:0> get 'DATA‘, '66'
COLUMN CELL
value:null timestamp=668, value=\x00\x00\x00\x00\x00\x00\x02\x15
1 row(s) in 1.4510 seconds
同樣不可讀
4、如果把錄入value格式改成String類型,則正常
存入數據的代碼:
p = new Put(Bytes.toBytes(“66”));
p.add(Bytes.toBytes("value"),Bytes.toBytes("null"), (Long.valueOf(“668”) ), Bytes.toBytes("533.0"));
...
取出的數據
hbase(main):007:0> get 'DATA‘, '66'
COLUMN CELL
value:null timestamp=668, value=533.0
1 row(s) in 0.8500 seconds
在java程序里面也有可用的結果
通過上述測試說明,hbase現在只支持String類型數據的存取
二、 小的注意點
1、取value的時候一定要用 new String(kv[i].getValue())的格式
System.out.println(kv[i].getValue().toString()); 錯誤
System.out.println(new String(kv[i].getValue())); 正確
2、用完ResultScanner 后一定要記得關掉:resultScanner.close();
3、當錄入的數據已經使用了String類型
那么,進行比較的時候也要使用String類型。例如下面使用float類型的filter,則不會對結果產生任何影響
Filter filter = new SingleColumnValueFilter(
Bytes.toBytes("value"),Bytes.toBytes("null") , CompareOp.LESS,Bytes.toBytes(Float.valueOf((float) 5.0)));
scan.setFilter(filter);
如果換成
Filter filter = new SingleColumnValueFilter(
Bytes.toBytes("value"),Bytes.toBytes("null") , CompareOp.LESS,Bytes.toBytes("5.0"));
scan.setFilter(filter);
則會會結果產生影響,但是需要注意的是,這里的設置方式也是錯誤的。
追蹤原因:
hbase關於比較的相關源碼如下:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public static int compareTo(final byte [] left, final byte [] right) {
return compareTo(left, 0, left.length, right, 0, right.length);
}
public static int compareTo(byte[] buffer1, int offset1, int length1,
byte[] buffer2, int offset2, int length2) {
// Bring WritableComparator code local
int end1 = offset1 + length1;
int end2 = offset2 + length2;
for (int i = offset1, j = offset2; i < end1 && j < end2; i++, j++) {
int a = (buffer1[i] & 0xff);
int b = (buffer2[j] & 0xff);
if (a != b) {
return a - b;
}
}
return length1 - length2;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
疑問:下面long型篩選,返回的結果並沒有value值,但是,結果的數據條數卻會發生變化,即使針對這個特定的時間戳讀取數據也沒有結果數據(曾試圖用scan確定了那個rowkey的那個列簇的那個列的那個時間戳,任何通過這些信息用get進行取值,但是也不能返回value值),為什么結果的條數會發生變化呢?
1、filter
(1)錄入的value是long型
如果想設置成數值型比較,則要進行數據類型設置,如下
Filter filter = new SingleColumnValueFilter(
Bytes.toBytes("value"),Bytes.toBytes("null") , CompareOp.LESS,Bytes.toBytes(Long.valueOf(5)));
scan.setFilter(filter);
resultScanner = table.getScanner(scan);
結果是:
rowkey 列簇:列名 時間戳 value
115404869300388065 value:null 27
115404869300388065 value:null 26
但是如果設置成字符串行,如下:
Filter filter = new SingleColumnValueFilter(
Bytes.toBytes("value"),Bytes.toBytes("null") , CompareOp.LESS,Bytes.toBytes(”5“));
scan.setFilter(filter);
resultScanner = table.getScanner(scan);
則返回的是按照字典序比較的結果(ps:rowkey是按照字典序排列的,10000比2 “小”)
115404869300388065 value:null 27
115404869300388065 value:null 3
115404869300388065 value:null 2
115404869300388065 value:null 1
細心的話可以發現輸出的幾個也是按照降序的順序排列的