1.通配符和正则表达式限制

  1. 性能:通配符和正则表达式匹配通常要求MySQL尝试匹配表中所有行由于行数的增加,搜索可能非常耗时
  2. 明确控制:很难明确的控制匹配什么,不匹配什么
  3. 智能化的结果:不能提供智能化的选择结果的方法

2.使用全本文搜索

必须索引被搜索的列,而且要随着数据的改变不断地重新索引,在索引之后,SELECT 可与Match()和 Against()一起使用进行搜索

2.1启用全文本搜索

一般在创建表的时候启用全文本搜索.

CREATE TABLE 接受FULLTEXT

CREATE TABLE a(
note_id INT NOT NULL ;
...
...
FULLTEXT(note_text))
#note_text列,为了进行全本文搜索,FULLTEXT(note_text)索引单个列,如果需要也可以指定多个列,定义之后,MySQL会自动维护该索引,在增加更新删除行时,索引会自动更新

不要在导入数据时使用FULLTEXT,应该先导入数据,然后修改表,定义FULLTEXT,这样有助于更快的导入数据

2.2进行全文本搜索

索引之后,Match()和 Against()执行全文本搜索,Match()指定被搜索的列, Against()指定要使用的搜索表达式

SELECT note_text
FROM productnotes
WHERE MATCH(note_text) Against('rabbit')

SELECT note_text
FROM productnotes
WHERE note_text LIKE '%rabbit%'
#和第一种一样,但是结果的次序不同

MATCH(note_text) :指示MySQL针对指定的列进行搜索

传递给MATCH的值必须与FULLTEXT定义中的相同,如果指定多个列则必须列出她们(并且次序正确)

Against(‘rabbit’):指定词rabbit作为搜索文本

上述语句用LIKE也能完成,但是全文本搜索有个优点,会对结果排序,具有较高等级的行先返回!!

SELECT note_text,
	   MATCH(note_text) Against('rabbit') AS `rank`
FROM productnotes

没有用WHERE子句,直接在SELECT中使用MATCH(note_text) Against(‘rabbit’),会得到一个等级,为0的是不包含搜索词的

2.3使用查询扩展

用来设法放宽所返回的全文本搜索结果的范围。

  1. 进行一个基本的全文本搜索,找出与搜索条件匹配的所有行
  2. 检查匹配行并选择所有有用的行
  3. 再次进行全文本搜索,不仅使用原来的条件,还使用所有有用的词
#全文本:输出1行
SELECT note_text
FROM productnotes
WHERE MATCH(note_text) Against('anvils')

#查询扩展:输出7行
SELECT note_text
FROM productnotes
WHERE MATCH(note_text) Against('anvils' WITH QUERY EXPANSION)

表中行越多,扩展查询返回的结果越好

2.4布尔文本搜索

可返回:

  1. 要匹配的词
  2. 要排斥的词(如果某行包含这个词,则不返回该行,即使它包含其他指定词)
  3. 排列提示(指定某些词比其他词更重要,更重要的词等级更高)
  4. 表达式分组
  5. 另外一些内容

即使没有FULLTEXT索引也可以使用

SELECT note_text
FROM productnotes
WHERE MATCH(note_text) Against('heavy' IN BOOLEAN MODE)

#匹配包含heavy但不包含任意以rope开始的词的行
SELECT note_text
FROM productnotes
WHERE MATCH(note_text) Against('heavy -rope*' IN BOOLEAN MODE)

布尔操作符

说明

+

包含,词必须存在

-

排除,词必须不出现

>

包含,并增加等级值

<

包含,并减少等级值

()

把词组成子表达式()允许子表达式作为一个组被包含、排除、排列等

~

取消一个词的排序值

*

词尾的通配符

“”

定义一个短语(与单个词的列表不同,匹配整个短语以便包含或排除这个短语)

#匹配rabbit ,bait,必须同时存在
SELECT note_text
FROM productnotes
WHERE MATCH(note_text) Against('+rabbit +bait' IN BOOLEAN MODE)

#匹配rabbit bait至少一个
SELECT note_text
FROM productnotes
WHERE MATCH(note_text) Against('rabbit bait' IN BOOLEAN MODE)

#匹配rabbit bait短语
SELECT note_text
FROM productnotes
WHERE MATCH(note_text) Against('"rabbit bait"' IN BOOLEAN MODE)

#增加rabbit的等级,降低carrot等级
SELECT note_text
FROM productnotes
WHERE MATCH(note_text) Against('>rabbit <carrot' IN BOOLEAN MODE)

#两个词都要匹配,同时出现,并且降低后者等级
SELECT note_text
FROM productnotes
WHERE MATCH(note_text) Against('+safe +(<combination)' IN BOOLEAN MODE)
2.5全文本搜索使用说明
  1. 在索引全文本数据时,短词(3个或3个以下字符)会被忽略且从索引排除
  2. MySQL有一个内建的非用词列表,这些词在搜索时会被忽略,如果需要可以覆盖这个列表
  3. 一个词出现在50%以上的行中,将会被认为是非用词,这个规则不用于布尔
  4. 若表中行数小于3行,全文本搜索不返回结果
  5. 忽略词中的单引号,don’t索引为dont
  6. 没有词分隔符的语言不能恰当返回全文本搜索结果(如中文)
  7. 仅在MyISAM数据库引擎中支持全文本搜索