简介MySQL全文索引是在基于文本的列(char、varchar或text列)上创建的,以提高对这些包含的数据进行查询和DML操作的效率列。全文索引被定义为CREATETABLE语句的一部分,或使用ALTERTABLE或CREATEINDEX附加到现有表。搜索语法是:match(field1,field2,…)against('keyword')。更多使用方法和详细信息,请参考MySQL全文索引版本说明官方文档。在MySQL5.6之前的版本中,只有MyISAM存储引擎支持全文索引。MySQL5.6及以后版本,MyISAM和InnoDB存储引擎都支持全文索引。全文索引只有字段数据类型为char、varchar、text及其series时才能建立全文索引。全文索引创建说明:搜索时,中文分词支持默认不友好。如果有中日韩文分词需求,需要在创建索引时声明分词插件ngram。语法是可选的[使用解析器ngram]。如果存在`t_stu`则删除表;CREATETABLE`t_stu`(`id`int(10)UNSIGNEDNOTNULLAUTO_INCREMENT,`name`varchar(255)CHARACTERSETutf8mb4COLLATEutf8mb4_general_ciNULLDEFAULTNULL,`kecheng`varchar5)varchar(2SETutf8mb4COLLATEutf8mb4_general_ciNULL,DEFAULTNULL`fenshu`int(11)NULLDEFAULTNULL,`keyword`varchar(255)CHARACTERSETutf8mb4COLLATEutf8mb4_general_ciNULLDEFAULTNULL,PRIMARYKEYFT_LTEFUSIND(`id`)(`keyword`)WITHPARSER`ngram`)ENGINE=InnoDBCHARACTERSET=utf8mb4COLLATE=utf8mb4_general_ciROW_FORMAT=Dynamic;------------------------------t_stu的记录---------------------------INSERTINTO`t_stu`VALUES(1,'张三','中国人',81,'张三');INSERTINTO`t_stu`VALUES(2,'张三','数学',75,'张三数学');INSERTINTO`t_stu`VALUES(3,'李四','中文',76,'李SiChinese');INSERTINTO`t_stu`VALUES(4,'李斯','数学',90,'李斯数学');INSERTINTO`t_stu`VALUES(5,'王武','中文',81,《王舞中国》);插入整数o`t_stu`VALUES(6,'王舞','数学',100,'王舞数学');INSERTINTO`t_stu`VALUES(7,'王舞','英语',90,'王舞英语'');createindex方法创建DROPTABLEIFEXISTS`t_stu`;CREATETABLE`t_stu`(`id`int(10)unsignedNOTNULLAUTO_INCREMENT,`name`varchar(255)DEFAULTNULL,`kecheng`varchar(255)DEFAULTNULL,`fenshu`int(11)DEFAULTNULL,`keyword`varchar(255)DEFAULTNULL,PRIMARYKEY(`id`)USINGBTREE)ENGINE=InnoDBDEFAULTCHARSET=utf8mb4ROW_FORMAT=DYNAMIC;INSERTINTO`t_stu`VALUES(1,'张三','Chinese',81,'张三');INSERTINTO`t_stu`VALUES(2,'张三','数学',75,'张三');INSERTINTO`t_stu`VALUES(3,'LiSi','Chinese',76,'LiSiChinese');INSERTINTO`t_stu`VALUES(4,'LiSi','Mathematics',90,'LiSiMath');INSERTINTO`t_stu`VALUES(5,'WangWu','Chinese',81,'WangWuChinese');INSERTINTO`t_stu`VALUES(6,'WangWu','数学',100,'WangWu数学');INSERTINTO`t_stu`VALUES(7,'WangWu','English',90,'WangWuEnglish');--createindex方法创建CREATEFULLTEXTINDEXft_indexONt_stu(keyword)WITHPARSERngram;altertableway创造。altertablet_stuaddfulltextindexft_index(keyword)withparserngram;由altertable创建。altertablet_stuaddfulltextindexft_index(keyword)withparserngram;通过dropindex删除全文索引。在t_stu上删除索引ft_index;通过altertable删除。altertablet_studropindexft_index;完全使用语法select*fromt_stuwherematch(keyword)against('张三');Tips:match()函数中指定的列必须与索引中指定的列完全一致,否则不起作用使用全文索引,全文索引不记录关键字来自哪一列。发现问题select*fromt_stuwherematch(keyword)against('Zhang');没有数据,或数据不完整。从结果可以看出,只有“张三”的输入匹配到了一条记录。了解过ElasticSearch、Lucene、Solr、MeiliSearch等搜索中间件的人对这样的结果的真实性并不满意。应检查预期结果。有3条记录是正常的。造成这种情况的一个关键原因是MySQL对应执行引擎下的全文索引的**【最小搜索长度】**。MySQL中的全文索引有两个关键变量,分别是最小搜索长度和最大搜索长度,对于长度小于最小搜索长度和大于最大搜索长度的词,将不会被索引。也就是说,单词的长度必须在上述两个变量的区间内。可以通过命令查看showvariableslike'%ft%';----------------------------//InnoDBinnodb_ft_min_token_size=3;innodb_ft_max_token_size=84;//MyISAMft_min_word_len=4;ft_max_word_len=84;可以看到在InnoDB引擎下最小搜索长度默认是3,在MyISAM引擎下是4,所以MySQL全文索引只会索引长度大于等于3或者4的词。基于InnoDB,只有“java”和“java”的长度大于等于3,而基于MyISAM,只有“java”的长度大于等于4。解决问题由于最小搜索长度没有满足要求,需要修改配置。在/etc/my.cnf下的mysqlId中添加如下内容。当然你也可以修改最大搜索长度,但不是必须的。innodb_ft_min_token_size=1ft_min_word_len=1完成后重启MySQL服务器,修复全文索引。修复全文索引语句如下,但一般建议删除索引重建索引。快速修复表t_stu;到目前为止,还没有达到最终的效果。搜索关键字“张”时,没有结果集,因为MySQL的全文索引有自然语言全文索引和布尔全文索引两种选择:1.自然语言全文索引默认,或者当使用innaturallanguagemode修饰符时,match()函数对文本集合执行自然语言搜索。以上例子都是基于自然语言的全文索引。自然语言搜索引擎将计算每个文档对象与查询的相关性。这里,相关性是基于匹配关键字的数量和关键字在文档中出现的次数。在整个索引中出现次数较少的术语在匹配时更相关。反之,不会搜索非常常见的词,如果一个词出现在超过50%的记录中,那么自然语言搜索就不会搜索这样的词。这个机制也比较容易理解。比如一个数据表,一篇一篇的存储文章。文章中常用词、语气词等出现频率高。搜索这些词是没有意义的。搜索具有文章的特点。词,以区别文章。2.布尔全文索引在布尔搜索中,您可以自定义查询中搜索词的相关性。在编写布尔搜索查询时,您可以通过一些前缀修饰符自定义搜索。MySQL内置的修饰符,在上面查询最小搜索长度时,搜索结果ft_boolean_syntax变量的值为内置修饰符,相关修饰符的具体作用可以在手册中找到。上面的情况可以用布尔来满足。select*fromt_stuwherematch(keyword)against('*Zhang*'INBOOLEANMODE);select*fromt_stuwherematch(keyword)against('Zhang*'INBOOLEANMODE);数据可以查出来。充分实现点赞效果。通过自然语言搜索模式查询SELECT*FROMarticlesWHEREMATCH(title,body)AGAINST('keyword'INNATURALLANGUAGEMODE);布尔全文搜索方式查询2.1管理和数据库匹配记录SELECT*FROMarticlesWHEREMATCH(title,body)AGAINST('+database+management'INBOOLEANMODE);2.2将记录与数据库匹配但不进行管理SELECT*FROMarticlesWHEREMATCH(title,body)AGAINST('+database-management'INBOOLEANMODE);2.3匹配MySQL,但降低数据库相关性SELECT*FROMarticlesWHEREMATCH(title,body)AGAINST('>database+MySQL'INBOOLEANMODE);select*fromt_stuwherematch(keyword)against('*王五*喜欢在布尔模式下学习*英语*');匹配度高的排在最前面。总结MySQL全文索引一开始只支持英文,因为英文单词之间有空格,用空格作为分词分隔符很方便。亚洲字符,如中文、日文、中文等,没有空格,这造成了一定的限制。不过从MySQL5.7.6开始,引入了ngram全文分析器来解决这个问题,对MyISAM和InnoDB引擎都有效。事实上,MyISAM存储引擎对全文索引的支持有很多限制,比如表级锁对性能的影响、数据文件崩溃、崩溃后的恢复等,这使得MyISAM的全文索引不适合适用于很多应用场景。所以,大多数情况下,建议是使用其他方案,比如第三方插件如MeiliSearch、ElasticSearch等,或者使用InnoDB存储引擎的全文索引。注意在使用全文索引之前,先明确版本支持。全文索引比like+%快N倍,但可能存在精度问题。如果需要对大量数据进行全文索引,建议先添加数据,再创建索引。中文可以使用MySQL5.7.6以后的版本,或者第三方插件。
