(1)为什么要用全文搜索:
a) 性能:通配符和正则表达式匹配通常要求mysql尝试匹配表中所有行,因此,这些搜索可能非常耗时;
b) 明确控制:使用通配符和正则表达式很难明确的控制匹配什么和不匹配什么;
c) 在使用全文本搜索时,mysql不需要分别查看每个行,不需要分别分析和处理每个词;
(2)全文本搜索的使用说明:
a) 在全文本搜索时,那些具有3个或3个以下字符的词被忽略且从索引中排除(如果需要,这个数目可以更改);
b) mysql带有一个内建的非用词(stopword)列表,这些词在索引全文本数据时总是被忽略,如果需要,可以覆盖这个列表;
c) 许多词出现的频率很高,搜索它们没有用处(返回太多的结果),因此,mysql规定了一条50%规则,如果一个词出现在50%以上的行中,则将它作为一个非用词忽略,50%规则不用于in boolean mode;
d) 如果表中的行数少于3行,则全文本搜索不返回结果(因为每个词或者不出现,或者至少出现在50%的行中);
e) 忽略词中的单引号,如don't索引为dont;
f) 不具有词分隔符(包括日语和汉语)的语言不能恰当地返回全文本搜索结果;
g) 仅能在MyISAM数据库引擎中支持全文本搜索;
(3)全文本搜索,Mysql支持几种基本的数据库引擎,两个最常使用的引擎为MyISAM和InnoDB,前者支持全文本搜索,而后者不支持;
(4)一般在创建表时启用全文本搜索,create table语句接受fulltext子句;在启用全文本搜索之后,使用两个函数match()和against()执行全文本搜索,其中match()指定被搜索的列,against()指定要使用的搜索表达式;
(5)传递给match()的值必须与fulltext()定义中的相同,如果指定多个列,则必须列出它们(而且次序正确);并且搜索不区分大小写,除非使用BINARY方式;
(6)使用查询扩展,用来设法放宽所返回的全文本搜索结果的范围;select ...where match(note_text) against('great' with query expansion);表中的行越多,使用查询扩展返回的结果越好;
(7)布尔文本搜索:即使没有fulltext索引也可以使用,但性能将随着数据量的增加而降低;如:
select ... where match(note_text) against('great -nice*' in boolean mode);
-nice*明确指示mysql排除包含nice*(任何以nice开始的词,包括nices)的行;
(8)对于大量的数据,一般不要在导入时使用fulltext索引,应该首先导入所有数据,然后再修改表,定义fulltext索引,这样速度会相对很快;把数据转载到一个已经有fulltext索引的表中,这样效率是很低的;
例子如下:
新建表:
create table prod
(
note_id not null,
note_text null,
primary key(note_id),
fulltext(note_text)
) engine = MyISAM;
插入数据后表中信息:
mysql> select * from prod;
+---------+---------------------------------+
| note_id | note_text |
+---------+---------------------------------+
| 1 | you are a super star right |
| 2 | not a super star left big great |
| 3 | great a boy or girls |
| 4 | nice good great |
| 5 | nice great a boy is |
| 6 | against great set |
| 7 | good beautiful nices great |
+---------+---------------------------------+
7 rows in set (0.00 sec)
mysql> select note_text from prod where match(note_text) against('great');
+---------------------------------+
| note_text |
+---------------------------------+
| against great set |
| not a super star left big great |
| good beautiful nices great |
+---------------------------------+
3 rows in set (0.00 sec)
-nice*明确指示mysql排除包含nice*(任何以nice开始的词,包括nices)的行;
mysql> select note_text from prod where match(note_text) against('great -nice*'
in boolean mode);
+---------------------------------+
| note_text |
+---------------------------------+
| not a super star left big great |
| against great set |
+---------------------------------+
2 rows in set (0.00 sec)查询扩展:
mysql> select note_text from prod where match(note_text) against('great' with qu
ery expansion);
+---------------------------------+
| note_text |
+---------------------------------+
| not a super star left big great |
| good beautiful nices great |
| you are a super star right |
| nice good beautiful |
| against great set |
+---------------------------------+
5 rows in set (0.00 sec)查询包含词great和nices的行
mysql> select note_text from prod where match(note_text) against('+great +nices'
in boolean mode);
+----------------------------+
| note_text |
+----------------------------+
| good beautiful nices great |
+----------------------------+
1 row in set (0.00 sec)查询包含词great或nice的至少一个词的行;
mysql> select note_text from prod where match(note_text) against('great nice' in
boolean mode);
+---------------------------------+
| note_text |
+---------------------------------+
| not a super star left big great |
| nice good beautiful |
| nice welcome a boy is |
| against great set |
| good beautiful nices great |
+---------------------------------+
5 rows in set (0.00 sec)查询包含字符串great set而不是匹配两个词great和set的行;
mysql> select note_text from prod where match(note_text) against('"great set"' i
n boolean mode);
+-------------------+
| note_text |
+-------------------+
| against great set |
+-------------------+
1 row in set (0.00 sec)
布尔全文搜索操作符: