MySQL 从 5.7.6 版本开始,MySQL就内置了ngram全文解析器,用来支持中文、日文、韩文分词。在 MySQL 5.7.6 版本之前,全文索引只支持英文全文索引,不支持中文全文索引,需要利用分词器把中文段落预处理拆分成单词,然后存入数据库。
一、全文解析器ngram
ngram就是一段文字里面连续的n个字的序列。ngram全文解析器能够对文本进行分词,每个单词是连续的n个字的序列。
MySQL 中使用全局变量 ngram_token_size 来配置 ngram 中 n 的大小,它的取值范围是1到10,默认值是 2。通常ngram_token_size设置为要查询的单词的最小字数。如果需要搜索单字,就要把ngram_token_size设置为 1。在默认值是 2 的情况下,搜索单字是得不到任何结果的。因为中文单词最少是两个汉字,推荐使用默认值 2。
- 查看Mysql默认的ngram_token_size大小
show variables like 'ngram_token_size'
- 修改ngram_token_size 变量的两种设置方式:
1、启动mysqld命令时指定
mysqld --ngram_token_size=2
2、修改mysql配置文件
[mysqld]
ngram_token_size=2
二、全文索引
- 建表时创建全文索引
create table sys_basics_word
(
id bigint(20) not null comment '主键',
chinese varchar(255) comment '中文',
thesaurus varchar(255) comment '同义词',
chinese_meaning varchar(255) comment '中文含义',
english_prototype varchar(255) comment '英文原型',
abbr varchar(255) comment '缩写',
reference varchar(255) comment '引用',
chinese_and_thesaurus char(10) comment '中文和同义词',
create_by varchar(100) comment '创建者',
create_date datetime comment '创建时间',
update_by varchar(100) comment '更新者',
update_date datetime comment '更新时间',
del_flag char(1) default '0' comment '删除标记',
FULLTEXT KEY `chinese_and_thesaurus` (`chinese_and_thesaurus`) WITH PARSER `ngram`,
primary key (id)
);
- 通过 alter table 方式
ALTER TABLE sys_basics_word ADD FULLTEXT INDEX chinese_and_thesaurus(chinese_and_thesaurus) WITH PARSER ngram;
- 通过 create index 方式
CREATE FULLTEXT INDEX chinese_and_thesaurusON sys_basics_word (chinese_and_thesaurus) WITH PARSER ngram;
三、检索模式
- 自然语言检索
(IN NATURAL LANGUAGE MODE)自然语言模式是 MySQL 默认的全文检索模式。自然语言模式不能使用操作符,不能指定关键词必须出现或者必须不能出现等复杂查询。 - 布尔检索
(IN BOOLEAN MODE)剔除一半匹配行以上都有的词,例如,每行都有this这个词的话,那用this去查时,会找不到任何结果,这在记录条数特别多时很有用,原因是数据库认为把所有行都找出来是没有意义的,这时,this几乎被当作是stopword(中断词);布尔检索模式可以使用操作符,可以支持指定关键词必须出现或者必须不能出现或者关键词的权重高还是低等复杂查询。
1、 IN BOOLEAN MODE的特色:
不剔除50%以上符合的row。
不自动以相关性反向排序。
可以对没有FULLTEXT index的字段进行搜寻,但会非常慢。
限制最长与最短的字符串。
套用Stopwords。
2、 搜索语法规则:
+ 一定要有(不含有该关键词的数据条均被忽略)。
– 不可以有(排除指定关键词,含有该关键词的均被忽略)。
> 提高该条匹配数据的权重值。
< 降低该条匹配数据的权重值。
~ 将其相关性由正转负,表示拥有该字会降低相关性(但不像-将之排除),只是排在较后面权重值降低。
* 万用字,不像其他语法放在前面,这个要接在字符串后面。
” ” 用双引号将一段句子包起来表示要完全相符,不可拆字。
全文索引比 like + % 快 N 倍,但是可能存在精度问题
如果需要全文索引的是大量数据,建议先添加数据,再创建索引
MATCH()函数使用的字段名,必须要与创建全文索引时指定的字段名一致,且只能是同一个表的字段不能跨表