热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

符合XOpen技术规范的UNIX版本自备了一个数据库dbm。它使用使用hash来保存非结构化数据,不支持SQL。它只是一个存储检索数据的例程。数据以keydata对的形式存储在文件中。

   符合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)中的接口:
   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)中的接口:
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)中的接口:
dbminit
store
fetch
delete
firstkey
nextkey
dbmclose

   下面程序的原型来自于<>,演示了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文档的语法这里不介绍。


推荐阅读
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
author-avatar
迷人的小刀
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有