1. 程式人生 > >一起學HBase——總結HBase中的PUT、GET、DELETE操作

一起學HBase——總結HBase中的PUT、GET、DELETE操作

傳統的關係型資料庫有CRUD增刪改查操作,同樣對於NoSQL列式資料庫也有CRUD操作。本文對HBase中常用的Scan、GET、PUT、DELETE操作的用法做個總結。

Put操作

Put相當於傳統資料庫的add操作,就是在資料庫中新增一條或多條記錄。 Put操作分為兩類,一類是一次操作一條記錄,另外一類是一次操作多條資料。

HBase提供一個Put類,通過該類的物件就可以在HBase中新增資料。

Put類提供的建構函式如下:

Put(byte[] row)  
Put(byte[] row,RowLock rowLock)  
Put(byte[] row,long ts)  
Put(byte[] row,long ts,RowLock rowLock)

通過上面的建構函式可以知道在建立物件時需要提供一個byte[]型別的引數row,該引數的主要作用是作為一行資料的行鍵(row key),和關係型資料庫中的主鍵是一樣的,是一行資料的唯一鍵。

Put提供如下的add方法將資料寫入到HBase中:

Put add(byte[] family,byte[] qualifier,byte[] value)  
Put add(byte[] family,byte[] qualifier,long ts,byte[] value)  
Put add(KeyValuee kv)throws IOException

使用Put add(byte[] family,byte[] qualifier,byte[] value)方法新增資料時,因為沒有指定時間戳,因此時間戳由region伺服器提供。

使用Put add(byte[] family,byte[] qualifier,long ts,byte[] value) 方法新增資料時,由時間戳由引數ts指定。

使用Put add(KeyValue kv)throws IOException新增資料時,將行鍵、列族、列限定符、時間戳和單元格值封裝為一個KeyValue物件。

將一行資料輸入到HBase中的程式碼:

public class HBasePut{
    public static void main(String[] args)throws IOExcetion{
        //通過載入hbase-default.xml和hbase-site.xml檔案的配置生成Configuration物件
        Configuration conf = HBaseConfiguration.create();
        
        //建立HTable物件,用於操作HBase中的bigdata17_table表
        HTable table = new HTable(conf,"bigdata17_table");
        //建立Put物件,並制定這行資料的行鍵bigdata17_row1
        Put put = new Put(Bytes.toBytes("bigdata17_row1"));
        //新增名為colfam1:qual1列,並設定值為val1
        put.add(Bytes.toBytes("colfaml"),Bytes.toBytes("qual1"),Bytes.toBytes("val1"));
        //將資料插入到表bigdata17_table
        table.put(put);
    }
}

將多行資料插入到HBase表中的程式碼:

List<Put> puts = new ArrayList<Put>();

Put put1 =  new Put(Bytes.toBytes("bigdata17_row1"));
put1.add(Bytes.toBytes("colfaml"),Bytes.toBytes("qual1"),Bytes.toBytes("val1"));
puts.add(put1);

Put put2 =  new Put(Bytes.toBytes("bigdata17_row2"));
put2.add(Bytes.toBytes("colfam2"),Bytes.toBytes("qual2"),Bytes.toBytes("val2"));
puts.add(put2);

Put put3 =  new Put(Bytes.toBytes("bigdata17_row2"));
put3.add(Bytes.toBytes("colfam1"),Bytes.toBytes("qual2"),Bytes.toBytes("val3"));
puts.add(put3);

table.put(puts);

和一次新增一條資料的區別是,使用了ArrayList列表,將要插入的多條資料儲存於ArrayList中。

Get操作

get操作用於從HBase中讀取資料,和Put一樣,也有兩類操作,一次讀取一條記錄,一次讀取多條記錄。

Get提供的建構函式如下的: Get(byte[] row) Get(byte[] row,RowLock rowLock) 通過上述的建構函式可知在建立Get物件時必須指定行鍵。RowLock引數的Get建構函式允許使用者設定行鎖。

HBase讀取資料的方法: Result get(Get get)throws IOException

Get類提供給瞭如下的方法用於設定精確座標讀取某個單元格的資料:

Get addFamily(byte[] family)
Get addColumn(byte[] family,byte[] qualifier)
Get setTimeRange(long minStamp,long maxStamp)throws IOException
Get setTimeStamp(long timestamp)
Get setMaxVersions()
Get setMaxVersions(int maxVersion)throws IOException

addFamily方法限制了一次只能讀取一個指定的列族,多次呼叫可以取得多個列族。 addColumn方法用於獲取指定列的資料。 setTimeStamp方法限制了讀取指定時間戳的資料。 setTimeRange用於讀取某個時間戳範圍內的資料。 setMaxVersions()方法讀取當前最大版本的資料。 setMaxVersions(int maxVersion)throws IOException方法用於讀取指定版本的資料。

get方法讀取到最新版本的資料,也是版本號最大的資料。在呼叫get方法之前呼叫setMaxVersions(int maxVersion),就可以讀取到所有版本的資料。

讀取一行資料的程式碼:

Configuration conf = HBaseConfiguration().create();
HTable table = new HTable(conf,"bigdata17_table");
Get get = new Get(Bytes.toBytes("bigdata17_row1"));
get.addColumn(Bytes.toBytes("colfam1"),Bytes.toBytes("qual1"));
Result result = table.get(get);
byte[] val = result.getValue(Bytes.toBytes("colfam1"),Bytes.toBytes("qual1"));
System.out.println("Value:" + Bytes.toString(val));

HBase提供讀取多行資料的方法: Result[] get(List gets)throws IOException

下面是讀取多行資料的程式碼:

byte[] colfam1 = Byte.toBytes("colfam1");
byte[] qual1 = Byte.toBytes("qual1");
byte[] qual2 = Byte.toBytes("qual2");
byte[] row1 = Byte.toBytes("bigdata17Row1");
byte[] row2 = Byte.toBytes("bigdata17Row2");

Configuration conf = HBaseConfiguration().create();
HTable table = new HTable(conf,"bigdata17_table");

List<Get> gets = new ArrayList<Get>();
Get get1 = new Get(row1);
get1.addColumn(colfam1,qual1);
gets.add(get1);

Get get2 = new Get(row2);
get2.addColumn(colfam1,qual1);
gets.add(get2);

Get get3 = new Get(row3);
get3.addColumn(colfam1,qual2);
gets.add(get3);

Result[] results = table.get(gets);

//迴圈results陣列,讀取每個返回的Result結果
for(Result result : results){
    String row = Bytes.toString(result.getRow());
    byte[] val1 = null;
    if(result.containColumn(colfam1,qual1)){
        val1 = result.getValue(colfam1,qual1);
        System.out.println("Value1:" + Bytes.toString(val1));
    }
    
    byte[] val2 = null;
    if(result.containColumn(colfam1,qual2)){
        val2 = result.getValue(colfam1,qual2);
        System.out.println("Value2:" + Bytes.toString(val2));
    }
}

//使用KeyValue方式迭代Results中的資料
for(Result result : results){
    for(KeyValue kv : result.raw()){
        System.out.println("Row:" + Bytes.toString(kv.getRow()) + " Value:" + Bytes.toString(kv.getValue()));
    }
}

Delete操作

HBase同樣也提供刪除資料的操作,由Delete類來執行。

Delete類提供了兩個建構函式: Delete(byte[] row) Delete(byte[] row,long timestamp,RowLock rowLock)

Delete類提供瞭如下的方法用於在刪除資料的過程中縮小資料的範圍,類似關係型資料庫的where條件:

Delete deleteFamily(byte[] family)刪除整個列族的所有版本資料  
Delete deleteFamily(byte[] family,long timesamp)刪除時間戳早於給定timesamp的資料,包含timesamp。  
Delete deleteColumns(byte[] family,byte[] qualifier)刪除列族中指定列的所有版本資料。  
Delete deleteColumns(byte[] family,byte[] qualifier,long timestamp)刪除和時間戳版本匹配的資料以及比指定時間戳早的版本的資料
Delete deleteColumn(byte[] family,byte[] qualifier)只刪除指定列中的最新版本的資料
Delete deleteColumn(byte[] family,byte[] qualifier,long timestamp)只刪除指定列中的和timpstamp匹配版本的資料。
void setTimestamp()設定時間戳,這個方法在呼叫其他3種方法時經常被忽略。但是如果不指定列族或列,則次呼叫與刪除整行不同,它會刪除匹配時間戳的或者比給定時間戳舊的所有列族中的所有列。

deleteColumns()和deleteColumn()的區別是,前者刪除多個版本的資料,後者只刪除指定版本的資料。

Delete同樣也提供刪除單行和多行的資料。

刪除單條資料的程式碼如下:

Delete delete = new Delete(Bytes.toBytes(bigdata1iRow1));

delete.setTimestamp(1);

delete.deleteColumn(Bytes.toBytes("colfam1"),Bytes.toBytes("qual1"),1);

delete.deleteColumns(Bytes.toBytes("colfam2"),Bytes.toBytes("qual1"));

delete.deleteColumn(Bytes.toBytes("colfam2"),Bytes.toBytes("qual3"),15);

delete.deleteFamily(Bytes.toBytes("colfam3"));

delete.deleteFamily(Bytes.toBytes("colfam3"),3);

table.delete(delete);

刪除多條資料的程式碼:

List<Delete> deletes = new ArrayList<Delete>();

Delete delete1 = new Delete(Bytes.toBytes("bigdata17Row1"));
delete1.setTimestamp(4);
deletes.add(delete1);

Delete delete2 = new Delete(Bytes.toBytes("bigdata17Row2"));
delete2.deleteColumn(Bytes.toBytes("colfam1"),Bytes.toBytes("qual1"),1);
deletes.add(delete2);

Delete delete3 = new Delete(Bytes.toBytes("bigdata17Row3"));
delete.deleteFamily(Bytes.toBytes("colfam3"));
delete.deleteFamily(Bytes.toBytes("colfam3"),3);
deletes.add(delete3);

table.delete(deletes);