MySQL 全文索引

创建全文索引(FULLTEXT INDEX)

创建表的同时创建全文索引

CREATE TABLE `article` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `title` varchar(255) DEFAULT NULL COMMENT '标题',
  `body` text COMMENT '内容',
  PRIMARY KEY (`id`),
  FULLTEXT KEY `body` (`body`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

通过 ALTER TABLE 的方式来添加

ALTER TABLE `student` 
ADD FULLTEXT INDEX ft_stu_name (`name`)

ft_stu_name是索引名,可以随便起
或者

ALTER TABLE `student` 
ADD FULLTEXT ft_stu_name (`name`)

直接通过CREATE INDEX的方式

CREATE FULLTEXT INDEX ft_email_name ON `student` (`name`)

也可以在创建索引的时候指定索引的长度

CREATE FULLTEXT INDEX ft_email_name ON `student` (`name` (20))

删除全文索引

直接使用 DROP INDEX(注意:没有 DROP FULLTEXT INDEX 这种用法)

DROP INDEX full_idx_name ON tommy.girl ;
使用 ALTER TABLE 的方式

ALTER TABLE tommy.girl DROP INDEX ft_email_abcd;

使用全文索引

跟普通索引稍有不同,使用全文索引的格式: MATCH (columnName) AGAINST (‘string’)

SELECT * FROM `student` WHERE MATCH(`name`) AGAINST('聪')

当查询多列数据时:建议在此多列数据上创建一个联合的全文索引,否则使用不了索引的。

SELECT * FROM `student` WHERE MATCH(`name`,`address`) AGAINST('聪 广东')

使用全文索引需要注意的是:(基本单位是词)
分词,全文索引以词为基础的,MySQL默认的分词是所有非字母和数字的特殊符号都是分词符

MYSQL中与全文索引相关的几个变量

必须通过修改MySQL的配置文件来完成。通常修改最小搜索长度的值为2,首先打开MySQL的配置文件

在 [mysqld]的下面追加
innodb_ft_min_token_size = 2
ft_min_word_len = 2
ngram_token_size = 2
使用命令:mysql> SHOW VARIABLES LIKE 'ft%';ft就是FullText的简写

变量名字 变量值 变量说明
ft_boolean_syntax + -><()~*:""&| 改变IN BOOLEAN MODE的查询字符,不用重新启动MySQL也不用重建索引
ft_min_word_len 4 最短的索引字符串,默认值为4,(通常改为1)修改后必须重建索引文件。重新建立索引命令:repair table tablename quick
ft_max_word_len 84 最长的索引字符串,默认值为84,修改后必须重建索引文件
ft_query_expansion_limit 20 查询括展时取最相关的几个值用作二次查询
ft_stopword_file (built-IN) 全文索引的过滤词文件,具体可以参考:MySQL全文检索中不进行全文索引默认过滤词
使用命令:show variables like "%ngram%"

变量名字 变量值 变量说明
ngram_token_size 2 ngram解析器令牌长度即against()中字符串切分的最小字符长度
特别注意:50%的门坎限制(当查询结果很多,几乎所有记录都有,或者极少的数据,都有可能会返回非所期望的结果):可用IN BOOLEAN MODE即可以避开50%的限制。
此时使用全文索引的格式就变成了:

SELECT * FROM `student` WHERE MATCH(`name`) AGAINST('聪' IN BOOLEAN MODE)

FT_BOOLEAN_SYNTAX (+ -><()~*:”“&|)使用的例子

  • : 用在词的前面,表示一定要包含该词,并且必须在开始位置
    +Apple 匹配:Apple123, “tommy, Apple”
  • : 不包含该词,所以不能只用-yoursql这样是查不到任何row的,必须搭配其他语法使用
    MATCH (girl_name) AGAINST (‘-林志玲 +张筱雨’)
    匹配到: 所有不包含林志玲,但包含张筱雨的记录
    空(也就是默认情况),表示可选的,包含该词的顺序较高
    apple banana 找至少包含上面词中的一个的记录行;
    +apple +juice 两个词均在被包含;
    +apple macintosh 包含词 “apple”,但是如果同时包含 “macintosh”,它的排列将更高一些;
    +apple -macintosh 包含 “apple” 但不包含 “macintosh”。

    :提高该字的相关性,查询的结果会排在比较靠前的位置
    < :降低相关性,查询的结果会排在比较靠后的位置
    " " : 双引号内作为整体不能拆词

  • : 通配符,只能接在词后面
    先不使用 ><

select * from article where match(body) against('明天晴天 ' in boolean mode);

可以看到完全匹配的排的比较靠前。

单独使用 >

select * from article where match(body) against('明天晴天 > 好好学习 ' in boolean mode);

单独使用 <

select * from article where match(body) against('明天晴天 < 出去放风筝' in boolean mode);

同时使用><

select * from article where match(body) against('明天晴天 > 阴天了吧 <好好学习 > 喝奶茶去 < 出去放风筝' in boolean mode);
image.png

可以通过括号来使用字条件

+aaa +(>bbb <ccc) : 找到有aaa和bbb和ccc,aaa和bbb,或者aaa和ccc(因为bbb,ccc前面没有+,所以表示可有可无),然后 aaa&bbb > aaa&bbb&ccc > aaa&ccc

将其相关性由正转负

~ :将其相关性由正转负,表示拥有该字会降低相关性,但不像「-」将之排除,只是排在较后面。
+apple ~macintosh : 先匹配apple,但如果同时包含macintosh,就排名会靠后。

通配符只能接在字符串后面

MATCH (girl_name) AGAINST ('+ABC') : 错误,不能放前面
MATCH (girl_name) AGAINST ('+张筱雨*') : 正确

整体匹配,用双引号将一段句子包起来表示要完全相符,不可拆字

"tommy huang"可以匹配 tommy huang xxxxx 但是不能匹配 tommy is huang

点赞

发表回复

电子邮件地址不会被公开。必填项已用 * 标注