mysql中模糊搜索关键字可以用like关键字,它可以查询出包涵关键字的字段,但当数据量变大时(比如超过百万条),由于不能使用索引,全表扫描会导致性能很差。那怎么能查询出包涵关键字的内容呢?这时可以采用mysql的全文搜索。但有个前提:需要把进行全文搜索的字段添加fulltext索引,并且只能建立在Myisam引擎上。然后用如match(字段1[,字段2,字段3…]) against(‘关键字1 关键字2’)这样的方式搜索,这样可以查询出某些字段中包涵某些关键字的信息。
另外,用like匹配的是字符,全文搜索匹配的是关键字。例如:“欢迎来到火星时代IT开发”,如果用like查询这句话的任意连接着的字符比如 “欢迎来”、“IT开发”类似无意义的字符也可以查询出相应的结果。而用全文搜索只能用一些有意义的词来查询才可以查询到,比如“火星时代”、“开发”此类关键字才能查到。通常查询比较短的内容,比如模糊查询姓名,可以采用like;而从大段落内容查询一些关键字,就要用全文搜索。
全文搜索中,如果搜索全英文的内容,因为英文每个单词都用空格分开的,mysql可以通过空格找到包涵搜索关键字的一些记录。但因为中文直接没有像英文那样有空格分开,mysql是无法搜索直接查询到包涵搜索关键字的记录的,这是需要写入数据的时候就把记录的内容用一个一个关键字用空格分开写入,这样mysql就可以搜索包涵中文的全文搜索了。例如:“欢迎来到火星时代IT开发”这句话,写入数据库时可以把每个关键字用空格分割写入, 类似“欢迎 来到 火星时代 IT 开发”这样的语句。
看到有一个scws这样的中文分词插件比较不错,简单的学习了一下。它包涵一些专有名称、人名、地名、数字年代等规则集合,可以直接将语句按这些规则分开成一个一个关键词,准确率在90%-95%之间。按照安装说明把scws的扩展放入php的扩展目录里,下载规则文件和词典文件,并在php配置文件中引用它们,就可以用scws进行分词了。
下面是简单的使用示例,代码如下:
- <?php
-
- $so = scws_new();
-
- $so->set_charset(‘utf-8’);
-
- $so->set_dict('/path/dict.utf8.xdb');
-
- $so->set_rule('/path/rules.utf8.ini ');
-
- $so->set_ignore(true);
-
- $so->set_multi(true);
-
- $so->set_duality(true);
-
- $so->send_text(“欢迎来到火星时代IT开发”);
-
- while ($tmp = $so->get_result())
- {
- print_r($tmp);
- }
- $so->close();
- ?>
注:如以上例子,输入的文字,词典,规则文件这三者的字符集必须统一,另外mysql 4.XX有的是不支持中文全文搜索的,可以存入关键字对应的区位码以方便全文搜索.
MySQL全文检索笔记
1.MySQL 4.x版本及以上版本提供了全文检索支持,但是表的存储引擎类型必须为MyISAM,以下是建表SQL,注意其中显式设置了存储引擎类型,代码如下:
- CREATE TABLE articles (
- id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
- title VARCHAR(200),
- body TEXT,
- FULLTEXT (title,body)
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
其中FULLTEXT(title,body) 给title和body这两列建立全文索引,之后检索的时候注意必须同时指定这两列.
2.插入测试数据,代码如下:
- INSERT INTO articles (title,body) VALUES
- ('MySQL Tutorial','DBMS stands for DataBase ...'),
- ('How To Use MySQL Well','After you went through a ...'),
- ('Optimizing MySQL','In this tutorial we will show ...'),
- ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
- ('MySQL vs. YourSQL','In the following database comparison ...'),
- ('MySQL Security','When configured properly, MySQL ...');
3.全文检索测试,代码如下:
- SELECT * FROM articles
- WHERE MATCH (title,body) AGAINST ('database');
检索结果如下:
- 5 MySQL vs. YourSQL In the following database comparison ...
- 1 MySQL Tutorial DBMS stands for DataBase ...
说明全文匹配时忽略大小写.
4.可能遇到的困扰,到目前为止都很顺利,但是如果检索SQL改为下面会怎样呢?代码如下:
- SELECT * FROM articles www.phpfensi.com
- WHERE MATCH (title,body) AGAINST ('well');
结果让人大跌眼镜,开始我也困惑了许久,后来去网上查了下才知道原来是这么回事.
mysql指定了最小字符长度,默认是4,必须要匹配大于4的才会有返回结果,可以用SHOW VARIABLES LIKE 'ft_min_word_len' 来查看指定的字符长度,也可以在mysql配置文件my.ini 更改最小字符长度,方法是在my.ini 增加一行,比如:ft_min_word_len = 2,改完后重启mysql即可. |