Berkeley DB使用SecondKey給數(shù)據(jù)排序的實現(xiàn)方法
Berkeley DB使用SecondKey給數(shù)據(jù)排序的實現(xiàn)方法是本文我們主要要介紹的內(nèi)容,在做項目的時候用到了nosql數(shù)據(jù)庫BDB,借此機會研究了一下它的用法。它的官方示例和文檔比較豐富,感覺比較容易學(xué)習(xí)。在開發(fā)過程中出現(xiàn)了一個需求,要把數(shù)據(jù)根據(jù)插入時間遍歷,個人認為通過第二主鍵(SecondKey)比較容易實現(xiàn)。
以下是我的基本實現(xiàn)過程:
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;
- }
- }
其中的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());
- }
- }
此類用于將ValueBean和DatabaseEntry進行轉(zhuǎn)換,兩個方法中的屬性讀寫順序要統(tǒng)一。
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;
- }
- }
指定insertTime屬性作為第二主鍵。
在插入一個新數(shù)據(jù)時生成insertTime十分關(guān)鍵,尤其在高并發(fā)和互為主從同步時極易出現(xiàn)“第二主鍵重復(fù)”的錯誤,造成數(shù)據(jù)無法插入,我了使用當(dāng)前時間毫秒數(shù)+AtomicInteger自增+hostName的asc碼之和,保證insertTime的前后大小順序。
System.currentTimeMillis()*1000000+(add_num.getAndIncrement()%1000)*1000 + host_key
4.創(chuàng)建第二數(shù)據(jù)庫,用于存儲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);
到此,便可以使用SecondaryCursor的getNext()和getPrev()前后遍歷了,getSearchKey()可以找到你想要的位置。
關(guān)于Berkeley DB使用SecondKey給數(shù)據(jù)排序的實現(xiàn)方法的相關(guān)知識就介紹到這里了,希望本次的介紹能夠?qū)δ兴斋@!
【編輯推薦】