我们都知道 InnoDB 在模糊查询数据时使用 "%xx" 会导致索引失效,但有时需求就是如此,类似这样的需求还有很多,例如,搜索引擎需要根基用户数据的关键字进行全文查找,电子商务网站需要根据用户的查询条件,在可能需要在商品的详细介绍中进行查找,这些都不是B+树索引能很好完成的工作。

通过数值比较,范围过滤等就可以完成绝大多数我们需要的查询了。但是,如果希望通过关键字的匹配来进行查询过滤,那么就需要基于相似度的查询,而不是原来的精确数值比较,全文索引就是为这种场景设计的。

全文索引(Full-Text Search)是将存储于数据库中的整本书或整篇文章中的任意信息查找出来的技术。它可以根据需要获得全文中有关章、节、段、句、词等信息,也可以进行各种统计和分析。

在早期的 MySQL 中,InnoDB 并不支持全文检索技术,从 MySQL 5.6 开始,InnoDB 开始支持全文检索。

1倒排索引

全文检索通常使用倒排索引(inverted index)来实现,倒排索引同 B+Tree 一样,也是一种索引结构。它在辅助表中存储了单词与单词自身在一个或多个文档中所在位置之间的映射,这通常利用关联数组实现,拥有两种表现形式:

  • inverted file index:{单词,单词所在文档的id}
  • full inverted index:{单词,(单词所在文档的id,再具体文档中的位置)}

MySQL模糊查询可以不用 like+% 了!_全文索引

对于 inverted file index 的关联数组

上图为 inverted file index 关联数组,可以看到其中单词"code"存在于文档1,4中,这样存储再进行全文查询就简单了,可以直接根据 Documents 得到包含查询关键字的文档;而 full inverted index 存储的是对,即(DocumentId,Position),因此其存储的倒排索引如下图,如关键字"code"存在于文档1的第6个单词和文档4的第8个单词。相比之下,full inverted index 占用了更多的空间,但是能更好的定位数据,并扩充一些其他搜索特性。

MySQL模糊查询可以不用 like+% 了!_倒排索引_02

2添加全文索引: 


CREATE FULLTEXT INDEX full_index_name ON table_name(col_name);


搜索: 

SELECT  *  FROM table_name where MATCH  (coloum_name)  AGAINST ('key')
  • +:表示该 word 必须存在
  • -:表示该 word 必须不存在
  • (no operator)表示该 word 是可选的,但是如果出现,其相关性会更高
  • @distance表示查询的多个单词之间的距离是否在 distance 之内,distance 的单位是字节,这种全文检索的查询也称为 Proximity Search,如 MATCH(context) AGAINST('"Pease hot"@30' IN BOOLEAN MODE)语句表示字符串 Pease 和 hot 之间的距离需在30字节内
  • >:表示出现该单词时增加相关性
  • <:表示出现该单词时降低相关性
  • ~:表示允许出现该单词,但出现时相关性为负
  • * :表示以该单词开头的单词,如 lik*,表示可以是 lik,like,likes
  • " :表示短语