POP Article V2.0 设为主页
收藏本站
首 页交流论坛留 言
您现在的位置:首 页 >> 热门开源项目 >> Berkeley DB >> 查看文章
Oracle Berkeley DB 指南(2)
作者:tamsyn  来源:www.sqlite.com.cn  时间:2007-11-5  【 字体: 】 〖 双击滚屏 〗

有了这些作为背景后,我们返回到次索引的讨论。因为 Berkeley DB 不了解键/数据对中数据元素的模式和结构,所以需要应用程序的帮助来找到我们用作次索引的字段。应用程序以回调函数方式提供帮助。回调函数接受键/数据对输入并返回引用了用作次键的值的 DBT

所以要创建 last_name 的次索引,必须编写一个回调函数,接受键/数据对输入并返回引用了数据项的 last_name 字段的 DBT。  

int
  lname_callback(DB *dbp, const DBT *key, const DBT *data, DBT *skey)
  {
  emp_data *edata;
  /*
  * We know that the opaque byte-string represented by the data DBT
  * represents one of our emp_data structures, so let's cast it
  * to one of those so that we can manipulate it.
  */
  edata = data->data;
  skey->data = edata->lname;
  skey->size = strlen((edata->lname);
  return (0);
  }

  写完回调函数后,可以指定次索引。次索引只是一个表,所以先创建一个表:  

DB *sdbp;
  ASSERT(db_create(&sdbp, dbenv, 0) == 0);
  /* Configure sdbp. */
  ASSERT(sdbp->open(sdbp, NULL, "emp_lname.db", NULL, DB_BTREE,
  DB_AUTO_COMMIT | DB_CREATE | DB_THREAD, 0644) == 0);

  再次使用 B 树结构对姓进行索引,保留以前使用的所有标记和模式。

  最后,您必须将次索引表与主表(员工表)相关联。请记住,dbp 是员工表的句柄, sdbp 是次索引表的句柄。

  ASSERT(dbp->associate(dbp, NULL, sdbp, lname_callback, flags) == 0);

  注意事项:

·                            可以了创建任意多的次索引。重要的问题是次索引降低了插入的速度 (因为您必须为每个次索引创建索引项),但如果使用次键值(如,姓)来查询和选择字节组, 它们将大大改进查询的性能。

·                            在任何时候更新主表时,只要打开并关联了次索引,次索引将始终保持最新。但如果忘记打开并关联次索引,然后更改基表,您会发现次索引不是最新的。

  应当避免这一情况。

  DDL 中的最后两个操作是丢弃命令:丢弃索引、表和数据库。

  如同在 SQL 中丢弃索引和删除表一样,您也能在 Berkeley DB 中完成这些操作。在 SQL 中,您可以执行以下命令

  DROP TABLE employee

  或者

  DROP INDEX lname

SQL 中丢弃一个表将丢弃与之关联的所有索引,在 Berkeley DB 中,您必须显式完成此任务。幸运的是,在 Berkeley DB 中丢弃表或索引是同样的操作。

  移除表前,必须关闭表上的所有数据库句柄。关闭表容易;假设我们要丢弃员工数据库的次索引。先关闭次索引:

  sdbp->close(sdbp, 0)

  在发出数据库句柄的关闭命令后,不能再使用句柄。

  关闭次索引表后,您可以使用 dbenv 句柄的 dbremove 方法将其移除:  

DB_ENV *dbenv;
  ASSERT(dbenv->dbremove(dbenv,
  NULL, "emp_lname.db", NULL, DB_AUTO_COMMIT) == 0);

  可以使用同一调用顺序 (closing dbremoving) 来丢弃表。

  假设不想丢弃表,只想更改其名称。您也可完成这一操作。

  与移除一样,首先要关闭表句柄:

  dbp->close(dbp, 0);

  现在您可以更改表名称:  

DB_ENV *dbenv;
  ASSERT(dbenv->dbrename(dbenv,
  NULL, "employee.db", NULL, "newemp.db", DB_AUTO_COMMIT) == 0);

  最后,您可能想销毁数据库。在 SQL 中执行

  DROP DATABASE personnel

  这一命令在 Berkeley DB 中也有对应的命令。

  首先,必须关闭环境:

  ASSERT(dbenv->close(dbenv, 0) == 0);

  与关闭表句柄一样,当关闭环境句柄后,将不能使用该句柄。所以,为了丢弃表,您需要创建一个新句柄,然后使用该句柄移除数据库(环境)。 

ASSERT(db_env_create(&dbenv, 0) == 0);
  ASSERT(dbenv->remove(dbenv, "my_databases/personnel", 0) == 0);

  至此,我们完成了 SQL DDL Berkeley DB 的转换。接下来,我们将讨论如何完成 SQL DML Berkeley DB 的转换。

  在 Berkeley DB 中执行 SQL DML 操作

  我们已经介绍了 SQL DDL 和其在 Berkeley DB 中的实现,现在要将数据添加到数据库,讨论 SQL 的插入、更新和删除。

  在 SQL 中使用插入语句将数据插入表:  

INSERT INTO employees VALUES (00010002, "mouse", "mickey", 1000000.00,
  "Main Street", "Disney Land", "CA", 98765);

  SQL 插入都变成了数据库或游标句柄的 Berkeley DB“put”方法;我们先讨论数据库,然后再探讨游标。

  假设您已经打开了一个表,有一个数据库句柄 dbp 引用了员工表。现在,雇佣 Mickey Mouse

DB *dbp;
  DBT key_dbt, data_dbt;
  emp_data edata;
  emp_key ekey;
  /* Put the value into the employee key. */
  ekey = 00010002;
  /* Initialize an emp_data structure. */
  strcpy(edata.lname, "Mouse");
  strcpy(edata.fname, "Mickey");
  edata.salary = 1000000.00;
  strcpy(edata.street, "Main Street");
  strcpy(edata.city, "Disney Land");
  strcpy(edata.state, "CA");
  edata.zip = 98765;
  /* Initialize DBTs */
  memset(&key_dbt, 0, sizeof(key_dbt));
  memset(&data_dbt, 0, sizeof(data_dbt));
  /* Now, assign key and data values to DBTs. */
  key->data = &ekey;
  key->size = sizeof(ekey);
  data->data = &edata;
  data->size = sizeof(edata);
  /* Finally, put the data into the database. */
  ASSERT(dbp->put(dbp, NULL, &key_dbt, &data_dbt, DB_AUTO_COMMIT) == 0);

  请注意,如果已经有将任何次索引与员工表相关联(如在 SQL ),则在插入时将自动对其进行更新。

  现在,假设表中有些数据,您希望对这些数据进行更改。例如,要给 Mickey 涨工资!有多种完成方法。

浏览次数:   【 打 印 】【 关 闭
上一篇:SQL 开发人员 Oracle Berkeley DB 指南(1)
下一篇:Oracle Berkeley DB 指南(3)
 论坛登陆
用户名:
密  码:
验证码: 
Cookie 选项:
正常登陆 隐身登陆
   
没有注册?
 文章搜索
 推荐文章
 酷站推荐
 热门文章
 网站统计
关于我们 | 网站地图 | 联系我们 | 网站历史 | 友情链接 | TOP
Copyright© 2006 Sqlite中文社区  程序开发: mistletoe  站长: 林轩 陈文成