BerkeleyDB同名key值(Duplicate Key)的使用

 
查看文章
   
BerkeleyDB同名key值(Duplicate Key)的使用
2008年07月16日 星期三 22:31
以下言論爲菜鳥烏焦巴弓之拙見,可信度最多達到百分之八十,如有被該文引入歧途者請冷靜點,臭雞蛋滴不要帶。請高手幫忙點錯,萬分感謝!
首先,我們要知道一個概念:duplicate keys,也就是說:在同一個庫中多條記錄共享一個key。在建庫的過程中,如果存在多條同名的記錄對應不同data時,就要用到這個東東了。例如某公司 職工數據庫裏,以員工的名字作爲記錄的key,同時有好幾個名叫Jackey的員工,這時就要用到同名key值的概念了。
注意:duplicate keys只能在二進制樹以及hash表格式的庫中。
啓用duplicates應該在建立數據庫的時候用DB->set_flags()來設置。有DB_DUP及DB_DUPSORT兩種標誌。前者不 使數據庫duplicate keys自動排列,而後者利用DB->set_dup_compare()指定排列函數後,支持自動排列功能,該排列函數的格式爲: int (*function)(DB *db, const DBT *key1, const DBT *key2); `
看一個代碼片段:
DB *dbp;
DBC *cursor;
DBT key, data;

db_create(&dbp, NULL, 0);
dbp->set_flags( DB_DUP);//或者DB_DUPSORT
dbp->open( NULL, file_name, NULL, DB_BTREE, DB_CREATE, 0);

這樣,新鍵的數據庫就有對duplicate keys的支持。

支持duplicate key的庫的寫入與一般的庫沒有什麼區別,用DB->put寫入時,記錄會被排在庫的最後;
dbp->put(dbp, NULL, &key, &value, 0);//flag不可爲DB_NOOVERWRITE
當用DBC->put()寫入時,可以用到下面幾個用於加入duplicate記錄的標誌宏:
DB_BEFORE;DB_AFTER //當前加入記錄的key與遊標當前指向的記錄的key一致。直接將該記錄作爲duplicate記錄加到當前記錄的前/後面。當庫的標誌爲DB_DUPSORT時,該標誌無用。
DB_KEYFIRST;DB_KEYLAST //如果該記錄的key值在庫中已經存在,且庫的定義爲DB_DUP(即不自動分類)時,該記錄被加到所屬key的duplicate列表的最前/後面。

需要說明的是,帶duplicate keys支持的庫,當你用普通的DB->get()來讀取記錄的時候,取得的是指定key值對應的第一個data,要取得後面一些data的時候,需要用到遊標DBC->c_get。請看下面的代碼片段:
DB *dbp;
DBC *cursor;
DBT key, data;

db_create(&dbp,NULL, 0);
dbp->open(NULL, file_one, NULL, DB_HASH, DB_CREATE, 0);
dbp->cursor(NULL, &cursor, 0);
/***對key與value進行初始化空間***/
cursor->c_get(cursor, &key, &value, DB_SET); //遊標指到第一個符合key值的記錄。
cursor->c_get(cursorp, &key, &data, DB_NEXT_DUP); //查找下一個該key對應的記錄。
這裏有幾個c_get常用的flag:
DB_SET; //遊標指向第一個符合key的記錄。
DB_SET_RANGE; //支持模糊查找,遊標指向第一個大於等於key值的value
DB_NEXT; DB_PREV; //下/上一條記錄(將duplicate記錄也作爲記錄看待)
DB_GET_BOTH;//前者遊標指向key、value值都匹配的記錄;
DB_GET_BOTH_RANGE; //後者支持模糊查找,遊標指向與key、value值最接近的第一條記錄。
DB_NEXT_NODUP; DB_PREV_NODUP; //下/上一條記錄(將duplicate排除在外)
DB_NEXT_DUP;//下一條duplicate記錄。

刪除duplicate key記錄:
當你用普通的DB->del()來刪除某條記錄的時候,如果該庫是帶duplicate key支持的,並且你在函數中指定的key值又恰好對應着多個data(即duplicate組),那麼你這個操作將把這個duplicate組中所有記錄全部刪除.
如果這種結果不是你真正想要的,那爲了避免這種情況,你必須使用遊標的方法才能指向該key值對應的duplicate組中的其它記錄,然後進行刪除.e.g:
DBC *cursor;
DB *dbp;
DBT *key, *value;

/*****打開/設置庫語句省略號*******/
dbp->set_flags(dbp, DB_DUP);
key.data = “xxx”;
key.size = strlen(“xxx”);
value.data = “yyy”;
value.size = strlen(“yyy”);

cursor->c_get(cursor, &key, &value, DB_GET_BOTH);
cursor->c_del(cursor, 0);
發佈了12 篇原創文章 · 獲贊 4 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章