Berkeley DB使用SecondKey给数据排序的实现方法是本文我们主要要介绍的内容,在做项目的时候用到了nosql数据库BDB,借此机会研究了一下它的用法。它的官方示例和文档比较丰富,感觉比较容易学习。在开发过程中出现了一个需求,要把数据根据插入时间遍历,个人认为通过第二主键(SecondKey)比较容易实现。
以下是我的基本实现过程:
1.在ValueBean中加入insertTime属性
public class ValueBean{
private String insertTime;
private String hostName;
private byte[] value;
public String getHostName() {
return hostName;
}
public void setHostName(String hostName) {
this.hostName = hostName;
}
public String getInsertTime() {
return insertTime;
}
public void setInsertTime(String insertTime) {
this.insertTime = insertTime;
}
public byte[] getValue() {
return value;
}
public void setValue(byte[] value) {
this.value = value;
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
其中的hostName属性在主从同步和生成插入时间时用到,value属性就是key-value中的值
2.TupleBinding类
public class ValueBeanBinding extends TupleBinding<ValueBean> {
@Override
public ValueBean entryToObject(TupleInput input) {
String time = input.readString();
String name = input.readString();
byte[] value = new byte[input.getBufferLength()-input.getBufferOffset()];//获得value长度
input.read(value);
ValueBean data = new ValueBean();
data.setInsertTime(time);
data.setHostName(name);
data.setValue(value);
return data;
}
@Override
public void objectToEntry(ValueBean object, TupleOutput output) {
ValueBean value = object;
output.writeString(value.getInsertTime());
output.writeString(value.getHostName());
output.write(value.getValue());
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
此类用于将ValueBean和DatabaseEntry进行转换,两个方法中的属性读写顺序要统一。
3.SecondaryKeyCreator,第二主键生成器
public class SecondKeyCreator implements SecondaryKeyCreator{
private TupleBinding<ValueBean> theBinding;
SecondKeyCreator(TupleBinding<ValueBean> theBinding) {
this.theBinding = theBinding;
}
@Override
public boolean createSecondaryKey(SecondaryDatabase secondary,
DatabaseEntry key, DatabaseEntry data, DatabaseEntry result) {
ValueBean v =
(ValueBean) theBinding.entryToObject(data);
String time=v.getInsertTime();
result.setData(time.getBytes());
return true;
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
指定insertTime属性作为第二主键。
在插入一个新数据时生成insertTime十分关键,尤其在高并发和互为主从同步时极易出现“第二主键重复”的错误,造成数据无法插入,我了使用当前时间毫秒数+AtomicInteger自增+hostName的asc码之和,保证insertTime的前后大小顺序。
System.currentTimeMillis()*1000000+(add_num.getAndIncrement()%1000)*1000 + host_key
4.创建第二数据库,用于存储secondkey
SecondaryConfig mySecConfig = new SecondaryConfig();
mySecConfig.setAllowCreate(true);
mySecConfig.setSortedDuplicates(false);
TupleBinding<ValueBean> tb =new ValueBeanBinding();
SecondKeyCreator keyCreator = new SecondKeyCreator(tb);
mySecConfig.setKeyCreator(keyCreator);
mySecConfig.setTransactional(envConfig.getTransactional());
String secDbName = "mySecondaryDatabase";
mySecDb = myEnv.openSecondaryDatabase(null, secDbName, storeDb, mySecConfig);
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
到此,便可以使用SecondaryCursor的getNext()和getPrev()前后遍历了,getSearchKey()可以找到你想要的位置。
关于Berkeley DB使用SecondKey给数据排序的实现方法的相关知识就介绍到这里了,希望本次的介绍能够对您有所收获!
【编辑推荐】