- 浏览: 2031046 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (651)
- ACE (35)
- BAT (9)
- C/C++ (116)
- fast-cgi (14)
- COM (27)
- python (59)
- CGI (4)
- C# (2)
- VC (84)
- DataBase (29)
- Linux (96)
- P2P (6)
- PHP (15)
- Web (6)
- Memcached (7)
- IME输入法 (11)
- 设计模式 (2)
- 搜索引擎 (1)
- 个人情感 (4)
- 笔试/面试 (3)
- 一亩三分地 (33)
- 历史 (2)
- 地理 (1)
- 人物 (3)
- 经济 (0)
- 不仅仅是笑哦 (43)
- 小故事大道理 (2)
- http://www.bjdsmyysjk120.com/ (0)
- http://www.bjdsmyy120.com/ (0)
- 它山之石可以攻玉 (15)
- 大学生你关注些什么 (28)
- 数据恢复 (1)
最新评论
-
luokaichuang:
这个规范里还是没有让我明白当浏览器上传文件时,STDIN的消息 ...
FastCGI规范 -
effort_fan:
好文章!学习了,谢谢分享!
com技术简介 -
vcell:
有错误os.walk(strPath)返回的已经是全部的文件和 ...
通过python获取目录的大小 -
feifeigd:
feifeigd 写道注意:文章中的CPP示例第二行 #inc ...
ATL入门:利用ATL编写简单的COM组件 -
feifeigd:
注意:文章中的CPP示例第二行 #include " ...
ATL入门:利用ATL编写简单的COM组件
UNIX/LINUX平台下的数据库种类非常多,参考资料1中列举了其中的大部分。通常,我们在设计UNIX/LINUX平台下的应用软件时,如果数据种类繁多,数据与数据之间关系比较复杂,就会选用一些大型的企业级数据库系统,如DB2,ORACLE、SYBASE等,如果软件规模不大,就倾向选用如MYSQL、POSTGRESQL等中小型数据库。例如使用PHP/PERL + MYSQL/POSTGRESQL设计网站基本上是一个很常规的做法。但是,当应用软件管理的数据类型较少(特别注意:这并不是说需要管理的数据量小),数据管理本身不复杂,且对数据操作要求高效率,则由大名鼎鼎的Berkeley(美国加州大学伯克利分校)开发的 Berkeley DB可能是一个很明智的选择。
DB最初开发的目的是以新的HASH访问算法来代替旧的hsearch函数和大量的dbm实现(如AT&T的dbm,Berkeley的ndbm,GNU项目的gdbm),DB的第一个发行版在1991年出现,当时还包含了B+树数据访问算法。在1992年,BSD UNIX第4.4发行版中包含了DB1.85版。基本上认为这是DB的第一个正式版。在1996年中期,Sleepycat软件公司成立,提供对DB的商业支持。在这以后,DB得到了广泛的应用,当前最新版本是4.3.27。
DB支持几乎所有的现代操作系统,如LINUX、UNIX、WINDOWS等,也提供了丰富的应用程序接口,支持C、C++、JAVA、PERL、TCL、PYTHON、PHP等。DB的应用十分广泛,在很多知名的软件中都能看到其身影。例如参考资料2中作者谈到利用DB在LINUX下实现内核级文件系统;参考资料3中通过实际测试数据说明DB提高了OPENLDAP的效率。LINUX下的软件包管理器RPM也使用DB管理软件包相关数据,可以使用命令file查看RPM数据目录/var/lib/rpm下的文件,则有形式如下的输出:
Dirnames: Berkeley DB (Btree, version 9, native byte-order)
Filemd5s: Berkeley DB (Hash, version 8, native byte-order)
值得注意的是DB是嵌入式数据库系统,而不是常见的关系/对象型数据库,对SQL语言不支持,也不提供数据库常见的高级功能,如存储过程,触发器等。
DB的设计思想是简单、小巧、可靠、高性能。如果说一些主流数据库系统是大而全的话,那么DB就可称为小而精。DB提供了一系列应用程序接口(API),调用本身很简单,应用程序和DB所提供的库在一起编译成为可执行程序。这种方式从两方面极大提高了DB的效率。第一:DB库和应用程序运行在同一个地址空间,没有客户端程序和数据库服务器之间昂贵的网络通讯开销,也没有本地主机进程之间的通讯;第二:不需要对SQL代码解码,对数据的访问直截了当。
DB对需要管理的数据看法很简单,DB数据库包含若干条记录,每一个记录由关键字和数据(KEY/VALUE)构成。数据可以是简单的数据类型,也可以是复杂的数据类型,例如C语言中结构。DB对数据类型不做任何解释, 完全由程序员自行处理,典型的C语言指针的"自由"风格。如果把记录看成一个有n个字段的表,那么第1个字段为表的主键,第2--n个字段对应了其它数据。DB应用程序通常使用多个DB数据库,从某种意义上看,也就是关系数据库中的多个表。DB库非常紧凑,不超过500K,但可以管理大至256T的数据量。
DB的设计充分体现了UNIX的基于工具的哲学,即若干简单工具的组合可以实现强大的功能。DB的每一个基础功能模块都被设计为独立的,也即意味着其使用领域并不局限于DB本身。例如加锁子系统可以用于非DB应用程序的通用操作,内存共享缓冲池子系统可以用于在内存中基于页面的文件缓冲。
数据库句柄结构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中属于高级特性,本质上看,环境是多个数据库的包装器。当一个或多个数据库在环境中打开后,环境可以为这些数据库提供多种子系统服务,例如多线/进程处理支持、事务处理支持、高性能支持、日志恢复支持等。
DB中核心数据结构在使用前都要初始化,随后可以调用结构中的函数(指针)完成各种操作,最后必须关闭数据结构。从设计思想的层面上看,这种设计方法是利用面向过程语言实现面对对象编程的一个典范。
在数据库领域中,数据访问算法对应了数据在硬盘上的存储格式和操作方法。在编写应用程序时,选择合适的算法可能会在运算速度上提高1个甚至多个数量级。大多数数据库都选用B+树算法,DB也不例外,同时还支持HASH算法、Recno算法和Queue算法。接下来,我们将讨论这些算法的特点以及如何根据需要存储数据的特点进行选择。
B+树算法:B+树是一个平衡树,关键字有序存储,并且其结构能随数据的插入和删除进行动态调整。为了代码的简单,DB没有实现对关键字的前缀码压缩。B+树支持对数据查询、插入、删除的常数级速度。关键字可以为任意的数据结构。
HASH算法:DB中实际使用的是扩展线性HASH算法(extended linear hashing),可以根据HASH表的增长进行适当的调整。关键字可以为任意的数据结构。
Recno算法: 要求每一个记录都有一个逻辑纪录号,逻辑纪录号由算法本身生成。实际上,这和关系型数据库中逻辑主键通常定义为int AUTO型是同一个概念。Recho建立在B+树算法之上,提供了一个存储有序数据的接口。记录的长度可以为定长或不定长。
Queue算法:和Recno方式接近, 只不过记录的长度为定长。数据以定长记录方式存储在队列中,插入操作把记录插入到队列的尾部,相比之下插入速度是最快的。
对算法的选择首先要看关键字的类型,如果为复杂类型,则只能选择B+树或HASH算法,如果关键字为逻辑记录号,则应该选择Recno或Queue算法。当工作集关键字有序时,B+树算法比较合适;如果工作集比较大且基本上关键字为随机分布时,选择HASH算法。Queue算法只能存储定长的记录,在高的并发处理情况下,Queue算法效率较高;如果是其它情况,则选择Recno算法,Recno算法把数据存储为平面文件格式。
#include <db.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
/* DB的函数执行完成后,返回0代表成功,否则失败 */
void print_error(int ret)
{
if(ret != 0)
printf("ERROR: %s\n",db_strerror(ret));
}
/* 数据结构DBT在使用前,应首先初始化,否则编译可通过但运行时报参数错误 */
void init_DBT(DBT * key, DBT * data)
{
memset(key, 0, sizeof(DBT));
memset(data, 0, sizeof(DBT));
}
void main(void)
{
DB *dbp;
DBT key, data;
u_int32_t flags;
int ret;
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;
/* 首先创建数据库句柄 */
ret = db_create(&dbp, NULL, 0);
print_error(ret);
/* 创建数据库标志 */
flags = DB_CREATE;
/* 创建一个名为single.db的数据库,使用B+树访问算法,本段代码演示对简单数据类型的处理 */
ret = dbp->open(dbp, NULL, "single.db", NULL, DB_BTREE, flags, 0);
print_error(ret);
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);
print_error(ret);
/* 手动把缓存中的数据刷新到硬盘文件中,实际上在关闭数据库时,数据会被自动刷新 */
dbp->sync();
init_DBT(&key, &data);
key.data = fruit;
key.size = strlen(fruit) + 1;
/* 从数据库中查询关键字为apple的记录 */
ret = dbp->get(dbp, NULL, &key, &data, 0);
print_error(ret);
/* 特别要注意数据结构DBT的字段data为void *型,所以在对data赋值和取值时,要做必要的类型转换。 */
printf("The number = %d\n", *(int*)(data.data));
if(dbp != NULL)
dbp->close(dbp, 0);
ret = db_create(&dbp, NULL, 0);
print_error(ret);
flags = DB_CREATE;
/* 创建一个名为complex.db的数据库,使用HASH访问算法,本段代码演示对复杂数据结构的处理 */
ret = dbp->open(dbp, NULL, "complex.db", NULL, DB_HASH, flags, 0);
print_error(ret);
init_DBT(&key, &data);
key.size = sizeof(int);
key.data = &(cust.c_id);
data.size = sizeof(CUSTOMER);
data.data = &cust;
ret = dbp->put(dbp, NULL, &key, &data,DB_NOOVERWRITE);
print_error(ret);
memset(&cust, 0, sizeof(CUSTOMER));
key.size = sizeof(int);
key.data = &key_cust_c_id;
data.data = &cust;
data.ulen = sizeof(CUSTOMER);
data.flags = DB_DBT_USERMEM;
dbp->get(dbp, NULL, &key, &data, 0);
print_error(ret);
printf("c_id = %d name = %s address = %s age = %d\n",
cust.c_id, cust.name, cust.address, cust.age);
if(dbp != NULL)
dbp->close(dbp, 0);
}
|
游标是依赖于数据库句柄的,应用程序代码框架如下:
/* 定义一个游标变量 */
DBC * cur;
/* 首先打开数据库,再打开游标 */
dbp->open(dbp, ……);
dbp->cursor(dbp, NULL, &cur, 0);
/* do something with cursor */
/* 首先关闭,在关闭数据库 */
cur->c_close(cur);
dbp->close(dbp, 0);
|
在游标打开后,可以以多种方式遍历特定记录。
Memset(&key, 0, sizeof(DBT));
Memset(&data, 0, sizeof(DBT));
/* 因为KEY和DATA为空,则游标遍历整个数据库记录 */
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加密算法(参考资料>)对数据进行处理 */
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);
|
从DB的官方站点http://www.sleepycat.com/下载最新的软件包db-4.3.27.tar.gz,解压到工作目录,进入该目录,依次执行下列三条命令即可。
../dist/configure
make
make install
|
执行make uninstall,则可卸载已安装的DB软件。
DB缺省把库和头文件安装在目录/usr/local/BerkeleyDB.4.3/下,使用gcc test.c -ggdb -I/usr/local/BerkeleyDB.4.3/include/ -L/usr/local/BerkeleyDB.4.3/lib/ -ldb -lpthread就可正确编译程序。如果读者的测试主机操作系统为RED HAT9,则安装的DB版本可能是4.0。特别要注意到这两个版本的库是不兼容的。例如打开数据库函数DB->open(),在4.0版本中入参为6个,而在4.3版中则为7个(可自行比较两个库的头文件db.h中DB->open函数的定义)。因为在DB相关的应用程序中,open函数基本上都是要执行的,所以如果函数和版本不匹配,编译肯定会出错。当然,编译完成后,可以使用命令ldd查看库的依赖关系。
DB是一个具有工业强度的嵌入式数据库系统,数据处理的效率很高。DB功能的稳定性历经时间的考验,在大量应用程序中使用便是明证。可以想见,在同等代码质量的条件下,软件的BUG数和代码的长度是成正比的,相对几十兆、几百兆大型数据库软件,DB的只有不到500K的大小!
从实现功能上看,DB是轻量级数据库系统,或可称为"极" 轻量级数据库系统。但是,我认为不能因此而心存轻视之意,所谓"尺有所短,寸有所长",以绝对角度比较工具之间的好坏是没有什么意义的,关键在于对工具的选择和运用(似乎可以参考一下极限编程的思想)。也许,正确的"表达范式"应该是:在当前应用背景下,选择这种工具是最合适的。
- 《Linux SQL Databases and Tools》
- 《Performance Improvement of OpenLDAP Transactional Backend》
- Rijndael加密算法官方站点
施聪,成都人,高级程序员、网络设计师。从事基于UNIX/LINUX下的c/c++程序设计和数据库建模工作已10年。可通过javer@163.com或memncmp@yahoo.com.cn和他联系。
发表评论
-
多机器执行ssh脚本
2012-08-30 18:12 2234#!/bin/bash Usage() { ... -
Berkeley DB 使用经验总结
2012-08-27 14:41 3083作者:陈磊 NoSQL是现在互联网Web2.0时代备受 ... -
C语言中标准输入流、标准输出流、标准错误输出流
2011-06-13 14:32 9277C语言中标准输入流、标准输出流、标准错误输出流 在 ... -
mysql给用户赋予权限
2011-05-20 17:35 1209grant all on *.* to 'apsara' ... -
Rsync 实现原理
2011-05-12 20:06 8313Rsync 实现原理 前言 关于rsync的原始文档 ... -
shell中双引号的误用
2011-05-12 15:02 1177for i in "$LIST" ... -
c++简单的虚函数测试
2011-04-27 14:25 1013#include <iostream> u ... -
C++文件行查找
2011-04-26 14:10 1399#include <iostream> # ... -
c++偏特化简单示例
2011-04-13 11:17 2151c++偏特化 // temp1.c ... -
shell for循环
2011-04-06 15:36 973for i in "1 2 3";do e ... -
GDB调试精粹及使用实例
2011-03-16 14:06 1133GDB调试精粹及使用实例 一:列文件清单 1. ... -
shell技巧 除法
2011-03-07 11:34 19174shell计算中使用除法,基本默认上都是整除。 比如: ... -
.bash_profile 文件修改之后不执行
2011-02-16 11:21 1934重新登录 不可能不好用的 除非你是从一个用户su oralc ... -
简单的ini文件解析
2011-02-12 16:36 1611int GetKeyVal(const string s ... -
SecureCRT中文显示乱码的解决方法
2011-02-12 11:38 1339最近开始用SecureCRT登陆linux系统,由于是新手,很 ... -
让putty显示中文
2011-02-11 14:43 1419对于经常在windows下远程ssh到linux的用户而言,p ... -
scanf族函数高级用法
2011-01-25 16:00 2550如何解释 fscanf(fd,&quo ... -
使用scons替代makefile(1)
2011-01-25 11:58 3721早在多年前我刚开始接触linux下的C程序时,经常被makef ... -
使用scons替代makefile(2)
2011-01-25 11:57 3575本篇文章接着上一篇进一步介绍scons的使用方法,主要介绍静态 ... -
使用scons替代makefile(3)
2011-01-25 11:55 4817在上两篇文章中已经简单介绍了用scons编译库文件,可执行程序 ...
相关推荐
Berkeley DB Java Edition(简称BDB JE)是一种高性能、轻量级的嵌入式数据库系统,由Oracle公司开发,广泛应用于需要快速数据存储和检索的应用场景。它并非传统的关系型数据库管理系统(RDBMS),而是一种键值对...
Berkeley DB嵌入式数据库系统,无需独立服务器进程,为BerkeleyDBUI提供高效的数据管理基础
4. **缓存系统**:嵌入式数据库如Berkeley DB常用于构建本地缓存,提高应用程序性能。 5. **嵌入式操作系统**:在小型嵌入式系统中,如汽车导航系统,嵌入式数据库可提供地图数据的存储和检索。 **设计和选择** ...
Berkeley DB是一个高性能、可靠性高的嵌入式数据库,广泛应用于嵌入式系统、移动设备、桌面应用程序等。Berkeley DB具有体积小、速度快、易用性高、支持事务等特点。 本章节对嵌入式数据库的概述、特点、分类和应用...
嵌入式数据库系统 Berkeley DB - **21.1 前言** - **嵌入式数据库**:介绍嵌入式数据库的一般特点。 - **21.2 DB 综述** - **Berkeley DB 介绍**:概述 Berkeley DB 的特点和优势。 - **21.3 DB 的设计思想** - ...
用berkeleydb设计的嵌入式数据库,可进行查询,修改,删除,插入基本功能
**Berkeley DB** 是一款轻量级的嵌入式数据库管理系统,由Oracle公司开发,广泛应用于需要快速、高效数据存储的场景,特别是在嵌入式系统和分布式应用中。这款数据库的特点在于它不需要独立的服务器进程,可以直接在...
本主题将深入探讨两种常见的嵌入式数据库技术:SQLite 和 Berkeley DB,并分析它们在指纹识别系统中的具体应用。 SQLite 是一种开源的关系型数据库管理系统,它具有轻量级、零配置、自包含的特点,无需独立服务器...
### 嵌入式数据库典型技术——SQLite与Berkeley DB的研究 #### 一、引言 随着信息技术的发展,特别是嵌入式系统领域的迅速进步,传统的数据库管理系统已经难以满足某些特定场景下的需求。例如,在资源受限的环境中...
目前,嵌入式数据库市场已经包含了多种类型的产品,如SQLite、Berkeley DB、HSQLDB等。这些数据库系统在性能、内存占用、数据完整性等方面不断优化,以适应各种设备和应用场景。未来趋势上,嵌入式数据库将更加注重...
Berkeley DB(简称BDB)是一种高性能、轻量级的嵌入式数据库系统,由Oracle公司开发并维护。它最初在伯克利大学诞生,因此得名“Berkeley DB”。这款数据库系统广泛应用于需要快速、可靠数据存储的应用中,尤其在...
常见的嵌入式数据库产品如Berkeley DB、Sysbase Adaptive Server Anywhere和Linter等,它们支持多种开发语言和平台,为开发者提供了广泛的灵活性。 总结来说,嵌入式数据库是现代技术领域不可或缺的一部分,它们在...
- **特性**:Berkeley DB 是一个高度可定制且性能卓越的嵌入式数据库系统,提供事务支持和多种数据访问方法。 - **应用领域**:适用于需要高效数据存储与检索的应用程序。 - **API 接口**:支持多种编程语言如 C、...
Berkeley DB是一款由Oracle公司开发的嵌入式数据库系统,被广泛应用于许多软件项目中,尤其是在需要快速、轻量级数据存储解决方案的场景下。它提供了键值对存储模式,适用于构建高性能的数据缓存和数据库应用程序。...
**伯克利数据库(Berkeley DB...总的来说,伯克利数据库(BDB)是一个强大的、适用于32位系统的嵌入式数据库解决方案,通过.NET接口库提供了与.NET环境的良好集成。在轻量级数据管理和存储需求中,它是值得考虑的选择。
本文将详细介绍嵌入式数据库的概念、特点、常见类型以及如何在嵌入式系统中选择和应用这些数据库。 嵌入式数据库为嵌入式系统提供了一种高效的数据存储解决方案。它们具有轻量级、高性能和易于部署的特点,适用于...
Berkeley DB是一个嵌入式数据库,为应用程序提供可伸缩的、高性能的、有事务保护功能的数据管理服务。 主要特点: 嵌入式:直接链接到应用程序中,与应用程序运行于同样的地址空间中,因此,无论是在网络上不同...