Berkeley DB——Records
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相关推荐
- BDB (Berkeley DB)数据库简单介绍(转载)
近期要使用DBD,于是搜了下相关的资料,先贴个科普性的吧: 转自http://www.javaeye.com/topic/202990 DB综述 DB最初开发的目的是以新的HASH訪问算法来取代旧的h ...
- BDB (Berkeley DB)简要数据库(转载)
使用最近DBD.然后搜了下相关资料,首先公布的是一门科学: 转会http://www.javaeye.com/topic/202990 DB综述 DB最初开发的目的是以新的HASH訪问算法来取代旧的h ...
- BDB (Berkeley DB)数据库简介(转载)
最近要使用DBD,于是搜了下相关的资料,先贴个科普性的吧: 转自http://www.javaeye.com/topic/202990 DB综述 DB最初开发的目的是以新的HASH访问算法来代替旧的h ...
- Berkeley db 数据库
开发Berkeley DB原因: DB最初开发的目的是以新的HASH访问算法来代替旧的hsearch函数和大量的dbm实现(如AT&T的dbm,Berkeley的ndbm,GNU项目的gdbm ...
- Berkeley DB
我们公司的产品中用到了伯克利db数据库,闲着没事干,学习了一下: 1:Berkeley DB是一个开源的文件数据库,嵌入式数据库系统.介于关系数据库与内存数据库之间,使用方式与内存数据库类似,它提供的 ...
- Berkeley DB 使用
http://www.ibm.com/developerworks/cn/linux/l-embdb/index.html UNIX/LINUX平台下的数据库种类非常多,参考资料1中 列举了其中的大部 ...
- Berkeley DB介绍
简介: Berkeley DB是历史悠久的嵌入式数据库系统,主要应用在UNIX/LINUX操作系统上,其设计思想是简单.小巧.可靠.高性能.Berkeley DB (DB)是一个高性能 ...
- Berkeley DB (DB)介绍
Berkeley DB (DB)是一个高性能的,嵌入数 据库编程库,和C语言,C++,Java,Perl,Python,PHP,Tcl以及其他很多语言都有绑定.Berkeley DB可以保存任意类型的 ...
- Berkeley DB 源代码分析 (6) 缓存模块
这篇文字原来是贴在wiki里面的,所以有一些wiki系统使用的格式标记,大家将就看吧,不好意思哈. = Memory Pool subsystem = == Architecture == mpool ...
最新文章
- php t string,PHP中出现意外的T_STRING错误
- 查看mysql数据库大小、表大小和最后修改时间
- Gamma校正及其OpenCV实现
- jQuary的相关动画效果
- Taglist:Exuberant ctags.......
- 融资13亿后突然死亡!首款产品被苹果点赞,与谷歌竞赛的明星创业公司Anki倒闭...
- JSP→基本语法/静态内容/指令/动作/表达式/小脚本(Scriptlet)/声明/注释、JSP页面声明周期、代码样例、九大隐式内置对象及方法代码样例
- deepin linux 怎么安装软件,Linux Deepin 从 Backports 安装软件包
- 递归解决换零钱问题--代码实现
- 产品经理入门知识梳理(含思维导图
- Mstar 方案白板书写加速
- 2023年全国最新工会考试精选真题及答案33
- 事务压缩 对表的影响 compress for oltp
- hssfrow 单元格样式_POI设置Excel单元格样式
- Android-0. Android studio在导航栏增加自己的功能图标(如小扳手)
- 【C++】关于char * tempbuffer = new char[100];
- Android-vold源码分析之连接电脑OTG(11)
- kvm 1.创建虚拟机
- 2020机械员-岗位技能(机械员)考试及机械员-岗位技能(机械员)考试题
- 【集成学习(下)】Task15 集成学习-案例 蒸汽量预测
热门文章
- java垃圾回收根对象_Java垃圾回收怎么理解?
- destoon php,DESTOON_7.0_UTF8
- mysql创建外键的表_Mysql表创建外键报错解决方案
- function 多个函数用一个_一列转多行多列,用INDIRECT函数,给你一个可套用的公式模板...
- 用CMake编译运行在网上下载的源文件src
- Caffe代码导读(2):LMDB简介
- 利用Hog特征和SVM分类器进行行人检测
- matlab和vs2008联合编程
- 对象在JVM中的表示: OOP-Klass模型
- 远程调用服务(RPC)和消息(Message Queue)对比及其适用/不适用场合