文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>GDBM/NDBM使用介绍

GDBM/NDBM使用介绍

时间:2010-09-22  来源:osdba

GDBM/NDBM使用介绍 

GDBM - GNU database manager,一套简单的资料库管理函数。 

gdbm 的常见版本是1.73 ,在大部份的FreeBSD, Linux 系统中皆已提供,若未提供, 
则可利用搜寻引擎寻找gdbm-1.7.3.tar.gz 或gdbm-1.8.0.tar.gz 并下载,利用 
configure 指令即可轻松安装。 

在安装时,可以选择是否一并安装dbm 及ndbm 的相容介面。 

dbm 是UNIX 上一套古老的常见资料库处理介面,而ndbm 则是改良dbm 缺失而设计的, 
两者的介面差异颇大。 

gdbm 则是根据ndbm 的介面设计的,两者间非常相似, ndbm 的函数名称皆以dbm_ 开头, 
而gdbm 为了加以区别,则以gdbm_ 开头,除此之外,皆可对应。 

gdbm 所提供的资料库管理介面,与ndbm 非常相似,因此gdbm 的说明,也可以适用于 
ndbm 上。 

可用两种方式判断有无安装 gdbm : 
1.查询有无 gdbm 的 manpage 
  $ man gdbm 
2.查询有无 gdbm 的 library 
  $ ls /usr/lib/libgdbm* 

gdbm 提供一套管理key/data 类型的资料库的函数,其特征是资料库中,每笔记录都有 
一个唯一的键值。 

这种key/data 格式的资料档案其实很常见,例如: 
-------------------------------------------- 
rock: 983-1231, [email protected] 
xyz: 931-4321, [email protected] 
-------------------------------------------- 
一个键值,一个记录内容。 

在使用gdbm 前,通常我们会用循序档来存放这类的资料,一笔一行或一区块,一
笔一笔的存下来,这样的好处是: 
1.修改方便 
  可以用一般的文字编辑工具增修资料,不用另行设计。 
2.节省空间 
  有多少资料就用多少空间,不像用struct 的随机档,不论资料量多少,所有 
  记录都占同样的空间。 

但其缺点有: 
1.管理不便 
  当记录数达数百、甚至数万笔时,继续用这种方式管理,可是件令人痛苦的事。 
2.使用负担大 
  资料搜寻费时,所有资料都必须从头开始找,在增修资料时也很费功夫,当资料 
  量大、使用率高时,会对系统造成负担。 

而gdbm 则是针对此缺点提出的一个解决方案,其利用hash 表存放键值,大幅节省 
搜寻时间,同时仍允许记录采用浮动长度,在时间及空间两者中取得平衡。 

其hash 表是用可扩充式hash 表演算法,会视需要自动扩充hash 表,不需担心 
hash 表的大小。 

gdbm 将资料库管理动作分成三个: 
1.storing 储存 
2.retrieval 撷取 
3.deletion 删除 

加上开启资料库及走访(visiting)的动作,提供七个主要的函数。 

再加上一个存放上述函数呼叫错误状态值的变数gdbm_errno 。 

其 prototype 如下: 
================================================= 
#include <gdbm.h> 

typedef struct { 
        char *dptr; 
        int dsize; 
} datum; 

extern gdbm_error gdbm_errno; 

GDBM_FILE gdbm_open (name, block_size, read_write, mode, fatal_func); 
char * name; 
int block_size, read_write, mode; 
void (*fatal_func) (); 

void gdbm_close (dbf); 
GDBM_FILE dbf; 

int gdbm_store (dbf, key, content, flag); 
GDBM_FILE dbf; 
datum key, content; 
int flag; 

datum gdbm_fetch (dbf, key); 
GDBM_FILE dbf; 
datum key; 

int gdbm_delete (dbf, key); 
GDBM_FILE dbf; 
datum key; 

datum gdbm_firstkey (dbf); 
GDBM_FILE dbf; 

datum gdbm_nextkey (dbf, key); 
GDBM_FILE dbf; 
datum key; 
================================================= 

datum 是用来表示记录键值及记录内容的structure 。 

1.gdbm_open() 
  开启资料库。 

  gdbm 将开启者分成reader 及writer ,在同一时间内可以有多个reader , 
  但一次只能有一个 writer 。当指定的资料库有reader 在使用时,其他人就无 
  法成为writer ,当有writer 在使用时,其他人就无法成为reader 或writer。 

  GDBM_FILE 是传回给开启者的 handle 值。 

  name 是资料库的档案名称,此档案是完整的, gdbm 不会添加其他字眼上去。 
  而gdbm 也就只会建立这一个资料库档案,不会另外再建索引档或关连档。 

  block_size 在建立资料库时指定,指示gdbm 以多大的记忆体区块来读写磁碟资 
  料,此值最小是512 (bytes) ,但不妨指定0 ,由gdbm 自行根据档案系统的状 
  态决定。 

  read_write 在指示开启者的开启型式,可指定的有四: 
  GDBM_READER 成为 reader 
  GDBM_WRITER 成为 writer 
  GDBM_WRCREAT 成为writer ,若资料库不存在则建立之 
  GDBM_NEWDB 成为writer ,并建立新的资料库,不论是否存在旧资料库 

  若欲成为writer ,则可以再附带一个设定值GDBM_FAST ,指示gdbm 在写入资 
  料时,不要马上进行与磁碟内容的同步化动作。 
  此行为在 gdbm 1.8 后,为预设动作。 

  mode 在指示建立资料库时,档案的属性,其意义同chmod() 。 
  一般设为0644 (rw-r--r--),若没有建立资料库的动作,则指定0 即可。 

  Fatal_func 为函数指标,当开启资料库,发现一个错误时,就呼叫该函数, 
  一般皆设为NULL ,由gdbm 自行以预设动作处理。 

  当gdbm 无法成为reader 或writer 时,会立即返回,而不会自动搁置, 
  此时gdbm_open() 传回NULL ,可由gdbm_errno 得知错误状态码。 

  范例: 
  --------------------------------------- 
  GDBM_FILE dbf; 
  dbf = gdbm_open("mydata.db", 0, GDBM_READER, 0, NULL); 
  if( dbf == NULL ) { 
    printf("Can not open database\n, %s\n", gdbm_strerror(gdbm_errno) ); 
  } 
  --------------------------------------- 


2.gdbm_close() 
  关闭资料库,不会有错误传回。 

  范例: 
  --------------------------------------- 
  gdbm_close(dbf); 
  --------------------------------------- 

3.gdbm_store() 
  储存记录。 

  将记录键值及记录内容存入资料库中,存入动作分为增加及替代,在flag 中指定, 
  其值有二: 
  GDBM_INSERT 增加一笔新记录,若键值已存在,则储存动作失败。 
  GDBM_REPLACE 替代记录内容。 

  其传回值有三: 
  -1 无法储存。 
  0 储存成功。 
  1 当使用GDBM_INSERT 时,键值已存在,无法储存。 

  范例: 
  --------------------------------------- 
  char keybuf[256], databuf[256]; 
  datum key, data; 

  gets(keybuf); 
  gets(databuf); 

  key.dptr = keybuf; key.dsize = strlen(keybuf); 
  data.dptr = databuf; data.dsize = strlen(databuf); 

  rc = gdbm_store(dbf, key, data, GDBM_INSERT); 
  if( rc != 0 ) { 
    printf("Can not store record\n, %s\n", gdbm_strerror(gdbm_errno) ); 
  } 
  --------------------------------------- 

  注意,这里示范的是资料键值及内容都是一般文字,如果键值及内容中,包 
  含'\0' 时,就不能用strlen() 去计算size 了。 

4.gdbm_fetch() 
  根据指定键值撷取记录。 

  传回记录的内容,要注意的是,记录内容的空间是由gdbm 以malloc() 配置的, 
  但gdbm 不会自动释放,故当你不再使用该资料时,记得将其释放。 

  若记录内容指向 NULL ,表无此记录。 

  范例: 
  --------------------------------------- 
  char keybuf[256]; 
  datum key, data; 

  gets(keybuf); 
  key.dptr = keybuf; key.dsize = strlen(keybuf); 

  data = gdbm_fetch(dbf, key); 
  if( data.dptr == NULL ) { 
    puts("Record not found!\n"); 
  } 
  else { 
    printf("Record found (%d): %s", data.dsize, data.dptr); 
    free(data.dptr); 
  } 
  --------------------------------------- 

  若你只是单纯地想查询键值是否已存在于资料库,而不想撷取资料内容时,可以使 
  用gdbm_exists(dbf, key) ,其传回非零值(true)时,表示键值存在。 

5.gdbm_delete() 
  根据指定键值移除记录。 

  传回0 表示成功删除, -1 表示删除失败。 

  范例: 
  --------------------------------------- 
  char keybuf[256]; 
  datum key; 

  gets(keybuf); 
  key.dptr = keybuf; key.dsize = strlen(keybuf); 

  rc = gdbm_delete(dbf, key); 
  if( rc != 0 ) 
    printf("Record can not delete.\n %s", gdbm_strerror(gdbm_errno)); 
  --------------------------------------- 

6.gdbm_firstkey() / gdbm_nextkey() 
  走访资料库。 

  根据hash 表走访资料库,由于其并非根据资料存入顺序或键值的排序走访,因此
  走访结果并无次序,但可以保证的是,每笔记录都会被走访一次,不会遗漏。 

  key.dptr 是由gdbm 以malloc() 配置的,但gdbm 不会自动释放,故当你走访完 
  毕时,记得将其释放。 

  当key.dptr 指向NULL 时,表示走访完毕。 

  注意,当你在走访资料库时,不要增加或删除任何记录,因为这将改变hash 表的
  内容,造成其走访时的遗漏。 

  范例: 
  --------------------------------------- 
  datum key, nextkey; 
  int n = 1; 

  puts("Key list:\n"); 
  key = gdbm_firstkey(dbf); 
  while( key.dptr != NULL ) { 
    printf("%d: %s", n, key.dptr); 
    n++; 
    nextkey = gdbm_nextkey(dbf, key); 
    free(key.dptr); 
    key = nextkey; 
  } 
  --------------------------------------- 

7.gdbm_reorganize() 
  重整资料库。 

  这个函数使用时,请再三斟酌,不要常使用。 

  随着资料库的增删,时间一久,资料库中,就会留下许多未被使用的空隙,此时可 
  呼叫gdbm_reorganize(dbf) 进行资料库的重整,去除那些空隙,适度缩减资料库 
  档案的大小。 

  除非呼叫gdbm_reorganize() ,否则gdbm 不会缩减资料库档案的长度,但是gdbm 
  也不是一直往后增加资料,当旧有资料被删除时, gdbm 会尽然重复使用那些空下来 
  的空间。 

附注: 

1.参考文件 GDBM(3), gdbm.h 
  详细说明请参阅此 manpage 。 
  $ man gdbm 

2.在本文中,一共提到了十个gdbm 函数及一个gdbm 变数: 
  gdbm_open() 
  gdbm_close() 
  gdbm_store() 
  gdbm_fetch() 
  gdbm_delete() 
  gdbm_firstkey() 
  gdbm_nextkey() 
  gdbm_exists() 
  gdbm_reorganize() 
  gdbm_strerror() 
  gdbm_errno 

  reader 无法使用gdbm_store(), gdbm_delete() 及gdbm_reorganize() 。
相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载