bind数据存储—Berkeley DB

这里还需要讲一个信息,就是bind的数据是通过怎样的方式组织起来的,Bind通过Berkeley DB的方式组织数据的,它是一个开源的文件数据库软件,介于关系数据库和内存数据库之间,使用方式和内存数据库类似,提供一系列可以直接访问数据库的函数,它可以保存任意类型的键值对

它的结构:它内部支持B+树,支持hash等算法

核心数据结构

数据库环境句柄DB_ENV:每个DB_ENV相当于一个数据库,它包含了数据库全局信息,比如缓冲区大小、以及对事务日志、锁等子系统的全局配置信息。

数据库句柄结构DB:每个DB相当于关系数据库的一个表,其中存储了很多key/data pair。DB句柄代表了一个包含了若干描述数据库表属性的参数,如数据库访问方法类型、逻辑页面大小、数据库名称等;同时,DB结构中包含了大量的数据库处理函数指针,大多数形式为 (*dosomething)(DB *, arg1, arg2, …)。其中最重要的有open,close,put,get等函数。

数据库记录结构DBT:DB中的记录由关键字和数据构成,关键字和数据都用结构DBT表示。实际上完全可以把关键字看成特殊的数据。结构中最重要的两个字段是 void * data和u_int32_t size,分别对应数据本身和数据的长度。

数据库游标结构DBC:游标(cursor)是数据库应用中常见概念,其本质上就是一个关于特定记录的遍历器。注意到DB支持多重记录(duplicate records),即多条记录有相同关键字,在对多重记录的处理中,使用游标是最容易的方式。

数据库环境句柄结构DB_ENV:环境在DB中属于高级特性,本质上看,环境是多个数据库的包装器。当一个或多个数据库在环境中打开后,环境可以为这些数据库提供多种子系统服务,例如多线/进程处理支持、事务处理支持、高性能支持、日志恢复支持等。

最简单的一个例子:
//声明一个数据
char *fruit = "apple";
int number = 15;
typedef struct customer
  {
  int c_id;
  char name[10];
  char address[20];
  int age;
  } CUSTOMER;
CUSTOMER cust;
int key_cust_c_id = 1;
cust.c_id = 1;
strncpy(cust. name, "javer", 9);
strncpy(cust.address, "chengdu", 19);
cust.age = 32;

DB *dbp;
DBT key, data;
ret = db_create(&dbp, NULL, 0);
/* 创建一个名为single.db的数据库,使用B+树访问算法,本段代码演示对简单数据类型的处理 */
ret = dbp->open(dbp, NULL, "single.db", NULL, DB_BTREE, flags, 0);
init_DBT(&key, &data);
  /* 分别对关键字和数据赋值和规定长度 */
key.data = fruit;
key.size = strlen(fruit) + 1;
data.data = &number;
data.size = sizeof(int);
ret = dbp->put(dbp, NULL, &key, &data,DB_NOOVERWRITE);
/* 手动把缓存中的数据刷新到硬盘文件中,实际上在关闭数据库时,数据会被自动刷新 */
dbp->sync();
或者存储这样的数据:
key.size = sizeof(int);
key.data = &(cust.c_id);
data.size = sizeof(CUSTOMER);
data.data = &cust;

游标的使用:
/* 定义一个游标变量 */
  DBC * cur;
  /* 首先打开数据库,再打开游标 */
  dbp->open(dbp, ……);
  dbp->cursor(dbp, NULL, &cur, 0);
  /* do something with cursor */
  /* 首先关闭,在关闭数据库 */
  cur->c_close(cur);
  dbp->close(dbp, 0);
在游标打开后,可以以多种方式遍历特定记录。
While((ret = cur->c_get(cur, &key, &data, DB_NEXT)) == 0)
{
 /* do something with key and data */
}

当想查询特定关键字对应的记录,则应对关键字赋值,并把cur->c_get()函数中标志位设置为DB_SET。例如
key.data = "xxxxx";
  key.size = XXX;
  While((ret = cur->c_get(cur, &key, &data, DB_SET)) == 0)
  {
  /* do something with key and data */
  }
环境使用
环境是DB数据库的包装器,提供多种高级功能。应用程序代码框架如下:
/* 定义一个环境变量,并创建 */
  DB_ENV *dbenv;
  db_env_create(&dbenv, 0);
  /* 在环境打开之前,可调用形式为dbenv->set_XXX()的若干函数设置环境 */
  /* 通知DB使用Rijndael加密算法(参考资料4)对数据进行处理 */
  dbenv->set_encrypt(dbenv, "encrypt_string", DB_ENCRYPT_AES);
  /* 设置DB的缓存为5M */
  dbenv->set_cachesize(dbenv, 0, 5 * 1024 * 1024, 0);
  /* 设置DB查找数据库文件的目录 */
  dbenv->set_data_dir(dbenv, "/usr/javer/work_db");
  /* 打开数据库环境,注意后四个标志分别指示DB启动日志、加锁、缓存、事务处理子系统 */
  dbenv->open(dbenv,home,DB_CREATE|DB_INIT_LOG|DB_INIT_LOCK| DB_INIT_MPOOL|DB_INIT_TXN, 0);
  /* 在环境打开后,则可以打开若干个数据库,所有数据库的处理都在环境的控制和保护中。注意db_create函数的第二个参数是环境变量 */
  db_create(&dbp1, dbenv, 0);
  dbp1->open(dbp1, ……);
  db_create(&dbp2, dbenv, 0);
  dbp1->open(dbp2, ……);
  /* do something with the database */
  /* 最后首先关闭打开的数据库,再关闭环境 */
  dbp2->close(dbp2, 0);
  dbp1->close(dbp1, 0);
  dbenv->close(dbenv, 0);

猜你喜欢

转载自blog.csdn.net/wellwang1993/article/details/83507067