返回   青蛙论坛 » IT论坛 » 操作系统类
用户名
密码
帮助 会员 日历 标记论坛为已读

回复
 
主题工具 显示模式
旧 01-09-2007, 17:59   #1
chyangwa
蝌蚪-小毛驴
 
chyangwa的头像
 
注册日期: Nov 2000
来自: 上海
帖子: 8,285
精华: 6
支持中文全文索引的MYSQL

支持中文全文索引的MYSQL

http://ckasj.vicp.net/blog/?p=87

24 9月 2006

mysql 从3.23版本就支持全文索引,可是直到迟迟没有对多字节的全文索引支持。国内的一个叫海量的公司对mysql源码进行修改提供了对中文全文索引和划词搜索的功能的支持。可是该公司并不按照MYSLQ遵循的GNU GPL版权协议发布,不要说开放源码了,就是最基本的二进制版本也不能没有限制的使用,实在让人很气恼。几天前再网上偶然发现了有人实现了对mysql4.0版本的中文全文索引的支持,并且以GPL版权发布。高兴之余准备安装体验一下,在此对hightman所做的这一切表示感谢!


下载并安装最新版本
—————–

下载最新的版本到http://myft.twomice.net这个网址,目前最新版本是mysql-4.0.27-hi4。和普通情况下编译安装mysql并没有很大区别,解压mysql-4.0.27-hi4.tgz并按照以下步骤进行安装。(这里我只简单的写一下安装步骤,更详细的内容请参照站长提供的安装说明)

1.安装并编译

tar xvzf mysql-4.0.27-hi4.tgz
cd mysql-4.0.27-hi4/
./configure –prefix=/usr/local/mysql40 –with-charset=gb2312 –with-extra-charsets=all –enable-hightman-mbft
make
make install
cp support-files/my-medium.cnf /etc/my.cnf
cp -f support-files/wordlist-gbk.txt /usr/local/mysql40/share/mysql/
cp -f support-files/stopwords-gbk.txt /usr/local/mysql40/share/mysql/
cd /usr/local/mysql40
groupadd mysql
useradd -g mysql mysql
bin/mysql_install_db –user=mysql
chown -R root .
chown -R mysql var
chgrp -R mysql .

2.配置my.cnf
编辑my.cnf ,在[mysqld]节加入以下配置信息

#add full text index suppost with gbk
ft_wordlist_charset = gbk
ft_wordlist_file = /usr/local/mysql40/share/mysql/wordlist-gbk.txt
ft_stopword_file = /usr/local/mysql40/share/mysql/stopwords-gbk.txt
ft_min_word_len = 2
ft_nlq_match_percent = 80
ft_nlq_match_maxnum = 5000

3.启动mysql

cd /usr/local/mysql40
bin/mysqld_safe –user=mysql &

功能测试
———

1.创建一个用来测试的表格,并在title和content两个字段添加全文索引

CREATE TABLE `test_ft` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(60) NOT NULL default ‘’,
`content` varchar(255) NOT NULL default ‘’,
PRIMARY KEY (`id`),
FULLTEXT KEY `title` (`title`,`content`)
)

查看test_ft表的结构

mysql> use test;
Database changed
mysql> desc test_ft;

+———+————–+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+———+————–+——+—–+———+—————-+
| id | int(11) | | PRI | NULL | auto_increment |
| title |varchar(60) | | MUL| | |
| content |varchar(255) | | | | |
+———+————–+——+—–+———+—————-+
3 rows in set (0.00 sec)

2.插入一些测试记录进行测试

INSERT INTO `test_ft` VALUES (1, ‘测试中文全文索引’, ‘我可以通过标题和内容索引到我想要的内容。’);
INSERT INTO `test_ft` VALUES (2, ‘中文,english’, ‘中英文混和全文索引测试’);
INSERT INTO `test_ft` VALUES (3, ‘测试对数字的索引’, ‘123456这个数字’);
INSERT INTO `test_ft` VALUES (4, ‘两个字段都能匹配’, ‘两个字段都能匹配’);
INSERT INTO `test_ft` VALUES (5, ‘测试全文索引’, ‘只有一个匹配’);

3.基本功能的测试

1)通过一些中文字的组合索引到我想要的内容,我使用’文索’两个没有意义的单字作为键搜索,id号为1的记录命中。

mysql> use test;
Database changed
mysql> SELECT id,MATCH (title, content)AGAINST (’文索’) FROM `test_ft`;
+—-+—————————————-+
| id | MATCH (title, content)AGAINST (’文索’) |
+—-+—————————————-+
| 1 | 1.1516622304916 |
| 2 | 0 |
| 3 | 0 |
| 4 | 0 |
| 5 | 0 |
+—-+—————————————-+
5 rows in set (0.00 sec)

2)通过正常的中文词汇索引,这一次我仍然希望1号记录命中。使用’标题’这个关键字进行搜索,结果如愿以偿。

mysql> SELECT id,MATCH (title, content)AGAINST (’标题’) FROM `test_ft`;
+—-+—————————————-+
| id | MATCH (title, content)AGAINST (’标题’) |
+—-+—————————————-+
| 1 | 1.1516622304916 |
| 2 | 0 |
| 3 | 0 |
| 4 | 0 |
| 5 | 0 |
+—-+—————————————-+
5 rows in set (0.00 sec)

3)测试中英文混和记录的搜索 ,我使用单词english进行搜索,2号记录命中

mysql> SELECT id,MATCH (title, content)AGAINST (’english’) FROM `test_ft`;
+—-+——————————————-+
| id | MATCH (title, content)AGAINST (’english’) |
+—-+——————————————-+
| 1 | 0 |
| 2 | 1.2830119132996 |
| 3 | 0 |
| 4 | 0 |
| 5 | 0 |
+—-+——————————————-+
5 rows in set (0.00 sec)

3)测试对数字的匹配。对数字的匹配是精确匹配的,我以关键字123456进行搜索3号记录被命中

mysql> SELECT id,MATCH (title, content)AGAINST (’123456′) FROM `test_ft`;
+—-+——————————————+
| id | MATCH (title, content)AGAINST (’123456′) |
+—-+——————————————+
| 1 | 0 |
| 2 | 0 |
| 3 | 1.1625151634216 |
| 4 | 0 |
| 5 | 0 |
+—-+——————————————+
5 rows in set (0.00 sec)

4)如果关键字被多条记录匹配,关键字出现的频率决定该记录的相似度。我使用’匹配’作为关键字搜索,4号记录和5号记录都命中,但是4号记录的相似度更高。

mysql> SELECT id,MATCH (title, content)AGAINST (’匹配’) FROM `test_ft`;
+—-+—————————————-+
| id | MATCH (title, content)AGAINST (’匹配’) |
+—-+—————————————-+
| 1 | 0 |
| 2 | 0 |
| 3 | 0 |
| 4 | 0.3876339495182 |
| 5 | 0.37130504846573 |
+—-+—————————————-+
5 rows in set (0.00 sec)

5) 逻辑匹配模式测试。 我使用’匹配 +字段’作为关键字使用逻辑模式搜索即包含’匹配’又包含’字段’的记录,4号记录命中,而使用’匹配 -字段’作为关键字使用逻辑搜索包含’匹配’但不包含’字段’的记录5号记录匹配。

‘匹配 +字段’作为关键字

mysql> SELECT id,MATCH (title, content)AGAINST (’匹配 +字段’ IN BOOLEAN MODE) FROM `test_ft`;
+—-+————————————————————–+
| id | MATCH (title, content)AGAINST (’匹配 +字段’ IN BOOLEAN MODE) |
+—-+————————————————————–+
| 1 | 0 |
| 2 | 0 |
| 3 | 0 |
| 4 | 1.3333333730698 |
| 5 | 0 |
+—-+————————————————————–+
6 rows in set (0.01 sec)

‘匹配 -字段’ 作为关键字

mysql> SELECT id,MATCH (title, content)AGAINST (’匹配 -字段’ IN BOOLEAN MODE) FROM `test_ft`;
+—-+————————————————————–+
| id | MATCH (title, content)AGAINST (’匹配 -字段’ IN BOOLEAN MODE) |
+—-+————————————————————–+
| 1 | 0 |
| 2 | 0 |
| 3 | 0 |
| 4 | 0 |
| 5 | 1 |
+—-+————————————————————–+
6 rows in set (0.01 sec)

4. 测试分词功能 。通过SEGMENT(”字符串”)。测试对字符串的分词功能。分词是根据‘wordlist-gbk.txt’词表进行中文分词的,我们可以根据需要对词表维护添加自己的词组。执行 select segment(”这是一个关于全文搜索的测试数字”); 输出如下结果。

mysql> select segment(”这是一个关于全文搜索的测试”);
+——————————————-+
| segment(”这是一个关于全文搜索的测试”) |
+——————————————-+
| 这是 一个 关于 全文 搜索 测试 |
+——————————————-+
1 row in set (0.00 sec)

5.需要注意的问题。在我测试和使用的过程中发现我使用‘测试’作为关键字搜索竟然没有任意记录命中,一开始还以为是个BUG。后来突然想起来这是MYSQL全文索引的一个特性,如果你的关键字有半数记录以上都能匹配那么意味着所有的记录都不能匹配(因为这样做匹配的化已经没有任何意义) 。 5条测试记录中有4条含有测试关键字,使用如下’测试’作为关键字搜索结果如下。

mysql> SELECT id,MATCH (title, content)AGAINST (’测试’) FROM `test_ft`;
+—-+—————————————-+
| id | MATCH (title, content)AGAINST (’测试’) |
+—-+—————————————-+
| 1 | 0 |
| 2 | 0 |
| 3 | 0 |
| 4 | 0 |
| 5 | 0 |
+—-+—————————————-+
5 rows in set (0.01 sec)

结论
——–
经过测试发现此版本对中文全文索引的支持一点都不比海量公司提供的功能差,而且hightman提供了中文全文索引的测试发现其运行效率也不错,在此再次对hightman表示支持和感谢。


Archived in 系统构架※安装配置 | Trackback | del.icio.us | Top Of Page
chyangwa离线中   回复时引用此帖
回复


主题工具
显示模式

发帖规则
不可以发表新主题
不可以回复主题
不可以上传附件
不可以编辑您的帖子

vB 代码开启
[IMG]代码开启
HTML代码关闭
论坛跳转



所有的时间均为北京时间。 现在的时间是 04:40.


NewvBB Core 1.1 Final - vBulletin v3.0.3
中文化与插件制作 NewVBB.com™ 2024。
友情连接        
摩托车.上海.中国        
         
         
         
         
         

上海市通信管理局
沪ICP备010502
沪ICP备05000578号