日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Berkeley DB——Records

發布時間:2025/3/21 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Berkeley DB——Records 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Berkeley DB——Records

?

本文主要講述如何操作Berkeley DB的記錄——RecordsCreateRetrieve、UpdateDelete

Key/Data Pair and Dbt object

Berkeley DB中保存的是key/data對,它們都是Dbt對象:

#include <db_cxx.h>

?

class Dbt {

public:

?????? Dbt(void *data, size_t size);

?????? Dbt();

?????? Dbt(const Dbt &);

?????? Dbt &operator = (const Dbt &);

?????? ~Dbt();

?

?????? void *get_data() const;

?????? void set_data(void *);

?

?????? u_int32_t get_size() const;

?????? void set_size(u_int32_t);

?

?????? u_int32_t get_ulen() const;

?????? void set_ulen(u_int32_t);

?

?????? u_int32_t get_dlen() const;

?????? void set_dlen(u_int32_t);

?

?????? u_int32_t get_doff() const;

?????? void set_doff(u_int32_t);

?

?????? u_int32_t get_flags() const;

?????? void set_flags(u_int32_t);

?

?????? DBT *Dbt::get_DBT();

?????? const DBT *Dbt::get_const_DBT() const;

?????? static Dbt *Dbt::get_Dbt(DBT *dbt);

?????? static const Dbt *Dbt::get_const_Dbt(const DBT *dbt);

};

?

它是DBT對象的c++封裝,而DBT是一個結構體。如果我們設置DB的訪問方法為B樹或者Hash的話,Key可以為任何值。而如果我們定義一個有n-1(相對于有n個字段的關系數據庫表)個字段的struct,將類型為這個struct的對象存入數據庫的話,就相當于我們存入了n個字段的值了,只是我們不能以data中的字段作為查詢條件,而只能以key為查詢條件。

Writing Records to the DB

通常情況下,我們需要設置Dbt對象的datalen,以指明需要保存的數據和數據所占用空間的大小——不是指針的大小而是實際數據所占空間的大小。當寫數據到DB中的時候,我們需要設置key/data對的sizedata。存入的數據最好是那些c/c++的基本數據類型——比如我們想存入字符串,那應該使用char*或者wchar_t*類型,而不是string或者wstring。根據我的實踐,如果存入stringwstring會發生一些奇怪的問題,具體看這里。

如果數據庫不允許重復記錄的話(默認情況,如果想存入重復記錄需要對Db設置相應的flag),put方法就相當于關系數據庫中的insert or update

int Db::put(DbTxn *txnid, Dbt *key, Dbt *data, u_int32_t flags);

我們可以給put方法傳入不同的flag來控制put的具體行為,這些flag有:

FlagDb.put

Description

0

添加數據到數據庫中。如果DB不允許重復記錄,當已經有相同的key的記錄時,將修改原記錄,否則存入新記錄;如果DB允許重復,則添加新記錄。

DB_APPEND

只針對QueueRecnoDB,將記錄添加到數據庫的末尾

DB_NODUPDATA

只針對B樹和HashDB,且數據庫需要設置為允許重復記錄,如果不存在相同key的記錄,則存入新記錄,否則返回DB_KEYEXIST

DB_NOOVERWRITE

當不存在key相同的記錄時,存入新的記錄,而不管DB是否允許有重復記錄;否則返回DB_KEYEXIST

?

代碼示例:

#include <db_cxx.h>

#include <string.h>

?

...

?

char *description = "Grocery bill.";

float money = 122.45;

?

Db my_database(NULL, 0);

// Database open omitted for clarity

?

Dbt key(&money, sizeof(float));

Dbt data(description, strlen(description) + 1);

?

int ret = my_database.put(NULL, &key, &data, DB_NOOVERWRITE);

if (ret == DB_KEYEXIST) {

??? my_database.err(ret, "Put failed because key %f already exists", money);

}

?

Getting Records from the DB

可以使用get方法從DB中根據key來獲取數據:

int Db::get(DbTxn *txnid, Dbt *key, Dbt *data, u_int32_t flags);

必須先設定key的值和size,把data當作out參數傳入,如果搜索到記錄,則數據會寫入data參數中,并且get方法返回0,否則返回非零值,這些返回值的含義如下:

Result

Description

0

成功

-30989

沒有找到此key的記錄

?

get方法也有一個flag參數,常用的flag有:

Flag

Description

0

取出key匹配的一條記錄,填充data參數

DB_GET_BOTH

keydata都匹配時,填充data參數

DB_SET_RECNO

根據行號來搜索記錄,keydata參數都將被填充(僅針對B+樹的DB)。

DB_MULTIPLE

key匹配時,返回一批數據到data參數所指的buffer中(針對設置了允許重復記錄的DB

?

一個例子:

#include <db_cxx.h>

#include <string.h>

...

?

float money;

char *description;

?

Db my_database(NULL, 0);

// Database open omitted for clarity

?

money = 122.45;

?

Dbt key, data;

// Use our own memory to retrieve the float.

// For data alignment purposes.

key.set_data(&money);

key.set_ulen(sizeof(float));

key.set_flags(DB_DBT_USERMEM);

?

my_database.get(NULL, &key, &data, 0);

?

// Money is set into the memory that we supplied.

description = (char *)data.get_data();

?

Deleting Records

刪除記錄使用del方法:

int Db::del(DbTxn *txnid, Dbt *key, u_int32_t flags);

如果DB設置為允許重復記錄的話,那key匹配的所有記錄都被刪除。想一條條記錄刪除的話,需要使用游標。

一個例子:

#include <db_cxx.h>

?

...

?

Db my_database(NULL, 0);

// Database open omitted for clarity

?

float money = 122.45;

Dbt key(&money, sizeof(float));

?

my_database.del(NULL, &key, 0);

?

del方法并不是真正的物理刪除,db文件的大小也不會變小——這有點象Access

An Example

#include "stdafx.h"

#include <iostream>

#include <db_cxx.h>

#include <string.h>

?

?

?

using namespace std;

int _tmain(int argc, _TCHAR* argv[])

{

?????? Db db(NULL,0);

??????

?????? u_int32_t oFlags = DB_CREATE; // Open flags;

?????? try

?????? {

????????????? db.open(NULL,??????????????? // Transaction pointer

???????????????????? "my_db.db",????????? // Database file name

??????????? NULL,??????????????? // Optional logical database name

??????????? DB_BTREE,?????? ?????// Database access method

??????????? oFlags,????????????? // Open flags

??????????? 0);????????????????? // File mode (using defaults)

????????????? db.truncate(NULL,0,0);

????????????? float money = 122.45;

????????????? char *description = "Grocery bill.";

?

????????????? Dbt key(&money, sizeof(float));

????????????? Dbt data(description, strlen(description)+1);

????????????? int ret = db.put(NULL, &key, &data, DB_NOOVERWRITE);

????????????? cout<<"put data--"<<description<<endl;

?

????????????? ret = db.get(NULL, &key, &data, DB_GET_BOTH);

????????????? cout<<"get key--"<<*((float*)key.get_data())<<endl;

????????????? cout<<"get data--"<<(char *)data.get_data()<<endl;

?

????????????? money = 111;

????????????? description = "James--------------------";

?

???????????? data.set_data(description);

????????????? data.set_size(strlen(description)+1);

????????????? db.put(NULL,&key,&data,DB_NOOVERWRITE);

????????????? ret = db.get(NULL, &key, &data, DB_GET_BOTH);

????????????? cout<<"get key--"<<*((float*)key.get_data())<<endl;

????????????? cout<<"get data--"<<(char *)data.get_data()<<endl;

?

????????????? money = 191;

????????????? description = "Mike";

?

????????????? data.set_data(description);

????????????? data.set_size(strlen(description)+1);

????????????? db.put(NULL,&key,&data,DB_NOOVERWRITE);

????????????? ret = db.get(NULL, &key, &data, DB_GET_BOTH);

????????????? cout<<"get key--"<<*((float*)key.get_data())<<endl;

????????????? cout<<"get data--"<<(char *)data.get_data()<<endl;

?

?

?????? }

?????? catch(DbException &e)

?????? {

????????????? cerr<<"DBException:"<<e.what();

?????? }

?????? catch(std::exception &e)

?????? {

????????????? cerr<<"DBException:"<<e.what();

?????? }

?????? system("pause");

?????? return 0;

}

?
所有Berkeley DB相關的隨筆

總結

以上是生活随笔為你收集整理的Berkeley DB——Records的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。