1.通配符和正则表达式限制
- 性能:通配符和正则表达式匹配通常要求MySQL尝试匹配表中所有行由于行数的增加,搜索可能非常耗时
- 明确控制:很难明确的控制匹配什么,不匹配什么
- 智能化的结果:不能提供智能化的选择结果的方法
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行
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布尔文本搜索
可返回:
- 要匹配的词
- 要排斥的词(如果某行包含这个词,则不返回该行,即使它包含其他指定词)
- 排列提示(指定某些词比其他词更重要,更重要的词等级更高)
- 表达式分组
- 另外一些内容
即使没有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全文本搜索使用说明
- 在索引全文本数据时,短词(3个或3个以下字符)会被忽略且从索引排除
- MySQL有一个内建的非用词列表,这些词在搜索时会被忽略,如果需要可以覆盖这个列表
- 一个词出现在50%以上的行中,将会被认为是非用词,这个规则不用于布尔
- 若表中行数小于3行,全文本搜索不返回结果
- 忽略词中的单引号,don’t索引为dont
- 没有词分隔符的语言不能恰当返回全文本搜索结果(如中文)
- 仅在MyISAM数据库引擎中支持全文本搜索