Berkeley DB——Records

本文主要讲述如何操作Berkeley DB的记录——Records的Create、Retrieve、Update和Delete。

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对象的data和len,以指明需要保存的数据和数据所占用空间的大小——不是指针的大小而是实际数据所占空间的大小。当写数据到DB中的时候,我们需要设置key/data对的size和data。存入的数据最好是那些c/c++的基本数据类型——比如我们想存入字符串,那应该使用char*或者wchar_t*类型,而不是string或者wstring。根据我的实践,如果存入string和wstring会发生一些奇怪的问题,具体看这里。

如果数据库不允许重复记录的话(默认情况,如果想存入重复记录需要对Db设置相应的flag),put方法就相当于关系数据库中的insert or update:

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

我们可以给put方法传入不同的flag来控制put的具体行为,这些flag有:

Flag(Db.put

Description

0

添加数据到数据库中。如果DB不允许重复记录,当已经有相同的key的记录时,将修改原记录,否则存入新记录;如果DB允许重复,则添加新记录。

DB_APPEND

只针对Queue和Recno的DB,将记录添加到数据库的末尾

DB_NODUPDATA

只针对B树和Hash的DB,且数据库需要设置为允许重复记录,如果不存在相同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

当key和data都匹配时,填充data参数

DB_SET_RECNO

根据行号来搜索记录,key和data参数都将被填充(仅针对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相关推荐

  1. BDB (Berkeley DB)数据库简单介绍(转载)

    近期要使用DBD,于是搜了下相关的资料,先贴个科普性的吧: 转自http://www.javaeye.com/topic/202990 DB综述 DB最初开发的目的是以新的HASH訪问算法来取代旧的h ...

  2. BDB (Berkeley DB)简要数据库(转载)

    使用最近DBD.然后搜了下相关资料,首先公布的是一门科学: 转会http://www.javaeye.com/topic/202990 DB综述 DB最初开发的目的是以新的HASH訪问算法来取代旧的h ...

  3. BDB (Berkeley DB)数据库简介(转载)

    最近要使用DBD,于是搜了下相关的资料,先贴个科普性的吧: 转自http://www.javaeye.com/topic/202990 DB综述 DB最初开发的目的是以新的HASH访问算法来代替旧的h ...

  4. Berkeley db 数据库

    开发Berkeley DB原因: DB最初开发的目的是以新的HASH访问算法来代替旧的hsearch函数和大量的dbm实现(如AT&T的dbm,Berkeley的ndbm,GNU项目的gdbm ...

  5. Berkeley DB

    我们公司的产品中用到了伯克利db数据库,闲着没事干,学习了一下: 1:Berkeley DB是一个开源的文件数据库,嵌入式数据库系统.介于关系数据库与内存数据库之间,使用方式与内存数据库类似,它提供的 ...

  6. Berkeley DB 使用

    http://www.ibm.com/developerworks/cn/linux/l-embdb/index.html UNIX/LINUX平台下的数据库种类非常多,参考资料1中 列举了其中的大部 ...

  7. Berkeley DB介绍

    简介:         Berkeley DB是历史悠久的嵌入式数据库系统,主要应用在UNIX/LINUX操作系统上,其设计思想是简单.小巧.可靠.高性能.Berkeley DB (DB)是一个高性能 ...

  8. Berkeley DB (DB)介绍

    Berkeley DB (DB)是一个高性能的,嵌入数 据库编程库,和C语言,C++,Java,Perl,Python,PHP,Tcl以及其他很多语言都有绑定.Berkeley DB可以保存任意类型的 ...

  9. Berkeley DB 源代码分析 (6) 缓存模块

    这篇文字原来是贴在wiki里面的,所以有一些wiki系统使用的格式标记,大家将就看吧,不好意思哈. = Memory Pool subsystem = == Architecture == mpool ...

最新文章

  1. php t string,PHP中出现意外的T_STRING错误
  2. 查看mysql数据库大小、表大小和最后修改时间
  3. Gamma校正及其OpenCV实现
  4. jQuary的相关动画效果
  5. Taglist:Exuberant ctags.......
  6. 融资13亿后突然死亡!首款产品被苹果点赞,与谷歌竞赛的明星创业公司Anki倒闭...
  7. JSP→基本语法/静态内容/指令/动作/表达式/小脚本(Scriptlet)/声明/注释、JSP页面声明周期、代码样例、九大隐式内置对象及方法代码样例
  8. deepin linux 怎么安装软件,Linux Deepin 从 Backports 安装软件包
  9. 递归解决换零钱问题--代码实现
  10. 产品经理入门知识梳理(含思维导图
  11. Mstar 方案白板书写加速
  12. 2023年全国最新工会考试精选真题及答案33
  13. 事务压缩 对表的影响 compress for oltp
  14. hssfrow 单元格样式_POI设置Excel单元格样式
  15. Android-0. Android studio在导航栏增加自己的功能图标(如小扳手)
  16. 【C++】关于char * tempbuffer = new char[100];
  17. Android-vold源码分析之连接电脑OTG(11)
  18. kvm 1.创建虚拟机
  19. 2020机械员-岗位技能(机械员)考试及机械员-岗位技能(机械员)考试题
  20. 【集成学习(下)】Task15 集成学习-案例 蒸汽量预测

热门文章

  1. java垃圾回收根对象_Java垃圾回收怎么理解?
  2. destoon php,DESTOON_7.0_UTF8
  3. mysql创建外键的表_Mysql表创建外键报错解决方案
  4. function 多个函数用一个_一列转多行多列,用INDIRECT函数,给你一个可套用的公式模板...
  5. 用CMake编译运行在网上下载的源文件src
  6. Caffe代码导读(2):LMDB简介
  7. 利用Hog特征和SVM分类器进行行人检测
  8. matlab和vs2008联合编程
  9. 对象在JVM中的表示: OOP-Klass模型
  10. 远程调用服务(RPC)和消息(Message Queue)对比及其适用/不适用场合