我们在 MySQL 资料中可以使用 match against 语句解决中文全文搜寻的问题
先看一个例句:
SELECT * FROM v9_search WHERE `siteid`= ‘1’ AND `typeid` = ‘3’ AND MATCH (`data`) AGAINST (‘基地 教育 韩天衡’ IN BOOLEAN MODE);
想要此语句生效需要满足以下几个条件:
1,表’v9_search’ 的型别必须是 MyISAM
2,栏位’data’ 的型别必须是 char,varchar,text
3,栏位’data’ 上建立全文检索(FULLTEXT)
4,栏位’data’ 中的资料为空格分隔的中文分词,例如:韩天衡先生绘画 韩天衡 绘画 先生 先生 绘画
5,mysql 索引词的最小长度不大于 2
其中 1-4 条常用,第五条需要修改 mysql 配置,配置项为:ft_min_word_len
检视 Mysql 配置项的命令如下:
show VARIABLES like ‘ft_%’;
一般情况下,ft_min_word_len 为 4,修改此引数,需要在配置档案 [mysqld] 位置内加入如下配置:
ft_min_word_len = 2
不能使用:set GLOBAL ft_min_word_len = 2; 语句强制修改。
引数修改之后,重新启动 mysql 服务,并且重新建索引,重建索引命令如下:
REPAIR TABLE tbl_name QUICK;
如果资料表中记录较多,重建索引花费时间较长,需耐心等待几秒钟。
MySQL 全文搜寻 match against 的用法
对于大的资料库,将资料装载到一个没有 FULLTEXT 索引的表中,然后再使用 ALTER TABLE  (或 CREATE INDEX) 建立索引,这将是非常快的。将资料装载到一个已经有 FULLTEXT 索引的表中,将是非常慢的。
1. 使用 Mysql 全文检索 fulltext 的先决条件
表的型别必须是 MyISAM
建立全文检索的栏位型别必须是 char,varchar,text
2. 建立全文检索先期配置
由于 Mysql 的预设配置是索引的词的长度是 4, 所以要支援中文单字的话, 首先更改这个.
*Unix 使用者要修改 my.cnf, 一般此档案在/etc/my.cnf, 如果没有找到, 先查询一下 find / -name ‘my.cnf’
在 [mysqld] 位置内加入:
ft_min_word_len    = 2
其它属性还有
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_wordlist_charset 表示词典的字符集, 目前支援良好的有 (UTF-8, gbk, gb2312, big5)
ft_wordlist_file 是词表档案, 每行包括一个词及其词频 (用若干制表符或空格分开, 消岐专用)
ft_stopword_file 表示过滤掉不索引的词表, 一行一个.
ft_min_word_len    加入索引的词的最小长度, 预设是 4, 为了支援中文单字故改为 2
3. 建立全文检索
在建表中用 FullText 关键字标识栏位, 已存在的表用 ALTER TABLE (或 CREATE INDEX) 建立索引
CREATE fulltext INDEX index_name ON table_name(colum_name);
4. 使用全文检索
在 SELECT 的 WHERE 字句中用 MATCH 函式, 索引的站群关键词 TDK 用 AGAINST 标识,IN BOOLEAN MODE 是只有含有关键字就行, 不用在乎位置, 是不是起启位置.
SELECT * FROM articles WHERE MATCH (tags) AGAINST (‘旅游’ IN BOOLEAN MODE);
5. 详细的说明请引数 Mysql 官方网站
http://dev.mysql.com/doc/refman/5.1/zh/functions.html#fulltext-search
这是 Mysql 5.1 的, 不过 4.X 也可以做为参考, 基本一置. 我用的就是 Mysql 4.1.
MySQL 支援全文索引 (Full-Text) 已经很久了,目前,fulltext 是一种只适用于 MyISAM 表的一个索引型别,而且对定义索引列的资料型别也有限制,只能是以下三种的组合 char 、 varchar 、 text 。 fulltext 可以在建立表的同时就一起定义好,或者在表建立完成之后,通过语句 alter table 或 create index 来追加索引,总之先后的效果是一样的,但是两者的效率却是存在很大差异的,大量的实验证明,对于大数量的表来说,先载入资料再来定义全文索引的 速度要远远优于在一个已经定义好全文索引的表里面插入大量资料的速度。一定会问:这是问什么呢?其实,道理很简单,前者只需要一次性对你的索引列表进行操 作,排序比较都是在内存中完成,然后写入硬碟;后者则要一条一条去硬碟中读取索引表然后再进行比较最后写入,自然这样速度就会很慢。 MySQL 是 通过 match() 和 against() 这两个函式来实现它的全文索引查询的功能。 match() 中的栏位名称要和 fulltext 中定义的栏位一致,如 果采用 boolean 模式搜寻,也允许只包括 fulltext 中的某个栏位,不需要全部列出。 against() 中定义的是所要搜寻的字串以及要求资料 库通过哪种模式去执行全文索引的搜寻查询。
家用一下 SEO 站群搜索引擎就会发现,分词的情况只是出现在当整词命中为 0 的情况下。
而具体怎样分词,大家可以参考一下 baidu 搜寻试验结果:
·如果搜 “徐祖宁宁”,结果为 “徐祖”+“宁宁” 。(搜人名的情况下,它可能有一个百家姓词典,自动将姓后第一个字归前)
·搜 “徐宁愿”,结果为 “徐宁愿” 。(说明 “宁愿” 归 “徐” 所有。同上。因为徐是姓。)
·搜 “徐祖宁愿”,结果为 “徐祖”+“宁愿” 。(因为 “宁愿” 是词,故 “徐” 只带 “祖” 。)
·搜 “徐祖宁高”,结果为 “徐祖宁” 。(因为 “宁高” 不是关键字,所以 “宁” 归前词所有。而 “高” 可能因为是单字,为提高前词搜寻效率故被省略。)