现在的位置: 首页 > 综合 > 正文

dbm数据库源代码分析(1):概述

2013年01月16日 ⁄ 综合 ⁄ 共 5970字 ⁄ 字号 评论关闭

   符合X/Open技术规范的UNIX版本自备了一个数据库dbm。它使用使用hash来保存非结构化数据,不支持SQL。它只是一个存储检索数据的例程。数据以key/data对的形式存储在文件中。规范中允许把关键字/数据对的长度限制为1023个字节,但通常实现时不限制。关键字的取值被用作存储数据的索引。dbm被X/Open组织标准化为ndbm。GNU的dbm实现为gdbm(GNU dbm的缩写),它本身的接口实现与旧版本不同,但它同时也提供了旧版本的dbm和ndbm实现,因此gdbm兼容dbm和ndbm。dbm、gdbm适合存储静态的,索引化的数据结构。适用于处理那些被频繁访问但却很少被更新的数据,因为它创建数据项时非常慢,但检索数据项时非常快。
   Ubuntu 8.04中,gdbm的库文件libgdbm.so,及其兼容dbm和ndbm的库文件libgdbm_compat.so都已安装在/usr/lib下,头文件在/usr/include下,其中gdbm.h用于gdbm,gdbm-ndbm.h用于gdbm或ndbm,dbm.h用于dbm(其实对原始编译的版本,ndbm的头文件应该是ndbm.h)。开发帮助文档libgdbm-dev默认没有安装,可到新立得软件包管理器中去安装。其他类型的系统中若没有安装的话,到gnu官网去下载安装,地址为ftp://ftp.gnu.org/gnu/,下载的软件包为gdbm-1.8.3.tar.gz。使用gdbm写程序时,编译程序要用-l选项加载相应的库文件(libgdbm.so或libgdbm_compat.so),头文件在/usr/include下能自动搜索到,如果不是安装在这个目录下,则要用-I选项给出头文件所在的目录。
   gdbm的索引(key)和数据块(data)均被封装为一个datum结构体。
typedef struct {
    char *dptr; /* 指向数据的起点 */
    int dsize;  /* 数据的长度 */
}datum;
   ndbm中操作数据库的结构为DBM结构体(相当于文件操作中的FILE,dbm中为int型文件描述符,gdbm中为GDBM_FILE结构),当我们打开一个dbm数据库时,将创建用两个数据文件,扩展名为”.pag”和”.dir”,但只返回一个DBM结构的指针,通过这个指针来操作这两个文件。注意不要使用读写函数直接操作数据文件,应该使用dbm提供的数据操作函数访问数据。在gdbm中则所有实现都只使用一个数据文件。注意也不要使用读写函数直接操作这个数据文件,应该使用gdbm提供的数据操作函数访问数据。dbm对数据的内部结构没有要求(不像SQL数据库中的表格),它操作的只是非结构化的二进制数据块。
   下面给出ndbm、dbm、gdbm的接口概述,并通过一个例子来说明其使用(以ndbm为例)。
   (2)<ndbm.h>中的接口:
   DBM *dbm_open(const char *name,int flags,int mode):打开一个已有的数据库文件name,不存在时创建。打开标志flags和打开模式mode与open函数相同。返回DBM结构的指针。
   void dbm_close(DBM *file):关闭打开的数据库。
   datum dbm_fetch(DBM *file,datum key):根据关键字key检索数据。
   int dbm_store(DBM *file,datum key,datum content,int flags):向数据库中存入数据,flags有DBM_INSERT或DBM_REPLACE。成功时返回0。
   int dbm_delete(file,key):删除数据.
   datum dbm_firstkey(file):返回数据库中的第一个关键字。
   datum dbm_nextkey(file):获取下一个关键字,一般与dbm_firstkey一起实现对数据库中所有关键字的扫描。
   int dbm_error(file):测试数据库中是否有错,没有就返回0。
   int dbm_clearerr(file):清除数据库中所有已被置位的错误标志。
   int dbm_pagfno(file):返回.pag文件的描述符,现在只有一个文件,故返回这个唯一的文件的描述符。
   int dbm_dirinfo(file):返回.dir文件的描述符,现在只有一个文件,故返回这个唯一的文件的描述符。
   int dbm_rdonly(file):查看数据库文件是不是以只读方式打开的。不常用的一个函数,主要是为了向后兼容。
   (2)<gdbm.h>中的接口:
extern gdbm_error gdbm_erro:存放操作时的错误码。
extern char *gdbm_version:存放版本信息。
gdbm_open
gdbm_close
gdbm_store
gdbm_fetch
gdbm_delete
gdbm_firstkey
gdbm_nextkey
gdbm_reorganize
gdbm_sync
gdbm_exists
gdbm_strerror
gdbm_setopt
gdbm_fdesc
   (3)<dbm.h>中的接口:
dbminit
store
fetch
delete
firstkey
nextkey
dbmclose

   下面程序的原型来自于<<Linux程序设计(第3版)>>,演示了ndbm接口的使用。

   执行结果:

   GNU dbm由西华盛顿大学的Philip A. Nelson等人开发,目前的版本为1.8.3。项目不大,整个gdbm-1.8.3.tar.gz包才223.3KB,解压后的整个源代码(包括构建性文件件)也只有904.7KB,共68个文件(用./configure配置项目后会变成73个文件)。除去项目的构建性文件,源代码文件的数目就更少了。所谓麻雀虽小,五脏倶全。因此,gdbm项目非常适合用来学习,对其源代码进行解剖和研究。
   gdbm的源代码树中没有子目录,所有的文件都放在一个目录中。整个项目的文件如下。
   (1)构建性文件:共15个文件。
configure.in:由autoscan生成的文件修改而来
aclocal.m4:由aclocal生成
autoconf.in.h:由autoheader生成
configure:由autoconf生成
config.guess、config.sub、ltmain.sh:由automake生成(调用了libtoolize)
COPYING、INSTALL、install-sh:由automake(-a)生成(项目中没有missing、depcomp)
Makefile.in:由automake生成
mkinstalldirs:一般开发者自己编写
NEWS、README、ChangeLog:由开发者自己编写(项目中没有AUTHORS)
   注意:当使用./configure脚本配置项目后,还会再生成4个构建性文件config.status、config.log、libtool、Makefile,以及1个头文件autoconf.h,这时总共有19个构建性文件。
   (2)头文件:共12个文件。autoconf.h、dbm.h、extern.h、gdbmconst.h、gdbmdefs.h、gdbmerrno.h、getopt.h、ndbm.h、proto.h、systems.h、gdbm.proto、gdm.proto2。
   (3)源代码文件:共39个文件。包括ndbm、dbm、gdbm三大部分,以及三个测试程序文件和一个dbm转换程序文件。
   (4)gdbm文档方面的文件:共3个文件。gdbm.3为纯文本文件、gdbm.info为八进制的流文件(可以用cat或od -c来查看其内容)、gdbm.texinfo为Texinfo文档。
   附:Texinfo介绍
   Texinfo是一个文档系统,它通过单个源文件同时生成在线信息文档和可打印的输出。也就是说,这两种类型的文档,你只需要写一份文档就行了。使用Texinfo创建的可打印的文档包括一本书的所有普通特征,如章、节、交叉引用和索引。通过一份Texinfo源文件,可以创建一份Info文件,一份HTML文档及一份XML文件。Texinfo源文件是普通的ASCII文件,它包含交互的@命令文本。你可以用任何文本编辑器编辑它,但GNU Emacs编辑器会更方便一些,因为它有一个Texinfo模式,提供了许多Texinfo相关特性。
   Textinfo支持的输出格式有info文件(通过makeinfo生成)、普通文本(通过makeinfo --no-headers生成)、HTML(通过makeinfo --html生成)、DVI(通过texi2dvi生成)、PDF(通过texi2dvi --pdf或者texi2pdf生成)、XML(通过makeinfo --xml生成)、Docbook(通过makeinfo --docbook)。
   由于Texinfo对本项目的解剖并无影响。因此Texinfo文档的语法这里不介绍。

抱歉!评论已关闭.