答案 0 :(得分:7)
首先,在范围删除方面,HBase,AFAIK还没有范围删除。但是有一种方法可以在HTableInterface API中一次删除多行。为此,只需从扫描中形成一个带有行键的Delete对象,并将它们放入List并使用API,完成!为了使扫描速度更快,请不要在扫描结果中包含任何列族,因为您只需要用于删除整行的行键。
其次,关于设计。首先我对要求的理解是,有内容具有内容id,每个内容都有针对它们生成的图表并存储这些数据;每个内容可以通过日期有多个图表,取决于排名。此外,我们希望最后生成的内容的图表显示在表格的顶部。
对于我对该要求的假设,我建议使用三个表 - auto_id,content_charts和generated_order。 content_charts的行键是其内容id,generated_order的行键是long,使用HTableInterface API 自动递减。对于递减使用'-1'作为偏移量并在应用程序首次启动时或在手动初始化auto_id表中的值Long.MAX_VALUE。因此,现在如果要删除图表数据,只需使用delete清除列族,然后放回新数据,然后将put放入generated_order表中。这样,最新的插入也将位于最新插入表的顶部,该表将内容id保存为单元格值。如果要确保generated_order每个内容只有一个条目,请首先保存generated_order id并获取值并在放入时将其保存到content_charts中,在删除列族之前,首先从generated_order中删除该行。这样,您可以使用2获取最大值并且不需要扫描图表来查找内容和图表。
我希望这有用。
答案 1 :(得分:2)
您可以使用BulkDeleteProtocol,它使用定义相关范围的扫描(开始行,结束行,过滤器)。
请参阅here
答案 2 :(得分:2)
我遇到了你的情况,这是我实现你想要的代码
Scan scan = new Scan();
scan.addFamily("Family");
scan.setStartRow(structuredKeyMaker.key(starDate));
scan.setStopRow(structuredKeyMaker.key(endDate + 1));
try {
ResultScanner scanner = table.getScanner(scan);
Iterator<Entity> cdrIterator = new EntityIteratorWrapper(scanner.iterator(), EntityMapper.create(); // this is a simple iterator that maps rows to exact entity of mine, not so important !
List<Delete> deletes = new ArrayList<Delete>();
int bufferSize = 10000000; // this is needed so I don't run out of memory as I have a huge amount of data ! so this is a simple in memory buffer
int counter = 0;
while (entityIterator.hasNext()) {
if (counter < bufferSize) {
// key maker is used to extract key as byte[] from my entity
deletes.add(new Delete(KeyMaker.key(entityIterator.next())));
counter++;
} else {
table.delete(deletes);
deletes.clear();
counter = 0;
}
}
if (deletes.size() > 0) {
table.delete(deletes);
deletes.clear();
}
} catch (IOException e) {
e.printStackTrace();
}