php版简易中文分词实现 - mysql版本
在chinaunix看到“php版简易中文分词实现”,原来的版本使用的是gdbm文本数据库,在php5下面测试老是不通过。今天将字典数据导入mysql,小小改动就可以用了.我觉得,如果要获取更好的性能,可以考虑将所有的词写入一个数组,并且写入内存(如memcache),查询速度应该有很大提高,不过今天没有时间试验了。
在class db_dictionary{}下面几行加入:
PHP:
-
class db_dict extends db_dictionary {
-
-
var $_table = 'dict';
-
-
/** 加载词典 (参数: 词典路径) */
-
function load($fname) {
-
include_once('DB.php');
-
$this->_dbh = DB::connect($fname);
-
if (DB::isError($this->_dbh))
-
{
-
echo "fail to open the dictionary: $fname <br />" . CRLF;
-
die;
-
}
-
$res = $this->_dbh->query("SET NAMES 'gbk'"); //mysql 4.1以上要这行,否则注释掉
-
}
-
-
/** 查词 */
-
function find($word)
-
{
-
if (!DB::isError($this->_dbh))
-
{
-
$this->query_times++;
-
-
// check the cache
-
if ($this->has_cache && isset($this->_cache[$word]))
-
return $this->_cache[$word];
-
-
// query from db
-
$val = (int)$this->_dbh->getOne("SELECT `value`
-
FROM {$this->_table} WHERE `key`=?", array($word) );
-
-
// save to cache
-
if ($this->has_cache)
-
$this->_cache[$word] = $val;
-
-
return $val;
-
} else {
-
echo "you should load the dictionary file first! <br />" . CRLF;
-
die;
-
}
-
}
-
}
然后修改:
/** 分词类: 逆向最大 (2级复查词频比较) */
PHP:
-
class cword_segment {
-
.................................
-
-
/** 设定词典 (根据后缀名确定类型) */
-
function set_dict($fname)
-
{
-
$this->_dict = new db_dict($fname);
-
}
-
-
-
.................................
-
}
调用的时候:
PHP:
-
$wp->set_dict('mysql://root@localhost/test');
在win下php5.1.1 +apache 2.0.53测试通过,其中的include_once('DB.php');是调用的Pear::DB
作者: volcano 发表于12月 12, 2005 at 4:58 pm
netman 于 2006-02-16 @ 16:29:45 留言 :
能不能发一份例中的’DB.php’文件,谢谢。email:uteryod@163.com
volcano 于 2006-02-17 @ 21:16:57 留言 :
pear:DB在这里,要安装的
http://pear.php.net/package/DB
fufay 于 2006-03-27 @ 15:25:58 留言 :
能不能发一份导入MYSQL 的字典表格给俺?
volcano 于 2006-03-28 @ 10:03:29 留言 :
回去找了一下,原来的数据库因为重装已经找不着了,再想想别的办法
volcano 于 2006-03-28 @ 16:44:23 留言 :
找了一下,这是我当是导出sql的脚本,在php5下面跑的,如果你mysql版本在4.1或以上,用下面这段代码还要注意字符集的问题:
< ?php
ob_start();
$db = dba_open("dict.cdb", "r", "cdb");
if ($key = dba_firstkey($db))
{
do {
$value = dba_fetch($key, $db);
echo "INSERT INTO dict VALUES ('', '$key', '$value');rn";
}
while ($key = dba_nextkey($db));
}
dba_close($db);
file_put_contents('word.sql', ob_get_clean());
?>
fufay 于 2006-03-31 @ 13:46:04 留言 :
谢谢,我试试看。
citizen 于 2006-08-02 @ 16:01:19 留言 :
请给一份 DB.php, THKS
volcano 于 2006-08-02 @ 21:10:08 留言 :
请直接用pear的DB.php,我在上面已经回答过了。如果你不了解什么是pear,请搜索一下
bigandy 于 2006-08-21 @ 12:25:24 留言 :
关于使用数据库方面,我想,是否可以考虑采用MYSQL HEAP TABLE的方式,在程序第一次启动的时候,检测一下没有这个数据库,那么,就从任意一个cdb,gdbm 或者文本都行,读出字典文件,然后建立mysql的 heap table,这样只要机器不重启,这个table就一直存在,而且字典也就只是占了十几m的内存而已,mysql 的heap table应该是目前所有数据库类型中最快的一个了。
volcano 于 2006-08-21 @ 12:35:15 留言 :
你可以测试一下这样做的效率和资源占用情况,个人还是倾向于使用key->value形式的缓存如memcache之类的,会快的多。或者直接使用作者用c写的daemon,比php更是快上了一大截