热门标签 | 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文档的语法这里不介绍。


推荐阅读
  • 问题描述现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能;在实际开发过程中 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • 本文探讨了如何在PHP与MySQL环境中实现高效的分页查询,包括基本的分页实现、性能优化技巧以及高级的分页策略。 ... [详细]
  • 如何将955万数据表的17秒SQL查询优化至300毫秒
    本文详细介绍了通过优化SQL查询策略,成功将一张包含955万条记录的财务流水表的查询时间从17秒缩短至300毫秒的方法。文章不仅提供了具体的SQL优化技巧,还深入探讨了背后的数据库原理。 ... [详细]
  • 本文探讨了如何在 Spring MVC 框架下,通过自定义注解和拦截器机制来实现细粒度的权限管理功能。 ... [详细]
  • 本文探讨了使用普通生成函数和指数生成函数解决组合与排列问题的方法,特别是在处理特定路径计数问题时的应用。文章通过详细分析和代码实现,展示了如何高效地计算在给定条件下不相邻相同元素的排列数量。 ... [详细]
  • OpenCV中的霍夫圆检测技术解析
    本文详细介绍了如何使用OpenCV库中的HoughCircles函数实现霍夫圆检测,并提供了具体的代码示例及参数解释。 ... [详细]
  • 网络流24题——试题库问题
    题目描述:假设一个试题库中有n道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取m道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷算 ... [详细]
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 入门指南:使用FastRPC技术连接Qualcomm Hexagon DSP
    本文旨在为初学者提供关于如何使用FastRPC技术连接Qualcomm Hexagon DSP的基础知识。FastRPC技术允许开发者在本地客户端实现远程调用,从而简化Hexagon DSP的开发和调试过程。 ... [详细]
  • 在OpenCV 3.1.0中实现SIFT与SURF特征检测
    本文介绍如何在OpenCV 3.1.0版本中通过Python 2.7环境使用SIFT和SURF算法进行图像特征点检测。由于这些高级功能在OpenCV 3.0.0及更高版本中被移至额外的contrib模块,因此需要特别处理才能正常使用。 ... [详细]
  • 本文探讨了如何通过Service Locator模式来简化和优化在B/S架构中的服务命名访问,特别是对于需要频繁访问的服务,如JNDI和XMLNS。该模式通过缓存机制减少了重复查找的成本,并提供了对多种服务的统一访问接口。 ... [详细]
  • 如何在PHP中安装Xdebug扩展
    本文介绍了如何从PECL下载并编译安装Xdebug扩展,以及如何配置PHP和PHPStorm以启用调试功能。 ... [详细]
  • 接下来要动手来做一个组件了,我想了一个计数器组件,功能方面是比较简单的,但这不是本章的重点,这一章的重点是说明一个组件的制作全过程。在其中可以学到很多组件制作的技巧,当然这些也是我从书上学得的。 ... [详细]
  • fzu 1715 Ball and Box n个不同的求放到m个不同的盒子中方法的个数
    1715BallandBoxAccept:120Submit:288TimeLimit:1000mSecMemoryLimit:32768KBProblem ... [详细]
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社区 版权所有