woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

Berkeley DB 简单入门

Development Environment

Windows XP ProfessionVisual Studio C++ 2005

Concept

1  Berkeley DB是嵌入式数据库系统,支持几乎所有的现代操作系统。

2  由一个个文件组成,文件名为XXX.DB,一个文件中可以含有一个到多个DB

3  Berkeley DB不支持SQL、存储过程和触发器等关系数据库的高级特性。

4  DatabaseDBT)就相同于关系数据库中的Table,它的key/data 对就相当于关系数据表的主键和其它n-1列,因为你可以在data中存入任意类型的数据,比如一个结构体。

5  游标(CursorDBC),就是一个关于特定记录的遍历器,在处理多重记录(duplicate record,多条记录key相同,而data不同)时使用它尤为方便,且效率高(称为bulk get,一次获取一批记录)。

6  数据库环境(DB_ENV),为Berkeley DB的高级特性,就是多个Database的包装器,它提供诸如日志恢复、多线程、事务处理和高性能支持等服务。

7  数据访问算法(Database Access Method)——数据在硬盘上存储和操作的方法。Berkeley DB支持B+树、HashRecnoQueue算法。

Begin to Use Berkeley DB

添加Berkeley dbinclude目录为Applicationinclude路径,添加其lib目录为Applicationlib引用路径,这样将Berkeley DBlib和我们的Application编译为一个程序,令其“嵌入”我们的程序中。

Choose Database Access Method

Access Method

Description

Choosing Occasion

B+

关键字有序存储,并且其结构能随数据的插入和删除进行动态调整。为了代码的简单,Berkeley DB没有实现对关键字的前缀码压缩。B+树支持对数据查询、插入、删除的常数级速度。关键字可以为任意的数据结构。

1  Key为复杂类型时。

2  Key有序时。

Hash

DB中实际使用的是扩展线性HASH算法(extended linear hashing),可以根据HASH表的增长进行适当的调整。关键字可以为任意的数据结构。

1  Key为复杂类型。

2  当数据较大且key随机分布时。

 

Recno

要求每一个记录都有一个逻辑纪录号,逻辑纪录号由算法本身生成。相当于关系数据库中的自动增长字段。Recho建立在B+树算法之上,提供了一个存储有序数据的接口。记录的长度可以为定长或不定长。

1  key为逻辑记录号时。

2  当非高并发的情况下。

Queue

Recno方式接近, 只不过记录的长度为定长。数据以定长记录方式存储在队列中,插入操作把记录插入到队列的尾部,相比之下插入速度是最快的。

1  1、当key为逻辑记录号时。

2  定长记录。

3  高并发的情况下。

 

 

Open Database

使用Db.open来打开一个数据库。打开数据库有多种方式,常用的有:

Open Flag

Description

DB_CREATE

如果数据库不存在,则创建之。

DB_EXCL

如果数据库存在,则返回失败。只和DB_CREATE一起使用才有意义。

DB_RDONLY

以只读的方式打开数据库。

 

代码示例:

#include <db_cxx.h>

 

...

 

Db db(NULL, 0);               // Instantiate the Db object

 

u_int32_t oFlags = DB_CREATE; // Open flags;

 

try {

    // Open the database

    db.open(NULL,                // Transaction pointer

            "my_db.db",          // Database file name

            NULL,                // Optional logical database name

            DB_BTREE,            // Database access method

            oFlags,              // Open flags

            0);                  // File mode (using defaults)

// DbException is not subclassed from std::exception, so

// need to catch both of these.

} catch(DbException &e) {

    // Error handling code goes here    

} catch(std::exception &e) {

    // Error handling code goes here

}

 

如果需要使用Berkeley DB的高级功能,可以在DbEnv(环境)中打开Database

#include <db_cxx.h>

...

u_int32_t env_flags = DB_CREATE;  // If the environment does not

                                  // exist, create it.

u_int32_t db_flags = DB_CREATE;   // If the database does not

                                  // exist, create it.

std::string envHome("/export1/testEnv");

std::string dbName("mydb.db");

DbEnv myEnv(0);

Db *myDb;

 

try {

    myEnv.open(envHome.c_str(), env_flags, 0);

    myDb = new Db(&myEnv, 0);

    myDb->open(NULL,

               dbName.c_str(),

               NULL,

               DB_BTREE,

               db_flags,

               0);

} catch(DbException &e) {

    std::cerr << "Error opening database environment: "

              << envHome

              << " and database "

              << dbName << std::endl;

    std::cerr << e.what() << std::endl;

    exit( -1 );

} catch(std::exception &e) {

    std::cerr << "Error opening database environment: "

              << envHome

              << " and database "

              << dbName << std::endl;

    std::cerr << e.what() << std::endl;

    exit( -1 );

}

 

Close Database

关闭数据库很简单,只需要使用Db.close(0)来关闭db

#include <db_cxx.h>

 

...

 

Db db(NULL, 0);

 

 // Database open and access operations happen here.

 

try {

    // Close the database

    db.close(0);

// DbException is not subclassed from std::exception, so

// need to catch both of these.

} catch(DbException &e) {

    // Error handling code goes here    

} catch(std::exception &e) {

    // Error handling code goes here

}

 

当在DbEnv中打开数据库时,关闭此DbEnv中的所有的Db后,必须关闭此DbEnv

try {

    if (myDb != NULL) {

        myDb->close(0);

    }

    myEnv.close(0);

    

} catch(DbException &e) {

    std::cerr << "Error closing database environment: "

              << envHome

              << " or database "

              << dbName << std::endl;

    std::cerr << e.what() << std::endl;

    exit( -1 );

} catch(std::exception &e) {

    std::cerr << "Error closing database environment: "

              << envHome

              << " or database "

              << dbName << std::endl;

    std::cerr << e.what() << std::endl;

    exit( -1 );

}

 

在操作数据(添加、修改和删除数据)时,都是在内存中进行的,并没有写到磁盘中,而只有当我们调用Db.close(0)方法后,才将内存中的数据写入磁盘中。如果不想关闭数据库而又想把数据写入磁盘的话,可以调用Db.sync(0)方法,及时将数据写入磁盘可以降低发生DB crash而导致数据丢失的危险的几率。

 

posted on 2012-06-01 16:20 肥仔 阅读(3423) 评论(0)  编辑 收藏 引用 所属分类: 数据库


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理