HTable提供了删除的方法,同时与之前的方法有一个对应的类名为Delete。
单行删除
delete()方法有许多变体,其中一个只需要一个Delete实例:
void delete(Delete delete) throws IOException
|
用户必须先创建一个Delete实例,然后再添加你想要删除数据的详细信息。构造函数是:
Delete(byte [] row) Delete(byte [] row,long timestamp,RowLock rowLock)
|
用户需要提供要修改的行,如果多次频繁地修改同一行的话,还可以提供rowLock参数(RowLock类的一个实例),以指定自己的RowLock。此外,最好缩小要删除的给定行中涉及数据的范围,可以使用下列方法:
Delete deleteFamily(byte[] family) Delete deleteFamily(byte[] family,long timestamp) 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) void setTimestamp(long timestamp)
|
有4种调用可缩小删除所涉及的数据范围。首先,用户可以使用deleteFamily()方法来删除一整个列族,包括其下所有的列。用户也可以指定一个时间戳,触发针对单元格数据版本的过滤,从所有的列中删除与这个时间戳相匹配的版本和比这个时间戳旧的版本。
另一种方法是deleteColumns(),它作用于特定的一列,如果用户没有指定时间戳,这个方法会删除该列的所有版本。如果用户指定了时间戳,这个方法会删除所有与这个时间戳相匹配的版本和更旧的版本。
最后一个方法是setTimestamp(),这个方法在调用其他3种方法时经常被忽略。但是,如果不指定列族或列,则此调用与删除整行不同,它会删除匹配时间戳的或者比给定时间戳旧的所有列族中的所有列。功能如下表
方法 |
无时间戳的删除 |
有时间戳的删除 |
none |
删除整行,即所有列的所有版本 |
从所有列族的所有列中删除与给定时间戳相同或者更旧的版本 |
delteColum() |
只删除给定列的最新版本,保留到旧版本 |
只删除与时间戳匹配的给定列的指定版本,如果不存在,则不删除 |
deleteColumns() |
删除给定列的所有版本 |
从给定列中删除与给定时间戳相等或者更旧的版本 |
deleteFamily() |
删除给定列族的所有列 |
从给定列族下的所有列中删除与给定时间戳相等或者更旧的版本 |
Delet类其他方法
方法 |
描述 |
getRow() |
返回创建Delte实例时指定的行键 |
getRowLock() |
返回当前Delete实例的RowLock实例 |
getLockId() |
返回创建时指定rowLock的锁ID,如果没有指定返回-1L |
getTimeStamp() |
检索Delete实例相关的时间戳 |
isEmpty() |
检查FamilyMap是否含有任何条目,即用户所指定的想要删除的列族或者列 |
getFmailyMap() |
这个方法可以获取用户通过deleteFamily()以及deleteColumn()/deleteColumns()添加的要删除的列和列族,返回的FamilyMap是使用列族名作为键,它的值是当前列族下要删除的列限定符的列表 |
从HBase中删除数据的应用示例
Delete delete = new Delete(Bytes.toBytes("row1")); delete.setTimestamp(1); delete.deleteColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1"), 1); delete.deleteColumns(Bytes.toBytes("colfam2"), Bytes.toBytes("qual1")); delete.deleteColumns(Bytes.toBytes("colfam2"), Bytes.toBytes("qual3"), 15); delete.deleteFamily(Bytes.toBytes("colfam3")); delete.deleteFamily(Bytes.toBytes("colfam3"), 3); table.delete(delete); table.close();
|
Delete的列表
基于列表的delete()调用与基于列表的put()调用非常相似,需要创建一个包含Delete()实例的列表,对其进行配置,并调用下面的方法:
void delete(List<Delete> deletes) throws IOException
|
当运行这个例子时,你会看到打印输出的删除前后的状态,还能看到使用KeyValue.toString()打印输出的原始的KeyValue实例。
正如其他的基于列表的操作,用户不能对删除操作在远程服务器上的执行顺序作任何假设。API会重新排列它们,并将同一个region服务器的操作集中到一个RPC请求中以提升性能。如果需要确保执行的顺序,用户需要把这些调用分成更小的组,并控制组之间的执行顺序。在最坏情况下,需要发送单独的Delete调用以保证顺序。
示例代码如下:
List<Delete> deletes = new ArrayList<Delete>(); Delete delete1 = new Delete(Bytes.toBytes("row1")); delete1.setTimestamp(4); deletes.add(delete1); Delete delete2 = new Delete(Bytes.toBytes("row2")); delete2.deleteColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1")); delete2.deleteColumns(Bytes.toBytes("colfam2"), Bytes.toBytes("qual3"), 5); deletes.add(delete2); Delete delete3 = new Delete(Bytes.toBytes("row3")); delete3.deleteFamily(Bytes.toBytes("colfam1")); delete3.deleteFamily(Bytes.toBytes("colfam2"), 3); table.delete(delete3); table.delete(deletes);
|
从HBase中删除错误数据
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "testtable"); List<Delete> deletes = new ArrayList<Delete>(); Delete delete4 = new Delete(Bytes.toBytes("row2")); delete4.deleteColumn(Bytes.toBytes("BOGUS"), Bytes.toBytes("qual1")); deletes.add(delete4); try { table.delete(deletes);
} catch (Exception e) { e.printStackTrace(); } table.close(); System.out.println("Deletes length:" + deletes.size()); for(Delete delete: deletes) { System.out.println(delete); }
|
原子性操作compare-and-delete
提供了用户可以在服务器端读取并修改的功能
boolean checkAndDelete(byte[] row,byte[] family,byte[] qualifier,byte[] value,Delete delete) throws IOException
|
用户必须制定行键、列族、列限定符和值来执行操作之前的检查。如果检查失败,则不执行删除操作,调用返回false。如果检查成功,则执行删除操作,调用返回true。
代码如下
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "testtable"); List<Delete> deletes = new ArrayList<Delete>(); Delete delete1 = new Delete(Bytes.toBytes("row1")); delete1.deleteColumns(Bytes.toBytes("colfam1"), Bytes.toBytes("qual3")); boolean res1 = table .checkAndDelete(Bytes.toBytes("row1"), Bytes.toBytes("colfam2"), Bytes.toBytes("qual3"), null, delete1); System.out.println("Delete successful:" + res1); Delete delete2 = new Delete(Bytes.toBytes("row1")); delete2.deleteColumns(Bytes.toBytes("colfam2"), Bytes.toBytes("qual3")); table.delete(delete2); boolean res2 = table .checkAndDelete(Bytes.toBytes("row1"), Bytes.toBytes("colfam2"), Bytes.toBytes("qual3"), null, delete1); System.out.println("Delete successful:" + res2); Delete delete3 = new Delete(Bytes.toBytes("row2")); delete3.deleteFamily(Bytes.toBytes("colfam1")); try { boolean res4 = table .checkAndDelete(Bytes.toBytes("row1"), Bytes.toBytes("colfam1"), Bytes.toBytes("qual1"), Bytes.toBytes("val1"), delete3);
} catch (Exception e) { e.printStackTrace(); }
|