Linux系统下C中使用BerkerlyDB笔记(一)
Berkerly DB 是一种嵌入式数据库。
1.数据类型
数据库句柄结构 DB,相当于表,存储key/value对。
数据库记录结构 DBT,表示关键字、数据,即key/value。其中两个重要字段:数据值void *data,数据大小u_int32_t size
数据库游标结构 DBC,可作为遍历器,DB支持多重记录。(我使用的都是B+树结构的数据库)
2.数据库创建
创建数据库句柄
DB *dbp;
ret = db_create(&dbp,NULL,0);
print_error(ret);
创建数据库标志
flags = DB_CREATE;
创建数据库mywork,使用B+树访问算法
ret = dbp->open(dbp,NULL,"mywork.db",NULL,DB_BTREE,flags,0);
print_error(ret);
获取数据库打开标记 (标记为DB_DUP时支持重复数据)
ret = dbp->get_open_flags(dbp,&open_flags);
3.数据库简单数据操作
DBT(数据结构)使用前应初始化
DBT key,value;
memset(key,0,sizeof(&key));
memset(value,0,sizeof(&value));
key可存放多种数据,int/float等基本类型,以及结构体。当data为浮点数时,为保存某些系统中内存对齐,可设置:
key.flags = DB_DBT_USERMEM;
数据库数据存放
ret = dbp->put(dbp,NULL,&key,&value,DB_NOOVERWRITE); -- NO_OVERWRITE 指定不可插入重复记录,若重复,则返回DB_KEYEXIST
ret = dbp->get(dbp,NULL,&key,&value,0); -- 读取key相应数据value
数据库更新
数据库关闭后自动更新数据至硬盘。
程序运行中,同步数据至硬盘 ret = dbp->sync(dbp,0);
4.游标
1)游标简单使用
定义游标变量
DBC *cur;
打开数据库后再打开游标
ret = dbp->cursor(dbp,NULL,&cur,0);
关闭数据库再关闭游标
if( cur != NULL ) ret = cur->c_close(cur);
ret = dbp->close(dbp,0);
2)游标遍历数据库
循环遍历整个数据库
while((ret = cur->c_get(cur,&key,&value,DB_NEXT))==0){}
当数据库支持重复数据时(一个key对应多个value),定位遍历某个key的所有value
data = “hello”;
key.data =data;
key.size = strlen(data)+1;
ret = cur->c_get(cur,&key,&value,DB_SET);
while(ret == 0){
```
memset(value,0,sizeof(&value)); // 避免value为上一个value值
ret = cur->c_get(cur,&key,&value,DB_NEXT_DUP);
}
3)使用游标访问数据
使用标志位定位数据
DB_SET_RANGE:移动游标至第一条大于等于key的位置
DB_GET_BOTH:移动游标至第一条匹配key和value的记录位置
DB_GET_BOTH_RANGE:先匹配key,再匹配value
4)使用游标插入记录
DB_NODUPDATA :key存在返回DB_KEYEXIST错误
DB_KEYFIRST :key存在,记录插在最前面
DB_KEYLAST :key存在,记录插在最后面
如:ret = cur->c_put(cur,&key,&value,DB_KEYFIRST);
使用游标插入记录不能获取事务性保护,可使用DB句柄插入。
5)使用游标处理重复记录
DB_GET_BOTH_RANGE :定位游标至特定记录,无论重复
DB_NEXT_DUP :获得当前key相同的记录,否则返回DB_NOTFOUNT。参考2)
6)使用游标删除记录
while((ret = cur->c_get(cur,&key,&value,DB_SET)) == 0 ){
cur->c_del(cur,0);
}
7)使用游标替换记录
ret = cur->c_get(cur,&key,&value,DB_SET);
if(ret == 0){
value.data = replacedata;
value.size = strlen(replacedata) + 1;
cur->c_put(cur,&key,&value,DB_CURRENT);
}