MySQL具备全文搜索的能力。全文搜索引擎可以在不使用模板匹配操作的情况下查找单词或短语。全文搜索分为3种模式,如下所示。
自然语言模式。把搜索字符串解释为一系列单词并查找包含这些单词的数据行。
布尔模式。把搜索字符串解释为一系列单词,但允许使用一些操作符字符来"修饰"这些单词以表明特定的要求,如某给定单词必须出现(或不出现)在匹配数据行里,某个数据行必须包含一个精确的短语,等等。
查询扩展模式。这种搜索分两阶段进行。第一阶段是自然语言搜索,第二阶段使用原来的搜索字符串加上在第一次搜索中找到的相关度最高的匹配数据行再进行一次搜索。这扩大了搜索范围,它可以把与原来的搜索字符串相关、但用原来的搜索字符串匹配不到的数据行也找出来。
要想对某个数据表进行全文搜索,必须事先为它创建一个FULLTEXT索引,这种索引具有以下特点。
全文搜索的基础是FULLTEXT索引,这种索引只能在MyISAM数据表里创建。FULLTEXT索引只能由CHAR、VARCHAR和TEXT这几种类型的数据列构成。
全文搜索将忽略"常见的"单词,而"常见"在这里的含义是"至少在一半的数据行里出现过"。千万不要忘记这个特点,尤其是在你准备对数据表进行全文搜索测试时。你至少要在测试数据表里插入3个数据行。如果那个数据表只有一个或两个数据行,它里面的每个单词将至少有50%的出现几率,所以对它进行全文搜索将不会有任何结果。
全文搜索还将忽略一些常用单词,如"the"、"after"和"other"等,这些单词被称为"休止单词",MySQL在进行全文搜索时总是会忽略它们。
太短的单词也将被忽略。在默认的情况下,"太短"指少于4个字符。但你可以通过重新配置服务器的办法把这个最小长度设置为其他值。
全文搜索对"单词"的定义是:由字母、数字、撇号(如"it's"中的"'")和下划线字符构成的字符序列。这意味着字符串"full-blood"将被解释为包含"full"和"blood"两个单词。全文搜索匹配整个单词,而不是单词的一部分。只要在一个数据行里找到了搜索字符串里的任何单词,FULLTEXT引擎就会认为这个数据行与搜索字符串是匹配的。在此基础上,布尔式全文搜索还允许你加上一些额外的要求,比如说,所有的单词都必须出现(不论顺序)才认为是匹配,(在搜索一条短语时)单词顺序必须与在搜索字符串里列出的一致,等等。布尔搜索还可以用来匹配不包含特定单词的数据行,或者通过添加一个通配符来匹配以一个给定前缀开头的所有单词。
FULLTEXT索引可以为一个或多个数据列而创建。如果它涉及多个数据列,基于该索引的搜索将在所有数据列上同时进行。反过来说,在进行全文搜索时,你给出的数据列清单必须和某个FULLTEXT索引所匹配的那些数据列精确匹配。比如说,如果你需要分别搜索col1、col2以及"col1和col2",你将需要创建3个索引:col1和col2各有一个,"col1和col2"有一个。
接下来的例子演示了全文搜索的使用方法。我们将先创建几个FULLTEXT索引,然后用MATCH操作符对它们进行一些查询。用来创建数据表并把一些样板数据加载到其中的脚本可以在sampdb数据库的fulltext子目录里找到。
FULLTEXT索引的具体创建过程与其他索引大同小异。你可以在创建一个新数据表的同时在CREATE TABLE语句里定义它们,也可以在数据表被创建出来以后再用ALTER TABLE或CREATE INDEX语句添加它们。因为FULLTEXT索引要求你必须使用MyISAM数据表,所以如果你正在创建一个需要使用全文搜索的MyISAM数据表,不妨利用一下MyISAM存储引擎的这个特点来加快点儿速度。在加载数据时,先填充数据表、再添加索引的办法要比先创建索引再加载数据的办法快得多。假设你有一个名为apothegm.txt的数据文件,其内容是一些名人名言:
如果按"名人"、"名言"和"名人加名言"进行搜索,你需要创建3个FULLTEXT索引:两个数据列各有一个,它们加起来有一个。下面这些语句将创建、填充一个名为apothegm的数据表,并为它编制索引: