﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-swordhell-文章分类-使用Berkeley DB</title><link>http://www.cppblog.com/swordhell/category/3270.html</link><description>君子曰：学不可以已。</description><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 04:18:47 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 04:18:47 GMT</pubDate><ttl>60</ttl><item><title>Berkeley DB的基本使用</title><link>http://www.cppblog.com/swordhell/articles/16419.html</link><dc:creator>Sword.Hell blog</dc:creator><author>Sword.Hell blog</author><pubDate>Thu, 14 Dec 2006 03:14:00 GMT</pubDate><guid>http://www.cppblog.com/swordhell/articles/16419.html</guid><wfw:comment>http://www.cppblog.com/swordhell/comments/16419.html</wfw:comment><comments>http://www.cppblog.com/swordhell/articles/16419.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swordhell/comments/commentRss/16419.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swordhell/services/trackbacks/16419.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在下载安装这个数据库之后，来使用这样的数据库做一个例子。1.创建一个数据库														#include 				&lt;				db_cxx.h				&gt;																#include 				&lt;				iostream				&gt;																#include ...&nbsp;&nbsp;<a href='http://www.cppblog.com/swordhell/articles/16419.html'>阅读全文</a><img src ="http://www.cppblog.com/swordhell/aggbug/16419.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swordhell/" target="_blank">Sword.Hell blog</a> 2006-12-14 11:14 <a href="http://www.cppblog.com/swordhell/articles/16419.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Berkeley DB网上的资源</title><link>http://www.cppblog.com/swordhell/articles/16412.html</link><dc:creator>Sword.Hell blog</dc:creator><author>Sword.Hell blog</author><pubDate>Thu, 14 Dec 2006 02:23:00 GMT</pubDate><guid>http://www.cppblog.com/swordhell/articles/16412.html</guid><wfw:comment>http://www.cppblog.com/swordhell/comments/16412.html</wfw:comment><comments>http://www.cppblog.com/swordhell/articles/16412.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swordhell/comments/commentRss/16412.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swordhell/services/trackbacks/16412.html</trackback:ping><description><![CDATA[
		<p>
				<br />下载地址：<br /><a href="http://www.oracle.com/database/berkeley-db/index.html">http://www.oracle.com/database/berkeley-db/index.html</a><br /><a href="http://www.oracle.com/technology/software/products/berkeley-db/db/index.html">http://www.oracle.com/technology/software/products/berkeley-db/db/index.html</a><br />[2006-12-13]我现在使用的数据库的版本是4.5.20<br /><a href="http://www.oracle.com/technology/software/products/berkeley-db/htdocs/popup/db/4.5.20/db-msi.html">http://www.oracle.com/technology/software/products/berkeley-db/htdocs/popup/db/4.5.20/db-msi.html</a></p>
		<p>在他们的主页上有三个版本的Berkeley DB下载。<br /><a href="http://www.oracle.com/technology/global/cn/products/berkeley-db/index.html">http://www.oracle.com/technology/global/cn/products/berkeley-db/index.html</a><br />新内容 <br /> <br />Berkeley DB 版本 4.5　该新版本现在支持多版本并发控制、针对复制环境的不断升级以及一个预置的复制框架来简化高可用性应用程序的开发。 <br />最新！ Berkeley DB Java 版版本 3.1　该新版本支持直接持久层 (DPL)、使用 Java 批注的 EJB 样式的 API 以及 DPL 类的模式进化。 <br />新的 Berkeley DB 论坛已经开放针对 Berkeley DB、Berkeley DB 高可用性（复制）、Berkeley DB Java 版以及 Berkeley DB XML 的新 OTN 论坛现已面向 OTN 成员开放。无论您是初学者还是个中好手，都可以通过这些论坛进入我们形式多样、内容丰富的互动社区。 </p>
		<p>Oracle Berkeley DB、Berkeley DB Java 版 和 Berkeley DB XML 都是开放源代码开发人员数据库（商用许可也提供），这些数据库可为开发人员提供快速、可靠、本地的持久性，而管理负担很少或根本没有。Berkeley DB 作为嵌入式数据库部署在应用程序层，为不需要 SQL 的应用程序使用情形提供高性能、可靠性、可伸缩性以及可用性。</p>
		<p align="right">在windows下有setup的安装包。我们可以直接安装这个嵌入式的数据库。<br />具体的开发可以直接看在安装目录下的文档。<br /><br />[Sword.Hell]</p>
<img src ="http://www.cppblog.com/swordhell/aggbug/16412.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swordhell/" target="_blank">Sword.Hell blog</a> 2006-12-14 10:23 <a href="http://www.cppblog.com/swordhell/articles/16412.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Berkeley DB概述(转2)</title><link>http://www.cppblog.com/swordhell/articles/16411.html</link><dc:creator>Sword.Hell blog</dc:creator><author>Sword.Hell blog</author><pubDate>Thu, 14 Dec 2006 02:22:00 GMT</pubDate><guid>http://www.cppblog.com/swordhell/articles/16411.html</guid><wfw:comment>http://www.cppblog.com/swordhell/comments/16411.html</wfw:comment><comments>http://www.cppblog.com/swordhell/articles/16411.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swordhell/comments/commentRss/16411.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swordhell/services/trackbacks/16411.html</trackback:ping><description><![CDATA[
		<p>
				<br />[转载]开源嵌入式数据库Berkeley DB<br />开源嵌入式数据库Berkeley DB<br />作者：肖文鹏 发文时间：2004.04.09 </p>
		<p>像MySQL这类基于C/S结构的关系型数据库系统虽然代表着目前数据库应用的主流，但却并不能满足所有应用场合的需要。有时我们需要的可能只是一个简单的基于磁盘文件的数据库系统。这样不仅可以避免安装庞大的数据库服务器，而且还可以简化数据库应用程序的设计。Berkeley DB正是基于这样的思想提出来的。 </p>
		<p>Berkeley DB简介 </p>
		<p>Berkeley DB是一个开放源代码的内嵌式数据库管理系统，能够为应用程序提供高性能的数据管理服务。应用它程序员只需要调用一些简单的API就可以完成对数据的访问和管理。与常用的数据库管理系统（如MySQL和Oracle等）有所不同，在Berkeley DB中并没有数据库服务器的概念。应用程序不需要事先同数据库服务建立起网络连接，而是通过内嵌在程序中的Berkeley DB函数库来完成对数据的保存、查询、修改和删除等操作。 </p>
		<p>Berkeley DB为许多编程语言提供了实用的API接口，包括C、C++、Java、Perl、Tcl、Python和PHP等。所有同数据库相关的操作都由Berkeley DB函数库负责统一完成。这样无论是系统中的多个进程，或者是相同进程中的多个线程，都可以在同一时间调用访问数据库的函数。而底层的数据加锁、事务日志和存储管理等都在Berkeley DB函数库中实现。它们对应用程序来讲是完全透明的。俗话说：“麻雀虽小五脏俱全。”Berkeley DB函数库本身虽然只有300KB左右，但却能够用来管理多达256TB的数据，并且在许多方面的性能还能够同商业级的数据库系统相抗衡。就拿对数据的并发操作来说，Berkeley DB能够很轻松地应付几千个用户同时访问同一个数据库的情况。此外，如果想在资源受限的嵌入式系统上进行数据库管理，Berkeley DB可能就是惟一正确的选择了。 </p>
		<p>Berkeley DB作为一种嵌入式数据库系统在许多方面有着独特的优势。首先，由于其应用程序和数据库管理系统运行在相同的进程空间当中，进行数据操作时可以避免繁琐的进程间通信，因此耗费在通信上的开销自然也就降低到了极低程度。其次，Berkeley DB使用简单的函数调用接口来完成所有的数据库操作，而不是在数据库系统中经常用到的SQL语言。这样就避免了对结构化查询语言进行解析和处理所需的开销。 </p>
		<p>基本概念 </p>
		<p>Berkeley DB简化了数据库的操作模式，同时引入了一些新的基本概念，从而使得访问和管理数据库变得相对简单起来。在使用Berkeley DB提供的函数库编写数据库应用程序之前，有必要先了解以下这些基本概念。 </p>
		<p>关键字和数据 </p>
		<p>关键字（Key）和数据（Data）是Berkeley DB用来进行数据库管理的基础，由这两者构成的Key/Data对（见表1）组成了数据库中的一个基本结构单元，而整个数据库实际上就是由许多这样的结构单元所构成的。通过使用这种方式，开发人员在使用Berkeley DB提供的API来访问数据库时，只需提供关键字就能够访问到相应的数据。 </p>
		<p>Key Data  <br />sport football <br />Fruit orange <br />Drink beer </p>
		<p>
				<br />表1 Key/Data对 </p>
		<p>如果想将第一行中的“sport”和“football”保存到Berkeley DB数据库中，可以调用Berkeley DB函数库提供的数据保存接口。此时“sport”和“football”将分别当成关键字和数据来看待。之后如果需要从数据库中检索出该数据，可以用“sport”作为关键字进行查询。此时Berkeley DB提供的接口函数会返回与之对应的数据“football”。 </p>
		<p>关键字和数据在Berkeley DB中都是用一个名为DBT的简单结构来表示的。实际上两者都可以是任意长度的二进制数据，而DBT的作用主要是保存相应的内存地址及其长度，其结构如下所示： </p>
		<p>typedef struct {<br />  void *data;<br />  u_int32_t size;<br />  u_int32_t ulen;<br />  u_int32_t dlen;<br />  u_int32_t doff;<br />  u_int32_t flags;<br />} DBT;</p>
		<p> </p>
		<p>在使用Berkeley DB进行数据管理时，缺省情况下是一个关键字对应于一个数据，但事实上也可以将数据库配置成一个关键字对应于多个数据。 </p>
		<p>对象句柄 </p>
		<p>在Berkeley DB函数库定义的大多数函数都遵循同样的调用原则：首先创建某个结构，然后再调用该结构中的某些方法。从程序设计的角度来讲，这一点同面向对象的设计原则是非常类似的，即先创建某个对象的一个实例，然后再调用该实例的某些方法。正因如此，Berkeley DB引入了对象句柄的概念来表示实例化后的结构，并且将结构中的成员函数称为该句柄的方法。 </p>
		<p>对象句柄的引入使得程序员能够完全凭借面向对象的思想，来完成对Berkeley DB数据库的访问和操作，即使当前使用的是像C这样的结构化语言。例如，对于打开数据库的操作来说，可以调用DB的对象句柄所提供的open函数，其原型如下所示： </p>
		<p>int DB-&gt;open(DB *db, DB_TXN *txnid, const char *file, <br />const char *database, DBTYPE type, u_int32_t flags, int mode);</p>
		<p> </p>
		<p>错误处理 </p>
		<p>对于任何一个函数库来说，如何对错误进行统一的处理都是需要考虑的问题。Berkeley DB提供的所有函数都遵循同样的错误处理原则，即函数成功执行后返回零，否则的话则返回非零值。 </p>
		<p>对于系统错误（如磁盘空间不足和访问权限不够等），返回的是一个标准的值;而对于非系统错误，返回的则是一个特定的错误编码。例如，如果在数据库中没有与某个特定关键字所对应的数据，那么在通过该关键字检索数据时就会出现错误。此时函数的返回值将是DB_NOTFOUND，表示所请求的关键字并没有在数据库中出现。所有标准的errno值都是大于零的，而由Berkeley DB定义的特殊错误编码则都是小于零的。 </p>
		<p>要求程序员记住所有的错误代号既不现实也没有什么实际意义，因为Berkeley DB提供了相应的函数来获得错误代号所对应的错误描述。一旦有错误发生，只需首先调用db_strerror()函数来获得错误描述信息，然后再调用DB-&gt;err()或DB-&gt;errx()就可以很轻松地输出格式化后的错误信息。  开源嵌入式数据库Berkeley DB(2)  <br />作者：肖文鹏 发文时间：2004.04.09 </p>
		<p>接上一篇：开源的嵌入式数据库Berkeley DB(1) </p>
		<p> </p>
		<p>应用统一的编程接口 </p>
		<p>使用Berkeley DB提供的函数来进行数据库的访问和管理并不复杂，在大多数场合下只需按照统一的接口标准进行调用就可以完成最基本的操作。 </p>
		<p>打开数据库 </p>
		<p>打开数据库通常要分两步进行：首先调用db_create()函数来创建DB结构的一个实例，然后再调用DB-&gt;open()函数来完成真正的打开操作。Berkeley DB将所有对数据库的操作都封装在名为DB的结构中。db_create()函数的作用就是创建一个该结构，其原型如下所示： </p>
		<p>typedef struct__db DB;<br />int db_create(DB **dbp, DB_ENV *dbenv, u_int32_t flags);</p>
		<p> </p>
		<p>将磁盘上保存的文件作为数据库打开是由DB-&gt;open()函数来完成的，其原型如下所示： </p>
		<p>int DB-&gt;open(DB *db, DB_TXN *txnid, const char *file, <br />const char *database, DBTYPE type, u_int32_t flags, int mode);</p>
		<p> </p>
		<p>下面这段代码示范了如何创建DB对象句柄及如何打开数据库文件： </p>
		<p>#include &lt;sys/types.h&gt;<br />#include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include &lt;string.h&gt;<br />#include &lt;db.h&gt;<br />#define DATABASE "demo.db"<br />/* 以下程序代码的程序头同此＊/<br />int main()<br />{ DB *dbp;<br />int ret;<br />if ((ret = db_create(&amp;dbp, NULL, 0)) != 0) {<br />  fprintf(stderr, "db_create: %s\n", db_strerror(ret));<br />  exit (1);<br />}<br />if ((ret = dbp-&gt;open(dbp, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {<br />  dbp-&gt;err(dbp, ret, "%s", DATABASE);<br />  exit (1);<br />}<br />}</p>
		<p> </p>
		<p>代码首先调用db_create()函数来创建一个DB对象句柄。变量dbp在调用成功后将成为数据库句柄，通过它可以完成对底层数据库的配置或访问。接下去调用DB-&gt;open()函数打开数据库文件，参数“DATABASE”指明对应的磁盘文件名为demo.db；参数“DB_BTREE”表示数据库底层使用的数据结构是B树；而参数“DB_CREATE”和“0664”则表明当数据库文件不存在时创建一个新的数据库文件，并且将该文件的属性值设置为0664。 </p>
		<p>错误处理是在打开数据库时必须的例行检查，这可以通过调用DB-&gt;err()函数来完成。其中参数“ret”是在调用Berkeley DB函数后返回的错误代码，其余参数则用于显示结构化的错误信息。 </p>
		<p>添加数据 </p>
		<p>向Berkeley DB数据库中添加数据可以通过调用DB-&gt;put()函数来完成，其原型如下所示： </p>
		<p>int DB-&gt;put(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags);</p>
		<p> </p>
		<p>下面这段代码示范了如何向数据库中添加新的数据： </p>
		<p>int main()<br />{ DB *dbp;<br />DBT key, data;<br />int ret;<br />if ((ret = db_create(&amp;dbp, NULL, 0)) != 0) {<br />  fprintf(stderr, "db_create: %s\n", db_strerror(ret));<br />  exit (1);<br />}<br />if ((ret = dbp-&gt;open(dbp,<br />  NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {<br />  dbp-&gt;err(dbp, ret, "%s", DATABASE);<br />  exit (1);<br />}<br />memset(&amp;key, 0, sizeof(key));<br />memset(&amp;data, 0, sizeof(data));<br />key.data = "sport";<br />key.size = sizeof("sport");<br />data.data = "football";<br />data.size = sizeof("football");<br />if ((ret = dbp-&gt;put(dbp, NULL, &amp;key, &amp;data, 0)) == 0)<br />  printf("db: %s: key stored.\n", (char *)key.data);<br />else<br />  dbp-&gt;err(dbp, ret, "DB-&gt;put");<br />}</p>
		<p> </p>
		<p>代码首先声明了两个DBT结构变量，并分别用字符串“sport”和“football”进行填充。它们随后作为关键字和数据传递给用来添加数据的DB-&gt;put()函数。DBT结构几乎会在所有同数据访问相关的函数中被用到。 </p>
		<p>在向数据库中添加数据时，如果给定的关键字已经存在，大多数应用会对于已经存在的数据采用覆盖原则。也就是说，如果数据库中已经保存了一个“sport/basketball”对，再次调用DB-&gt;put()函数添加一个“sport/football”对，那么先前保存的那些数据将会被覆盖。但Berkeley DB允许在调用DB-&gt;put()函数时指定参数“DB_NOOVERWRITE”，声明不对数据库中已经存在的数据进行覆盖，其代码如下： </p>
		<p>if ((ret = dbp-&gt;put(dbp, NULL, &amp;key, &amp;data, DB_NOOVERWRITE)) == 0)<br />printf("db: %s: key stored.\n", (char *)key.data);<br />else<br />dbp-&gt;err(dbp, ret, "DB-&gt;put");</p>
		<p> </p>
		<p>一旦给出“DB_NOOVERWRITE”标记，如果DB-&gt;put()函数在执行过程中发现给出的关键字在数据库中已经存在了，就无法成功地把该Key/Data对添加到数据库中，于是将返回错误代号“DB_KEYEXIST”。 </p>
		<p>检索数据 </p>
		<p>从Berkeley DB数据库中检索数据可以通过调用DB-&gt;get()函数来完成，其原型如下所示： </p>
		<p>int DB-&gt;get(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags);</p>
		<p> </p>
		<p>下面这段代码示范了如何从数据库中检索出所需的数据： </p>
		<p>int main()<br />{ DB *dbp;<br />DBT key, data;<br />int ret;<br />if ((ret = db_create(&amp;dbp, NULL, 0)) != 0) {<br />  fprintf(stderr, "db_create: %s\n", db_strerror(ret));<br />  exit (1);<br />}<br />if ((ret = dbp-&gt;open(dbp,<br />  NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {<br />  dbp-&gt;err(dbp, ret, "%s", DATABASE);<br />  exit (1);<br />}<br />memset(&amp;key, 0, sizeof(key));<br />memset(&amp;data, 0, sizeof(data));<br />key.data = "sport";<br />key.size = sizeof("sport");<br />if ((ret = dbp-&gt;get(dbp, NULL, &amp;key, &amp;data, 0)) == 0)<br />  printf("db: %s: key retrieved: data was %s.\n",<br />   (char *)key.data, (char *)data.data);<br />else<br />  dbp-&gt;err(dbp, ret, "DB-&gt;get");<br />}</p>
		<p> </p>
		<p>代码同样声明了两个DBT结构变量，并且调用memset()函数对它们的内容清空。虽然Berkeley DB并不强制要求在进行数据操作之前先清空它们，但出于提高代码质量考虑还是建议先进行清空操作。在进行数据检索时，对DB-&gt;get()函数的返回值进行处理是必不可少的，因为它携带着检索操作是否成功完成等信息。下面列出的是DB-&gt;get()函数的返回值： </p>
		<p>◆ 0 函数调用成功，指定的关键字被找到； </p>
		<p>◆ DB_NOTFOUND 函数调用成功，但指定的关键字未被找到； </p>
		<p>◆大于0 函数调用失败，可能出现了系统错误。 </p>
		<p>删除数据 </p>
		<p>从Berkeley DB数据库中删除数据可以通过调用DB-&gt;del()函数来完成，其原型如下所示： </p>
		<p>int DB-&gt;del(DB *db, DB_TXN *txnid, DBT *key, u_int32_t flags);</p>
		<p> </p>
		<p>下面这段代码示范了如何从数据库中删除数据： </p>
		<p>int main()<br />{ DB *dbp;<br />DBT key;<br />int ret;<br />if ((ret = db_create(&amp;dbp, NULL, 0)) != 0) {<br />  fprintf(stderr, "db_create: %s\n", db_strerror(ret));<br />  exit (1);<br />}<br />if ((ret = dbp-&gt;open(dbp,<br />  NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {<br />  dbp-&gt;err(dbp, ret, "%s", DATABASE);<br />  exit (1);<br />}<br />memset(&amp;key, 0, sizeof(key));<br />key.data = "sport";<br />key.size = sizeof("sport");<br />if ((ret = dbp-&gt;del(dbp, NULL, &amp;key, 0)) == 0)<br />  printf("db: %s: key was deleted.\n", (char *)key.data);<br />else<br />  dbp-&gt;err(dbp, ret, "DB-&gt;del");<br />}</p>
		<p> </p>
		<p>删除数据只需给出相应的关键字，不用指明与之对应的数据。 </p>
		<p>关闭数据库 </p>
		<p>对于一次完整的数据库操作过程来说，关闭数据库是不可或缺的一个环节。这是因为Berkeley DB需要依赖于系统底层的缓冲机制，也就是说只有在数据库正常关闭的时候，修改后的数据才有可能全部写到磁盘上，同时它所占用的资源也才能真正被全部释放。关闭数据库的操作是通过调用DB-&gt;close()函数来完成的，其原型如下所示： </p>
		<p>int DB-&gt;close(DB *db, u_int32_t flags);</p>
		<p> </p>
		<p>下面这段代码示范了如何在需要的时候关闭数据库： </p>
		<p>int main()<br />{ DB *dbp;<br />DBT key, data;<br />int ret, t_ret;<br />if ((ret = db_create(&amp;dbp, NULL, 0)) != 0) {<br />  fprintf(stderr, "db_create: %s\n", db_strerror(ret));<br />  exit (1);<br />}<br />if ((ret = dbp-&gt;open(dbp,<br />  NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {<br />  dbp-&gt;err(dbp, ret, "%s", DATABASE);<br />  goto err;<br />}<br />memset(&amp;key, 0, sizeof(key));<br />memset(&amp;data, 0, sizeof(data));<br />key.data = "sport";<br />key.size = sizeof("sport");<br />if ((ret = dbp-&gt;get(dbp, NULL, &amp;key, &amp;data, 0)) == 0)<br />  printf("db: %s: key retrieved: data was %s.\n",<br />   (char *)key.data, (char *)data.data);<br />else<br />  dbp-&gt;err(dbp, ret, "DB-&gt;get");<br />if ((t_ret = dbp-&gt;close(dbp, 0)) != 0 &amp;&amp; ret == 0)<br />  ret = t_ret; <br />exit(ret);<br />}</p>
		<p> </p>
		<p>小结 </p>
		<p>Berkeley DB这个嵌入式数据库系统使用非常简单。它没有数据库服务器的概念，也不需要复杂的SQL语句，所有对数据的操作和管理都可以通过函数调用来完成，非常适合于那些需要对数据进行简单管理的应用场合。 </p>
		<p> </p>
		<p> </p>
<img src ="http://www.cppblog.com/swordhell/aggbug/16411.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swordhell/" target="_blank">Sword.Hell blog</a> 2006-12-14 10:22 <a href="http://www.cppblog.com/swordhell/articles/16411.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Berkeley DB概述(转1)</title><link>http://www.cppblog.com/swordhell/articles/16410.html</link><dc:creator>Sword.Hell blog</dc:creator><author>Sword.Hell blog</author><pubDate>Thu, 14 Dec 2006 02:21:00 GMT</pubDate><guid>http://www.cppblog.com/swordhell/articles/16410.html</guid><wfw:comment>http://www.cppblog.com/swordhell/comments/16410.html</wfw:comment><comments>http://www.cppblog.com/swordhell/articles/16410.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/swordhell/comments/commentRss/16410.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swordhell/services/trackbacks/16410.html</trackback:ping><description><![CDATA[
		<p>
				<br />皮东</p>
		<p>    Berkeley DB是由美国Sleepycat Software公司开发的一套开放源码的嵌入式数据库的程序库（database library），<br />它为应用程序提供可伸缩的、高性能的、有事务保护功能的数据管理服务。Berkeley DB为数据的存取和管理提供了一组<br />简洁的函数调用API接口。</p>
		<p>    它是一个经典的C-library模式的toolkit，为程序员提供广泛丰富的函数集，是为应用程序开发者提供工业级强度的<br />数据库服务而设计的。其主要特点如下：</p>
		<p>    嵌入式（Embedded）：它直接链接到应用程序中，与应用程序运行于同样的地址空间中，因此，无论是在网络上不同<br />计算机之间还是在同一台计算机的不同进程之间，数据库操作并不要求进程间通讯。</p>
		<p>    Berkeley DB为多种编程语言提供了API接口，其中包括C、C++、Java、Perl、Tcl、Python和PHP，所有的数据库操作<br />都在程序库内部发生。多个进程，或者同一进程的多个线程可同时使用数据库，有如各自单独使用，底层的服务如加锁、<br />事务日志、共享缓冲区管理、内存管理等等都由程序库透明地执行。</p>
		<p>    轻便灵活（Portable）：它可以运行于几乎所有的UNIX和Linux系统及其变种系统、Windows操作系统以及多种嵌入式实<br />时操作系统之下。它在32位和64位系统上均可运行，已经被好多高端的因特网服务器、台式机、掌上电脑、机顶盒、网络<br />交换机以及其他一些应用领域所采用。一旦Berkeley DB被链接到应用程序中，终端用户一般根本感觉不到有一个数据库<br />系统存在。</p>
		<p>    可伸缩（Scalable）：这一点表现在很多方面。Database library本身是很精简的（少于300KB的文本空间），但它<br />能够管理规模高达256TB的数据库。它支持高并发度，成千上万个用户可同时操纵同一个数据库。Berkeley DB能以足够小<br />的空间占用量运行于有严格约束的嵌入式系统，也可以在高端服务器上耗用若干GB的内存和若干TB的磁盘空间。</p>
		<p>    Berkeley DB在嵌入式应用中比关系数据库和面向对象数据库要好，有以下两点原因：<br />    <br />    （1）因为数据库程序库同应用程序在相同的地址空间中运行，所以数据库操作不需要进程间的通讯。在一台机器的<br />不同进程间或在网络中不同机器间进行进程通讯所花费的开销，要远远大于函数调用的开销；</p>
		<p>    （2）因为Berkeley DB对所有操作都使用一组API接口，因此不需要对某种查询语言进行解析，也不用生成执行计划，<br />大大提高了运行效.</p>
		<p>
				<br />BerkeleyDB系统结构 </p>
		<p>
				<br />    Berkeley DB由五个主要的子系统构成.包括: 存取管理子系统、内存池管理子系统、事务子系统、锁子系统以及日志子系统。<br />其中存取管理子系统作为Berkeley DB数据库进程包内部核心组件，而其他子系统都存在于Berkeley DB数据库进程包的外部。   </p>
		<p>    每个子系统支持不同的应用级别。</p>
		<p>    1.数据存取子系统<br />    数据存取（Access Methods）子系统为创建和访问数据库文件提供了多种支持。Berkeley DB提供了以下四种文件存储方法：<br />哈希文件、B树、定长记录（队列）和变长记录（基于记录号的简单存储方式），应用程序可以从中选择最适合的文件组织结构。<br />程序员创建表时可以使用任意一种结构，并且可以在同一个应用程序中对不同存储类型的文件进行混合操作。</p>
		<p>    在没有事务管理的情况下，该子系统中的模块可单独使用，为应用程序提供快速高效的数据存取服务。<br />数据存取子系统适用于不需事务只需快速格式文件访问的应用。</p>
		<p>    2.内存池管理子系统<br />    内存池（Memory pool）子系统对Berkeley DB所使用的共享缓冲区进行有效的管理。它允许同时访问数据库的多个进程或者<br />进程的多个线程共享一个高速缓存，负责将修改后的页写回文件和为新调入的页分配内存空间。<br />    <br />    它也可以独立于Berkeley DB系统之外，单独被应用程序使用，为其自己的文件和页分配内存空间。<br />内存池管理子系统适用于需要灵活的、面向页的、缓冲的共享文件访问的应用。</p>
		<p>    3.事务子系统<br />    事务（Transaction）子系统为Berkeley DB提供事务管理功能。它允许把一组对数据库的修改看作一个原子单位，<br />这组操作要么全做，要么全不做。在默认的情况下，系统将提供严格的ACID事务属性，但是应用程序可以选择不使用系统所作的<br />隔离保证。该子系统使用两段锁技术和先写日志策略来保证数据库数据的正确性和一致性。</p>
		<p>    它也可以被应用程序单独使用来对其自身的数据更新进行事务保护。事务子系统适用于需要事务保证数据的修改的应用。<br />    <br />    4.锁子系统<br />    锁（Locking）子系统为Berkeley DB提供锁机制，为系统提供多用户读取和单用户修改同一对象的共享控制。<br />数据存取子系统可利用该子系统获得对页或记录的读写权限；事务子系统利用锁机制来实现多个事务的并发控制。<br />    <br />    该子系统也可被应用程序单独采用。锁子系统适用于一个灵活的、快速的、可设置的锁管理器。<br />    <br />    5.日志子系统    <br />    日志（Logging）子系统采用的是先写日志的策略，用于支持事务子系统进行数据恢复，保证数据一致性。<br />它不大可能被应用程序单独使用，只能作为事务子系统的调用模块。</p>
		<p>    以上几部分构成了整个Berkeley DB数据库系统。各部分的关系如下图所示：<br />    <br />    在这个模型中，应用程序直接调用的是数据存取子系统和事务管理子系统，这两个系统进而调用更下层的内存管理子系统、<br />锁子系统和日志子系统。<br />    <br />    由于几个子系统相对比较独立，所以应用程序在开始的时候可以指定哪些数据管理服务将被使用。可以全部使用，<br />也可以只用其中的一部分。例如，如果一个应用程序需要支持多用户并发操作，但不需要进行事务管理，那它就可以<br />只用锁子系统而不用事务。有些应用程序可能需要快速的、单用户、没有事务管理功能的B树存储结构，那么应用程序<br />可以使锁子系统和事务子系统失效，这样就会减少开销。  </p>
		<p>BerkeleyDB存储功能概述     <br />    <br />    Berkeley DB所管理数据的逻辑组织单位是若干个独立或有一定关系的数据库(database)，<br />每个数据库由若干记录组成，这些记录全都被表示成(key，value)的形式.</p>
		<p>    如果把一组相关的(key，value)对也看作一个表的话，那么每一个数据库只允许存放一个table，<br />这一点不同于一般的关系数据库。实际上，在Berkeley DB中所提到的“数据库”，相当于一般关系数据库系统中的表；<br />而“key/data”对相当于关系数据库系统中的行(rows)；Berkeley DB不提供关系数据库中列直接访问的功能，<br />而是在“key/data”对中的data项中通过实际应用来封装字段(列)。</p>
		<p>    在物理组织上，每一个数据库在创建的时候可以由应用程序根据其数据特点来选择一种合适的存储结构。<br />可供选择的四种文件存储结构分别是：哈希文件、B树、定长记录(队列)和变长记录(基于记录号的简单存储方式)。</p>
		<p>    一个物理的文件中可以只存放一个单独的数据库，也可以存放若干相关或不相关的数据库，而且这些数据库<br />可以分别采用除队列之外任意不同的组织方式，以队列组织的数据库只能单独存放于一个文件，不能同其他存储类型混合存放。</p>
		<p>    一个文件除了受最大文件长度和存储空间的约束之外，理论上可以存储任意多个数据库。<br />因此系统定位一个数据库通常需要两个参数——“文件名”和“数据库名”，这也是Berkeley DB不同于<br />一般关系数据库的地方。</p>
		<p>   Berkeley DB存储系统为应用程序提供了一系列的接口函数，用于对数据库的管理和操作。其中包括：<br />      (1)数据库的创建、打开、关闭、删除、重命名等，以及对数据的检索和增删改操作；<br />      (2)提供一些附加的功能，例如读取数据库状态信息、读取所在文件的信息、读取所在数据库环境的信息、<br />清空数据库的内容、数据库的同步备份、版本升级、提示出错信息等等；<br />      (3)系统还提供了游标机制，用于存取和访问成组的数据，以及对两个或多个相关数据库进行关联和等值连接操作；<br />      (4)系统还给出了一些接口函数用于对存取策略进行优化配置，比如应用程序可以自己设置B树的排序比较函数、<br />每页中存放key的最少数目，哈希桶的填充因子、哈希函数、哈希表最大长度，队列的最大长度，数据库存放的字节顺序，<br />底层存储页的大小，内存分配函数，高速缓存的大小，定长记录的大小和填充位，变长记录所用的分隔符等等。<br />     </p>
		<p>转自(<a href="http://dev.csdn.net/article/39/39637.shtm">http://dev.csdn.net/article/39/39637.shtm</a>)<br /></p>
<img src ="http://www.cppblog.com/swordhell/aggbug/16410.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swordhell/" target="_blank">Sword.Hell blog</a> 2006-12-14 10:21 <a href="http://www.cppblog.com/swordhell/articles/16410.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>