??xml version="1.0" encoding="utf-8" standalone="yes"?>
下蝲地址Q?br />http://www.oracle.com/database/berkeley-db/index.html
http://www.oracle.com/technology/software/products/berkeley-db/db/index.html
[2006-12-13]我现在用的数据库的版本?.5.20
http://www.oracle.com/technology/software/products/berkeley-db/htdocs/popup/db/4.5.20/db-msi.html
在他们的主页上有三个版本的Berkeley DB下蝲?br />http://www.oracle.com/technology/global/cn/products/berkeley-db/index.html
新内?
Berkeley DB 版本 4.5 该新版本现在支持多版本ƈ发控制、针对复制环境的不断升以及一个预|的复制框架来简化高可用性应用程序的开发?
最斎ͼ Berkeley DB Java 版版?3.1 该新版本支持直接持久?(DPL)、?Java Ҏ?EJB 样式?API 以及 DPL cȝ模式q化?
新的 Berkeley DB 论坛已经开N?Berkeley DB、Berkeley DB 高可用性(复制Q、Berkeley DB Java 版以?Berkeley DB XML 的新 OTN 论坛现已面向 OTN 成员开放。无论您是初学者还是个中好手,都可以通过q些论坛q入我们形式多样、内容丰富的互动C?
Oracle Berkeley DB、Berkeley DB Java ??Berkeley DB XML 都是开放源代码开发h员数据库Q商用许可也提供Q,q些数据库可为开发h员提供快速、可靠、本地的持久性,而管理负担很或Ҏ没有。Berkeley DB 作ؓ嵌入式数据库部v在应用程序层Qؓ不需?SQL 的应用程序用情形提供高性能、可靠性、可伸羃性以及可用性?/p>
在windows下有setup的安装包。我们可以直接安装这个嵌入式的数据库?br />具体的开发可以直接看在安装目录下的文档?br />
[Sword.Hell]
像MySQLq类ZC/Sl构的关pd数据库系l虽然代表着目前数据库应用的LQ但却ƈ不能满所有应用场合的需要。有时我们需要的可能只是一个简单的Z盘文g的数据库pȝ。这样不仅可以避免安装庞大的数据库服务器Q而且q可以简化数据库应用E序的设计。Berkeley DB正是Zq样的思想提出来的?
Berkeley DB?
Berkeley DB是一个开放源代码的内嵌式数据库管理系l,能够为应用程序提供高性能的数据管理服务。应用它E序员只需要调用一些简单的API可以完成对数据的访问和理。与常用的数据库理pȝQ如MySQL和Oracle{)有所不同Q在Berkeley DB中ƈ没有数据库服务器的概c应用程序不需要事先同数据库服务徏立v|络q接Q而是通过内嵌在程序中的Berkeley DB函数库来完成Ҏ据的保存、查询、修改和删除{操作?
Berkeley DB多编E语a提供了实用的API接口Q包括C、C++、Java、Perl、Tcl、Python和PHP{。所有同数据库相关的操作都由Berkeley DB函数库负责统一完成。这h论是pȝ中的多个q程Q或者是相同q程中的多个U程Q都可以在同一旉调用讉K数据库的函数。而底层的数据加锁、事务日志和存储理{都在Berkeley DB函数库中实现。它们对应用E序来讲是完全透明的。俗话说Q“麻雀虽小五脏俱全。”Berkeley DB函数库本w虽然只?00KB左右Q但却能够用来管理多?56TB的数据,q且在许多方面的性能q能够同商业U的数据库系l相抗衡。就拿对数据的ƈ发操作来_Berkeley DB能够很轻村֜应付几千个用户同时访问同一个数据库的情c此外,如果惛_资源受限的嵌入式pȝ上进行数据库理QBerkeley DB可能是惟一正确的选择了?
Berkeley DB作ؓ一U嵌入式数据库系l在许多斚w有着独特的优ѝ首先,׃其应用程序和数据库管理系l运行在相同的进E空间当中,q行数据操作时可以避免繁琐的q程间通信Q因此耗费在通信上的开销自然也就降低C极低E度。其ơ,Berkeley DB使用单的函数调用接口来完成所有的数据库操作,而不是在数据库系l中l常用到的SQL语言。这样就避免了对l构化查询语aq行解析和处理所需的开销?
基本概念
Berkeley DB化了数据库的操作模式Q同时引入了一些新的基本概念,从而得访问和理数据库变得相对简单v来。在使用Berkeley DB提供的函数库~写数据库应用程序之前,有必要先了解以下q些基本概念?
关键字和数据
关键字(KeyQ和数据QDataQ是Berkeley DB用来q行数据库管理的基础Q由q两者构成的Key/Data对(见表1Q组成了数据库中的一个基本结构单元,而整个数据库实际上就是由许多q样的结构单元所构成的。通过使用q种方式Q开发h员在使用Berkeley DB提供的API来访问数据库Ӟ只需提供关键字就能够讉K到相应的数据?
Key Data
sport football
Fruit orange
Drink beer
? Key/Data?
如果惛_W一行中的“sport”和“football”保存到Berkeley DB数据库中Q可以调用Berkeley DB函数库提供的数据保存接口。此时“sport”和“football”将分别当成关键字和数据来看待。之后如果需要从数据库中索出该数据,可以用“sport”作为关键字q行查询。此时Berkeley DB提供的接口函Cq回与之对应的数据“football”?
关键字和数据在Berkeley DB中都是用一个名为DBT的简单结构来表示的。实际上两者都可以是Q意长度的二进制数据,而DBT的作用主要是保存相应的内存地址及其长度Q其l构如下所C:
typedef struct {
void *data;
u_int32_t size;
u_int32_t ulen;
u_int32_t dlen;
u_int32_t doff;
u_int32_t flags;
} DBT;
在用Berkeley DBq行数据理Ӟ~省情况下是一个关键字对应于一个数据,但事实上也可以将数据库配|成一个关键字对应于多个数据?
对象句柄
在Berkeley DB函数库定义的大多数函数都遵@同样的调用原则:首先创徏某个l构Q然后再调用该结构中的某些方法。从E序设计的角度来Ԍq一点同面向对象的设计原则是非常cM的,卛_创徏某个对象的一个实例,然后再调用该实例的某些方法。正因如此,Berkeley DB引入了对象句柄的概念来表C实例化后的l构Qƈ且将l构中的成员函数UCؓ该句柄的Ҏ?
对象句柄的引入得程序员能够完全凭借面向对象的思想Q来完成对Berkeley DB数据库的讉K和操作,即当前使用的是像Cq样的结构化语言。例如,对于打开数据库的操作来说Q可以调用DB的对象句柄所提供的open函数Q其原型如下所C:
int DB->open(DB *db, DB_TXN *txnid, const char *file,
const char *database, DBTYPE type, u_int32_t flags, int mode);
错误处理
对于M一个函数库来说Q如何对错误q行l一的处理都是需要考虑的问题。Berkeley DB提供的所有函数都遵@同样的错误处理原则,卛_数成功执行后q回Ӟ否则的话则返回非零倹{?
对于pȝ错误Q如盘I间不和访问权限不够等Q,q回的是一个标准的?而对于非pȝ错误Q返回的则是一个特定的错误~码。例如,如果在数据库中没有与某个特定关键字所对应的数据,那么在通过该关键字索数据时׃出现错误。此时函数的q回值将是DB_NOTFOUNDQ表C所h的关键字q没有在数据库中出现。所有标准的errno值都是大于零的,而由Berkeley DB定义的特D错误编码则都是于零的?
要求E序员记住所有的错误代号既不现实也没有什么实际意义,因ؓBerkeley DB提供了相应的函数来获得错误代h对应的错误描q。一旦有错误发生Q只需首先调用db_strerror()函数来获得错误描qC息,然后再调用DB->err()或DB->errx()可以很L地输出格式化后的错误信息。?开源嵌入式数据库Berkeley DB(2)
作者:肖文?发文旉Q?004.04.09
接上一:开源的嵌入式数据库Berkeley DB(1)
应用l一的编E接?
使用Berkeley DB提供的函数来q行数据库的讉K和管理ƈ不复杂,在大多数场合下只需按照l一的接口标准进行调用就可以完成最基本的操作?
打开数据?
打开数据库通常要分两步q行Q首先调用db_create()函数来创建DBl构的一个实例,然后再调用DB->open()函数来完成真正的打开操作。Berkeley DB所有对数据库的操作都封装在名ؓDB的结构中。db_create()函数的作用就是创Z个该l构Q其原型如下所C:
typedef struct__db DB;
int db_create(DB **dbp, DB_ENV *dbenv, u_int32_t flags);
磁盘上保存的文件作为数据库打开是由DB->open()函数来完成的Q其原型如下所C:
int DB->open(DB *db, DB_TXN *txnid, const char *file,
const char *database, DBTYPE type, u_int32_t flags, int mode);
下面q段代码C了如何创建DB对象句柄及如何打开数据库文Ӟ
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#define DATABASE "demo.db"
/* 以下E序代码的程序头同此Q?
int main()
{ DB *dbp;
int ret;
if ((ret = db_create(&dbp, NULL, 0)) != 0) {
fprintf(stderr, "db_create: %s\n", db_strerror(ret));
exit (1);
}
if ((ret = dbp->open(dbp, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
dbp->err(dbp, ret, "%s", DATABASE);
exit (1);
}
}
代码首先调用db_create()函数来创Z个DB对象句柄。变量dbp在调用成功后成为数据库句柄Q通过它可以完成对底层数据库的配置或访问。接下去调用DB->open()函数打开数据库文Ӟ参数“DATABASE”指明对应的盘文g名ؓdemo.dbQ参数“DB_BTREE”表C数据库底层使用的数据结构是B树;而参数“DB_CREATE”和?664”则表明当数据库文g不存在时创徏一个新的数据库文gQƈ且将该文件的属性D|ؓ0664?
错误处理是在打开数据库时必须的例行检查,q可以通过调用DB->err()函数来完成。其中参数“ret”是在调用Berkeley DB函数后返回的错误代码Q其余参数则用于昄l构化的错误信息?
d数据
向Berkeley DB数据库中d数据可以通过调用DB->put()函数来完成,其原型如下所C:
int DB->put(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags);
下面q段代码C了如何向数据库中d新的数据Q?
int main()
{ DB *dbp;
DBT key, data;
int ret;
if ((ret = db_create(&dbp, NULL, 0)) != 0) {
fprintf(stderr, "db_create: %s\n", db_strerror(ret));
exit (1);
}
if ((ret = dbp->open(dbp,
NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
dbp->err(dbp, ret, "%s", DATABASE);
exit (1);
}
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
key.data = "sport";
key.size = sizeof("sport");
data.data = "football";
data.size = sizeof("football");
if ((ret = dbp->put(dbp, NULL, &key, &data, 0)) == 0)
printf("db: %s: key stored.\n", (char *)key.data);
else
dbp->err(dbp, ret, "DB->put");
}
代码首先声明了两个DBTl构变量Qƈ分别用字W串“sport”和“football”进行填充。它们随后作为关键字和数据传递给用来d数据的DB->put()函数。DBTl构几乎会在所有同数据讉K相关的函C被用到?
在向数据库中d数据Ӟ如果l定的关键字已经存在Q大多数应用会对于已l存在的数据采用覆盖原则。也是_如果数据库中已经保存了一个“sport/basketball”对Q再ơ调用DB->put()函数d一个“sport/football”对Q那么先前保存的那些数据会被覆盖。但Berkeley DB允许在调用DB->put()函数时指定参数“DB_NOOVERWRITE”,声明不对数据库中已经存在的数据进行覆盖,其代码如下:
if ((ret = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE)) == 0)
printf("db: %s: key stored.\n", (char *)key.data);
else
dbp->err(dbp, ret, "DB->put");
一旦给出“DB_NOOVERWRITE”标讎ͼ如果DB->put()函数在执行过E中发现l出的关键字在数据库中已l存在了Q就无法成功地把该Key/DataҎ加到数据库中Q于是将q回错误代号“DB_KEYEXIST”?
索数?
从Berkeley DB数据库中索数据可以通过调用DB->get()函数来完成,其原型如下所C:
int DB->get(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags);
下面q段代码C了如何从数据库中索出所需的数据:
int main()
{ DB *dbp;
DBT key, data;
int ret;
if ((ret = db_create(&dbp, NULL, 0)) != 0) {
fprintf(stderr, "db_create: %s\n", db_strerror(ret));
exit (1);
}
if ((ret = dbp->open(dbp,
NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
dbp->err(dbp, ret, "%s", DATABASE);
exit (1);
}
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
key.data = "sport";
key.size = sizeof("sport");
if ((ret = dbp->get(dbp, NULL, &key, &data, 0)) == 0)
printf("db: %s: key retrieved: data was %s.\n",
(char *)key.data, (char *)data.data);
else
dbp->err(dbp, ret, "DB->get");
}
代码同样声明了两个DBTl构变量Qƈ且调用memset()函数对它们的内容清空。虽然Berkeley DBq不强制要求在进行数据操作之前先清空它们Q但Z提高代码质量考虑q是先进行清I操作。在q行数据索时Q对DB->get()函数的返回D行处理是必不可少的,因ؓ它携带着索操作是否成功完成等信息。下面列出的是DB->get()函数的返回|
?0 函数调用成功Q指定的关键字被扑ֈQ?
?DB_NOTFOUND 函数调用成功Q但指定的关键字未被扑ֈQ?
◆大? 函数调用p|Q可能出Cpȝ错误?
删除数据
从Berkeley DB数据库中删除数据可以通过调用DB->del()函数来完成,其原型如下所C:
int DB->del(DB *db, DB_TXN *txnid, DBT *key, u_int32_t flags);
下面q段代码C了如何从数据库中删除数据Q?
int main()
{ DB *dbp;
DBT key;
int ret;
if ((ret = db_create(&dbp, NULL, 0)) != 0) {
fprintf(stderr, "db_create: %s\n", db_strerror(ret));
exit (1);
}
if ((ret = dbp->open(dbp,
NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
dbp->err(dbp, ret, "%s", DATABASE);
exit (1);
}
memset(&key, 0, sizeof(key));
key.data = "sport";
key.size = sizeof("sport");
if ((ret = dbp->del(dbp, NULL, &key, 0)) == 0)
printf("db: %s: key was deleted.\n", (char *)key.data);
else
dbp->err(dbp, ret, "DB->del");
}
删除数据只需l出相应的关键字Q不用指明与之对应的数据?
关闭数据?
对于一ơ完整的数据库操作过E来_关闭数据库是不可或缺的一个环节。这是因为Berkeley DB需要依赖于pȝ底层的缓冲机Ӟ也就是说只有在数据库正常关闭的时候,修改后的数据才有可能全部写到盘上,同时它所占用的资源也才能真正被全部释放。关闭数据库的操作是通过调用DB->close()函数来完成的Q其原型如下所C:
int DB->close(DB *db, u_int32_t flags);
下面q段代码C了如何在需要的时候关闭数据库Q?
int main()
{ DB *dbp;
DBT key, data;
int ret, t_ret;
if ((ret = db_create(&dbp, NULL, 0)) != 0) {
fprintf(stderr, "db_create: %s\n", db_strerror(ret));
exit (1);
}
if ((ret = dbp->open(dbp,
NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
dbp->err(dbp, ret, "%s", DATABASE);
goto err;
}
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
key.data = "sport";
key.size = sizeof("sport");
if ((ret = dbp->get(dbp, NULL, &key, &data, 0)) == 0)
printf("db: %s: key retrieved: data was %s.\n",
(char *)key.data, (char *)data.data);
else
dbp->err(dbp, ret, "DB->get");
if ((t_ret = dbp->close(dbp, 0)) != 0 && ret == 0)
ret = t_ret;
exit(ret);
}
结
Berkeley DBq个嵌入式数据库pȝ使用非常单。它没有数据库服务器的概念,也不需要复杂的SQL语句Q所有对数据的操作和理都可以通过函数调用来完成,非常适合于那些需要对数据q行单管理的应用场合?
Berkeley DB是由国Sleepycat Software公司开发的一套开放源码的嵌入式数据库的程序库Qdatabase libraryQ,
它ؓ应用E序提供可~的、高性能的、有事务保护功能的数据管理服务。Berkeley DB为数据的存取和管理提供了一l?br />z的函数调用API接口?/p>
它是一个经典的C-library模式的toolkitQؓE序员提供广泛丰富的函数集,是ؓ应用E序开发者提供工业强度?br />数据库服务而设计的。其主要特点如下Q?/p>
嵌入式(EmbeddedQ:它直接链接到应用E序中,与应用程序运行于同样的地址I间中,因此Q无论是在网l上不同
计算Z间还是在同一台计机的不同进E之_数据库操作ƈ不要求进E间通讯?/p>
Berkeley DB为多U编E语a提供了API接口Q其中包括C、C++、Java、Perl、Tcl、Python和PHPQ所有的数据库操?br />都在E序库内部发生。多个进E,或者同一q程的多个线E可同时使用数据库,有如各自单独使用Q底层的服务如加锁?br />事务日志、共享缓冲区理、内存管理等{都q序库透明地执行?/p>
M灉|QPortableQ:它可以运行于几乎所有的UNIX和Linuxpȝ及其变种pȝ、Windows操作pȝ以及多种嵌入式实
时操作系l之下。它?2位和64位系l上均可q行Q已l被好多高端的因特网服务器、台式机、掌上电脑、机盒、网l?br />交换Z及其他一些应用领域所采用。一旦Berkeley DB被链接到应用E序中,l端用户一般根本感觉不到有一个数据库
pȝ存在?/p>
可~(ScalableQ:q一点表现在很多斚w。Database library本n是很_的(于300KB的文本空_Q但?br />能够理规模高达256TB的数据库。它支持高ƈ发度Q成千上万个用户可同时操U同一个数据库。Berkeley DB能以_?br />的空间占用量q行于有严格U束的嵌入式pȝQ也可以在高端服务器上耗用若干GB的内存和若干TB的磁盘空间?/p>
Berkeley DB在嵌入式应用中比关系数据库和面向对象数据库要好,有以下两点原因:
Q?Q因为数据库E序库同应用E序在相同的地址I间中运行,所以数据库操作不需要进E间的通讯。在一台机器的
不同q程间或在网l中不同机器间进行进E通讯所p的开销Q要q远大于函数调用的开销Q?/p>
Q?Q因为Berkeley DBҎ有操作都使用一lAPI接口Q因此不需要对某种查询语言q行解析Q也不用生成执行计划Q?br />大大提高了运行效.
BerkeleyDBpȝl构
Berkeley DB׃个主要的子系l构?包括: 存取理子系l、内存池理子系l、事务子pȝ、锁子系l以及日志子pȝ?br />其中存取理子系l作为Berkeley DB数据库进E包内部核心lgQ而其他子pȝ都存在于Berkeley DB数据库进E包的外部。 ?
每个子系l支持不同的应用U别?/p>
1.数据存取子系l?br /> 数据存取QAccess MethodsQ子pȝ为创建和讉K数据库文件提供了多种支持。Berkeley DB提供了以下四U文件存储方法:
哈希文g、B树、定长记录(队列Q和变长记录Q基于记录号的简单存储方式)Q应用程序可以从中选择最适合的文件组l结构?br />E序员创时可以用Q意一U结构,q且可以在同一个应用程序中对不同存储类型的文gq行混合操作?/p>
在没有事务管理的情况下,该子pȝ中的模块可单独用,为应用程序提供快速高效的数据存取服务?br />数据存取子系l适用于不需事务只需快速格式文件访问的应用?/p>
2.内存池管理子pȝ
内存池(Memory poolQ子pȝ对Berkeley DB所使用的共享缓冲区q行有效的管理。它允许同时讉K数据库的多个q程或?br />q程的多个线E共享一个高速缓存,负责修改后的页写回文g和ؓ新调入的分配内存空间?br />
它也可以独立于Berkeley DBpȝ之外Q单独被应用E序使用Qؓ其自q文g和页分配内存I间?br />内存池管理子pȝ适用于需要灵zȝ、面向页的、缓冲的׃n文g讉K的应用?/p>
3.事务子系l?br /> 事务QTransactionQ子pȝ为Berkeley DB提供事务理功能。它允许把一l对数据库的修改看作一个原子单位,
q组操作要么全做Q要么全不做。在默认的情况下Q系l将提供严格的ACID事务属性,但是应用E序可以选择不用系l所作的
隔离保证。该子系l用两D锁技术和先写日志{略来保证数据库数据的正性和一致性?/p>
它也可以被应用程序单独用来对其自n的数据更新进行事务保护。事务子pȝ适用于需要事务保证数据的修改的应用?br />
4.锁子pȝ
锁(LockingQ子pȝ为Berkeley DB提供锁机Ӟ为系l提供多用户d和单用户修改同一对象的共享控制?br />数据存取子系l可利用该子pȝ获得寚w或记录的d权限Q事务子pȝ利用锁机制来实现多个事务的ƈ发控制?br />
该子pȝ也可被应用程序单独采用。锁子系l适用于一个灵zȝ、快速的、可讄的锁理器?br />
5.日志子系l ?
日志QLoggingQ子pȝ采用的是先写日志的策略,用于支持事务子系l进行数据恢复,保证数据一致性?br />它不大可能被应用E序单独使用Q只能作Z务子pȝ的调用模块?/p>
以上几部分构成了整个Berkeley DB数据库系l。各部分的关pd下图所C:
在这个模型中Q应用程序直接调用的是数据存取子pȝ和事务管理子pȝQ这两个pȝq而调用更下层的内存管理子pȝ?br />锁子pȝ和日志子pȝ?br />
׃几个子系l相Ҏ较独立,所以应用程序在开始的时候可以指定哪些数据管理服务将被用。可以全部用,
也可以只用其中的一部分。例如,如果一个应用程序需要支持多用户q发操作Q但不需要进行事务管理,那它可?br />只用锁子pȝ而不用事务。有些应用程序可能需要快速的、单用户、没有事务管理功能的B树存储结构,那么应用E序
可以佉K子系l和事务子系l失效,q样׃减少开销。?
BerkeleyDB存储功能概述
Berkeley DB所理数据的逻辑l织单位是若q个独立或有一定关pȝ数据?database)Q?br />每个数据库由若干记录l成Q这些记录全都被表示?keyQvalue)的Ş?
如果把一l相关的(keyQvalue)对也看作一个表的话Q那么每一个数据库只允许存放一个tableQ?br />q一点不同于一般的关系数据库。实际上Q在Berkeley DB中所提到的“数据库”,相当于一般关pL据库pȝ中的表;
而“key/data”对相当于关pL据库pȝ中的?rows)QBerkeley DB不提供关pL据库中列直接讉K的功能,
而是在“key/data”对中的data中通过实际应用来封装字D???/p>
在物理组l上Q每一个数据库在创建的时候可以由应用E序Ҏ其数据特Ҏ选择一U合适的存储l构?br />可供选择的四U文件存储结构分别是Q哈希文件、B树、定长记?队列)和变长记?Z记录L单存储方??/p>
一个物理的文g中可以只存放一个单独的数据库,也可以存放若q相x不相关的数据库,而且q些数据?br />可以分别采用除队列之外Q意不同的l织方式Q以队列l织的数据库只能单独存放于一个文Ӟ不能同其他存储类型合存放?/p>
一个文仉了受最大文仉度和存储I间的约束之外,理论上可以存储Q意多个数据库?br />因此pȝ定位一个数据库通常需要两个参数——“文件名”和“数据库名”,q也是Berkeley DB不同?br />一般关pL据库的地斏V?/p>
Berkeley DB存储pȝ为应用程序提供了一pd的接口函敎ͼ用于Ҏ据库的管理和操作。其中包括:
(1)数据库的创徏、打开、关闭、删除、重命名{,以及Ҏ据的索和增删Ҏ作;
(2)提供一些附加的功能Q例如读取数据库状态信息、读取所在文件的信息、读取所在数据库环境的信息?br />清空数据库的内容、数据库的同步备份、版本升U、提C出错信息等{;
(3)pȝq提供了游标机制Q用于存取和讉K成组的数据,以及对两个或多个相关数据库进行关联和{D接操作;
(4)pȝq给Z一些接口函数用于对存取{略q行优化配置Q比如应用程序可以自p|B树的排序比较函数?br />每页中存放key的最数目,哈希桶的填充因子、哈希函数、哈希表最大长度,队列的最大长度,数据库存攄字节序Q?br />底层存储늚大小Q内存分配函敎ͼ高速缓存的大小Q定长记录的大小和填充位Q变长记录所用的分隔W等{?br />
转自(http://dev.csdn.net/article/39/39637.shtm)