首页 > 学技术 > 技术网文 > PHP > 正文

[原创] [成果来了] MySQL4.0.x/5.1.x FullText (全文检索) 中文支持


来源 chinaunix.net 酷勤网整理

计划临时网址: http://php.twomice.net/mysql_ft/
---------------------------------------------------------------------
这不光是 mysql 的事, 与 php 配合更是爽!! 做一个小规模搜索引擎将不再是烦恼!!

20060914: 发布为 mysql 5.1.x 定制的相应插件, 详见主页 :p

最新情况
【2006年09月09日】
针对 MyISAM fulltext (全文检索) 定制的带有词典分词能力及多字节字符支持(特别是中文)第一个版本发布. 

概述介绍
MySQL 从 3.23 的某个小版本开始就已经支持在 MyISAM 表中建立全文索引的列. 但一直不支持多字节字符集(如中文), 更不可能具备分词能力了. 经过对单字节字符集的试用, 感觉效果挺好. 凭借着兴趣及应用的需要, 加上之前发布的简易分词系统, 决定以 MySQL-4.0.26 为基础, 自己动手加入多字节字符集的检索与简易的词典分词. 在不影响MySQL的系统结构及其他功能的前提下, 解决MySQL目前对中文全文检索无法正确支持的缺陷并进而优化MySQL对中文检索处理的性能. 

关于什么是分词、何谓全文检索以及为什么要这样做, 请自行 Google 或借助其它资料先了解一下. 

由于时间和手头没有比较好的测试库, 临时组建了一个约 200MB , 7.6万行的数据表进行了简易测试. 建立 

顺便提一下, 有一个叫作海量的分词技术公司, 很早就做过 mysql-chinese 的 hack, 不过迟迟没有按照 GNU 精神及时发布源码, 所以才决定自己来作. 


安装使用

  0. 本软件包目前只支持从源码方式编译安装, 这里假定您已经拥有这方面的知识基础

  1. 从本地 下载 获取源码包, 格式为: mysql-4.0.6h**.tgz 
    wget http://php.twomice.net/mysql_ft/mysql-4.0.26h1.tgz 

  2. 解压编译安装: 
    tar xvzf mysql-4.0.26h1.tgz
    cd mysql-4.0.26h1/
    ./configure --prefix=/usr/local --with-charset=gb2312 --with-extra-charsets=all --enable-hightman-mbft
    make
    make install

  3. 拷入词库文件 (可自行定制, 格式参照源码目录下的: README.hightman_mbft 说明吧)
    cp -f support-files/wordlist-gbk.txt $PREFIX/share/mysql/
    cp -f support-files/stopwords-gbk.txt $PREFIX/share/mysql/
   
  4. 修改 /etc/my.cnf 在 [mysqld] 位置内加入: 

ft_wordlist_charset = gbk
ft_wordlist_file    = /home/soft/mysql/share/mysql/wordlist-gbk.txt
ft_stopword_file    = /home/soft/mysql/share/mysql/stopwords-gbk.txt
ft_min_word_len     = 2

  说明: ft_wordlist_charset 表示词典的字符集, 目前支持良好的有(UTF-8, gbk, gb2312, big5)
        ft_wordlist_file    是词表文件, 每行包括一个词及其词频(用若干制表符或空格分开,消岐专用)
        ft_stopword_file    表示过滤掉不索引的词表, 一行一个.
        ft_min_word_len     加入索引的词的最小长度, 缺省是 4, 为了支持中文单字故改为 2

  5. 重启 mysqld 服务器
    $PREFIX/share/mysql/mysql.server stop
    $PREFIX/share/mysql/mysql.server start

  6. 建表测试, 参见页面底部的测试命令或翻查 MySQL 手册吧.
  
本地下载
· [20060909] - 发布第一个版本, 内测完毕. 本地直接下载: mysql-4.0.26.h1.tgz (MD5: ffa39dfc9ab9cbff953035f2c084734 



前瞻计划
* 在 SELECT 句法中加入 SEGMENT(str) 函数返回切好的词 (空格隔开??) 
* 对于带有 MATCH() 从句或条件的 SELECT 句法可以使用 MATCH_POS() 返回第一次出现关键词的位置?? 
* 欢迎有兴趣的能人力士加入一起完善, 或计划提交给 mysql 总部?? (只是 mysql 发展太快了, 由于某些原因目前本人还在用 mysql 4.0) 



其它说明
本软件秉承GNU(通用公共许可证)精神释出, 旨在抛砖引玉, 互相学习促进. 
hack 部分的代码全部由本人(即 hightman)独立完成, 未经同意请勿修改代码包括但不限于商业应用、分支发布等. 本改进软件包不包含任何恶意代码, 由于本人水平及精力有限, Bug及错误之处在所难免, 由此升级修改引起的数据丢失等后果本人不承担任何责任. 
关于本软件的bug报告、疑问以及建议或改进优化代码请联系我. (MSN: [email]MingL_Mar@msn.com[/email] 或加 QQ群: 17708754) 

对源码有兴趣者请自行 grep 与 HAVE_HIGHTMAN_MBFT 相关的部分代码 主要集中在以下文件: 
  sql/mysqld.cc
  sql/set_var.cc
  include/ft_global.h
  myisam/ft_wordlist.c(新增) 
  myisam/ft_stopwords.c
  myisam/ft_parser.c
  myisam/ftdefs.h 
  myisam/ft_static.c
  
测试情况(略)

[ 本帖最后由 hightman 于 2006-9-14 11:17 编辑 ]



 bs 回复于:2006-09-09 14:05:26

关注中


 hightman 回复于:2006-09-09 14:45:38

希望有人帮助完善加入用 SELECT 句法的函数
SEGMENT(str) 和 MATCH_POS(), 这样就非常完整了. ^-^

MYSQL 的解析器到函数的映射看得有点晕,呵


 james.liu 回复于:2006-09-09 17:51:54

php+bridge+java+lucene做全文检索速度很快的。

不过你这个思路蛮好的,,不知道有没有架构图或者流程图,这样方便了解整个过程实现。



数据量加到50万吧。。7万感觉少了点。

关注。。。


 hightman 回复于:2006-09-09 18:45:56

1. 回楼上, Lucene 的确久经考验, 不过它运行在java环境, 不习惯也不会用 :p  而且好像也没有比较好的免费 java 版分词

   基于 mysql 的话, 使用相对要方便得多, 包括更新索引和维护.... 更主要的是假设一个 MyISAM 表支持 50万数据还比较理想的话, 通过简单的拆分设计就非常容易把总量做大...  对于中小型数据检索应该够用了.

2. 现在发布第二次修订版本, 增加函数 SEGMENT(str) 用于 select 句法中... 直接返回分好的语汇(空格分开)
    这样的改法有点偏离初衷, 因为改动了它的语法 :( 但没有想到更好的作法, 故暂时就这样了.

    原计划开发 MATCH_POS() 函数, 现已放弃, 只需配合 SEGMENT() + LOCATE() 很容易实现


mysql> SELECT SEGMENT("hello,你好我是一个中国人。英语叫chinese");
+----------------------------------------------------+
| segment("hello,你好我是一个中国人。英语叫chinese") |
+----------------------------------------------------+
| 你好 我是 一个 中国人 英语 叫 chinese            |
+----------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT title, SEGMENT(title) from articles limit 4,4;
+-------------------+-------------------+
| title             | SEGMENT(title)    |
+-------------------+-------------------+
| MySQL vs. YourSQL | MySQL YourSQL     |
| MySQL Security    | MySQL Security    |
| 中国测试          | 中国 测试         |
| 疯猜测中国测试    | 疯 猜测 中国 测试 |
+-------------------+-------------------+
4 rows in set (0.00 sec)


[ 本帖最后由 hightman 于 2006-9-9 19:13 编辑 ]


 yarco3 回复于:2006-09-09 18:58:43

8错...

8过...
1. 应用会不会太偏了点. 我是说, 这个分词方法是否也适用于其它国家的语言.(不然的话,除非mysql针对中文国家特别发布一个中文版本)
2. 是否mysql数据库的内部编码必须是gbk?


 hightman 回复于:2006-09-09 19:22:07

1. 支持是词典切词(正向最大,简单交叉消岐,避免和服之类的), 字符集自己注意匹配起来就可以了.
   也就是说你的MYSQL存放用的是 gb2312/gbk 那么分词用的词典也必须是 gb2312/gbk
   如果是 UTF-8, big5 亦然...

2. mysql数据库的 default-charset 没太多要求的, 是什么都行.... (mysql 4.1及其后续版本各表均包含有字符集信息, 可能有所不一样. 未试)

引用:原帖由 yarco3 于 2006-9-9 18:58 发表
8错...

8过...
1. 应用会不会太偏了点. 我是说, 这个分词方法是否也适用于其它国家的语言.(不然的话,除非mysql针对中文国家特别发布一个中文版本)
2. 是否mysql数据库的内部编码必须是gbk? 




 james.liu 回复于:2006-09-09 20:17:43

你数据表的数据哪儿来的?用户插入进来的还是后来另外做的专门针对全文检索的?

如果是前者,,那么插入速度和索引这两者你如何协调的呢?

如果是后者,我大概看了下,你可以参考下lucene的field这块定义,将检索和保存数据分开,,这样速度还会快。


 z33 回复于:2006-09-09 21:53:15

不错。
先支持一下,感谢hightman


 wuwei517200 回复于:2006-09-10 11:53:51

支持!


 ww_dragon 回复于:2006-09-11 13:21:30

我以前是海量的,祝贺你!

海量科技的确没有按照GNU发布,希望你能给大家提供一个更好版本。


 dualface 回复于:2006-09-11 13:45:20

NB啊!

说什么也要支持!我还准备以你的 PHP 版分词为基础,做一个简单的站内文章搜索引擎呢。


 hightman 回复于:2006-09-11 20:36:43

引用:原帖由 dualface 于 2006-9-11 13:45 发表
NB啊!

说什么也要支持!我还准备以你的 PHP 版分词为基础,做一个简单的站内文章搜索引擎呢。 



如果有条件自己安装 MySQL 的话又不需要 MYsql 5的新功能,那么用这个版本的MYSQL去取代它,将十分简单了


 dualface 回复于:2006-09-11 22:40:59

引用:原帖由 hightman 于 2006-9-11 20:36 发表


如果有条件自己安装 MySQL 的话又不需要 MYsql 5的新功能,那么用这个版本的MYSQL去取代它,将十分简单了 



但大多数情况下都是跑虚拟主机,没条件哦


 yarco3 回复于:2006-09-12 01:18:13

lightman, 有没有可能不需要安装mysql, 额外加个扩展/补丁就能用的?
虽然configure/install比较简单,不过大多数人应该不太愿意接触它,何况还有依赖关系.
或者
假如没太大平台/语言问题的话, 就如同你所说的提交到mysql.com去.
早加进去,可以早用这个功能也好.


 zhanglp888 回复于:2006-09-12 10:16:24

UTF-8可行吗?


 hightman 回复于:2006-09-12 18:23:23

引用:原帖由 zhanglp888 于 2006-9-12 10:16 发表
UTF-8可行吗? 



可行.


 hightman 回复于:2006-09-14 11:17:33

顶一下, 5.1.x 的插件也出来了


 yejr 回复于:2006-09-14 13:40:09

支持一下,如果你的分词算法或者分词词汇表是免费/开源的话,提交给mysql开发小组吧,让更多的中文用户享受fulltext


 rocklv 回复于:2006-09-15 10:26:44

分词词汇表更新频率怎么样啊,觉得这个挺重要,现在很多新词汇的


 foolkaka 回复于:2006-09-27 21:24:11

佩服!!
牛人啊~
我测试一下~
看看是否稳定 
目前正在使用lucene,数据量太大了~ 
最近也在用php搞亿级数据的解决方案~


 tonera 回复于:2006-09-28 17:23:20

那个分词还不错。曾起心加入一个算法计算每个词的"信息墒",以区分各词的价值。后来实在太忙,只能想想罢了。
不知道楼主是否有性能测试报告?


 qlks 回复于:2006-09-29 09:59:38

支持mysql 5.0吗?


 zqshuai 回复于:2006-12-19 10:34:54

支持




原文链接:http://bbs.chinaunix.net/viewthread.php?tid=825746
转载请注明作者名及原文出处



收藏本页到: