以下言論爲菜鳥烏焦巴弓之拙見,可信度最多達到百分之八十,如有被該文引入歧途者請冷靜點,臭雞蛋滴不要帶。請高手幫忙點錯,萬分感謝! 首先,我們要知道一個概念: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);
|
|