免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5522 | 回复: 16
打印 上一主题 下一主题

[代码] 纯php编写的类gdbm/cdb数据库引擎 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-05-08 14:19 |只看该作者 |倒序浏览
下载地址:http://www.hi-php.com/hdb-0.1.zip  (内带测试程序及说明)

   PHP4代码版HDB - (HashTreeDB.class.php)
   -----------------------------------------------------------------------
   作者: 马明练(hightman) (MSN: MingL_Mar@msn.com) (php-QQ群: 17708754)
   网站: http://www.hi-php.com
   时间: 2007/05/01 (update: 2007/05/08)
   版本: 0.1
   目的: 取代 cdb/gdbm 快速存取分词词典, 因大部分用户缺少这些基础配件和知识
   功能:
         这是一个类似于 cdb/gdbm 的 PHP 代码级数据类库, 通过 key, value 的方
         式存取数据, 使用非常简单.

         适用于快速根据唯一主键查找数据

   效能:
         1. 效率高(20万记录以上比php内建的cdb还要快), 经过优化后 35万记录时
            树的最大深度为5, 查找效率高,单个文件
         2. 文件小(缺省设置下, 基础数据约 100KB, 之后每条记录为 key, value的
            总长度+13bytes
         3. 无系统依赖, 跨操作系统, 不受 little endian 和 big endian 影响
         4. PHP 代码级, 修改维护方便
         5. 提供内建二叉树优化函数, 提供存取结构图绘制接口, 提供遍历接口
         6. 数据可快速更新, 而 cdb 是只读的或只写的

   缺点:
         1. 对于unique key来说, 一经增加不可清除 (可以将value设为空值)
         2. 当更新 value 时, 如果新 value 较长则旧的记录直接作废, 长期修改
            可能会导致文件有一些无用的膨胀, 这类情况可以调用遍历接口完全重
            建整个数据库
         3. 由于是 php 代码级的引擎, 性能上比 gdbm 没有什么优势
         4. IO操作, 可以考虑将数据文件放到 memfs 上 (linux/bsd)
         5. key 最大长度为 240bytes, value 最大长度为 65279 bytes, 整个文件最大为 4G
         6. 不可排序和随机分页读取

   用法: (主要的方法)

   1. 建立类操作句柄, 构造函数: HashTreeDB([int mask [, int base ]])
      可选参数(仅针对新建数据有效): mask, base 均为整型数, 其中
        mask 是 hash 求模的基数, 建议选一个质数, 大约为总记录数的 1/10 即可.
        base 是 hash 数据计算的基数, 建议使用默认值. ``h = ((h << 5) + h) ^ c''

      $HDB = new HashTreeDB;

   2. 打开数据文件, Bool Open(string fpath [, string mode])
      必要参数 fpath 为数据文件的路径, 可选参数 mode 的值为 r 或 w, 分别表示只
      读或读写方式打开数据库. 成功返回 true, 失败返回 false.

      缺省情况下是以只读方式打开, 即 mode 的缺省值为 'r'
      $HDB->Open('/path/to/dict.hdb');

      或以读写方式打开(新建数据时必须), mode 值为 'w', 此时数据库可读可写
      $HDB->Open('/path/to/dict.hdb', 'w');

   3. 根据 key 读取数据 mixed Get(string key [, bool verbose])
      成功查找到 key 所对应的数据时返回数据内容, 类型为 string
      当 key 不存在于数据库中时或产生错误直接返回 false
      (*注* 当 verbose 被设为 true 时, 则返回一个完整的记录数组, 含 key&value, 仅用于调试目的)

      $value = $HDB->Get($key);
      或
      $debug = $HDB->Get($key, true); print_r($debug);

   4. 存入数据 bool Put(string key [, string value])
      成功返回 true, 失败或出错返回 false , 必须以读写方式打开才可调用
      注意存入的数据目前只支持 string 类型, 有特殊需要可以使用 php 内建的 serialize 将 array 转换
      成 string 取出时再用 unserialize() 还原

      $result = $HDB->Put($key, $value);

   5. 关闭数据库, void Close()
      $HDB->Close();

   6. 查询文件版本号, string Version()
      返回类似 HDB/0.1 之类的格式, 是当前文件的版本号

   7. 记录遍历, mixed Next()
      返回一条记录key, value 组成的数组, 并将内部指针往后移一位, 可调用 Reset() 重置指针
      当没有记录时会返回 false, 典型应用如下

      $HDB->Reset();
      while ($tmp = $HDB->Next())
      {
          echo "$tmp[key] => $tmp[value]\n";
      }
      也可用于导出数据库重建新的数据库, 以清理过多的重写导致的文件空档.

   8. 遍历指针复位, void Reset()
      此函数仅为搭配 Next() 使用
      $HDB->Reset();

   9. 优化数据库, 将数据库中的 btree 转换成完全二叉树. void Optimize([int index])
      由于数据库针对 key 进行 hash 分散到 mask 颗二叉树中, 故这里的 index 为 0~[mask-1]
      缺省情况下 index 值为 -1 会优化整个数据库, 必须以读写方式打开的数据库才能用该方法

      $HDB->Optimize();

  10. 打印分析树, 绘出存贮结构的树状图, void Draw([int index])
      参数 index 同 Optimize() 的参数, 本函数无返回值, 直接将结果 echo 出来, 仅用于调试和观看
      分析

      $HDB->Draw(0);
      $HDB->Draw(1);
      ...

hdb-0.1.zip

7.92 KB, 下载次数: 226

论坛徽章:
0
2 [报告]
发表于 2007-05-08 14:21 |只看该作者
该功能起初写的是为了替代一些不懂或无法支持 cdb 数据库的分词爱好者

所以寻求了一个简单可靠快速的替代方案,目前版本号为 0.1 ,实测 36 万条数据,最大树深 5层,平均 3~4u次 fread 即可,实际操作时间,即 $HDB->Get() 前后时间差均为 0.0003 或更小级别

论坛徽章:
0
3 [报告]
发表于 2007-05-08 14:24 |只看该作者
好东东,,支持一下..正在测试当中

论坛徽章:
0
4 [报告]
发表于 2007-05-08 16:19 |只看该作者
居然把email写出来,这不是作死嘛。。。

论坛徽章:
0
5 [报告]
发表于 2007-05-08 16:21 |只看该作者
我发现平衡二叉树做这种大数据量的特别合适,搜索,插入,修改都非常快

论坛徽章:
0
6 [报告]
发表于 2007-05-10 11:44 |只看该作者
标题不好理解,就是一个功能强大的文本数据库类吧?

论坛徽章:
0
7 [报告]
发表于 2007-05-10 14:57 |只看该作者
原帖由 wobushiwo 于 2007-5-8 16:21 发表
我发现平衡二叉树做这种大数据量的特别合适,搜索,插入,修改都非常快


http://www.phpbtree.com/ 这个怎样?

论坛徽章:
0
8 [报告]
发表于 2007-05-10 14:58 |只看该作者
这个 效率怎样 和直接用btree比较

[ 本帖最后由 eye_onme 于 2007-5-10 14:59 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2007-05-11 03:36 |只看该作者
测试例子错了,应该是5位数字

论坛徽章:
0
10 [报告]
发表于 2007-05-11 05:00 |只看该作者
把hbd加入到你的php4_scws_full_060620中,并把dict.cdb(12MB)转换成dict.hdb(9MB),粗略测试后,分词速度比用cdb的慢了一半左右。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP