简述
MySQL 全文索引是一种用于搜索文本内容的索引技术。它允许在 MySQL 数据库中执行高效的全文搜索操作,而不仅仅是简单的精确匹配。
全文索引可以用于在文本字段(如 VARCHAR 或 TEXT 类型的字段)中查找特定的关键词、短语或表达式。它有助于提高搜索的速度和准确性,并支持高级搜索功能,如模糊匹配、近似匹配和排序。
要使用全文索引,首先需要在要搜索的表中创建全文索引。可以通过使用 FULLTEXT 索引类型并指定要索引的列来实现。例如,假设我们有一个包含标题和内容的文章表,可以如下创建全文索引。
sql
CREATE FULLTEXT INDEX idx_fulltext_search ON articles(title, content);
创建完全文索引后,可以使用 MATCH AGAINST 语句执行全文搜索。MATCH AGAINST 语句接受一个搜索条件作为参数,并返回与条件匹配的行。
例如,以下是在文章表中执行全文搜索的示例。
sql
SELECT * FROM articles WHERE MATCH(title, content) AGAINST('keyword');
在上面的示例中,keyword 是要搜索的关键词。
注意,全文索引只能用于 MyISAM 和 InnoDB 存储引擎,而不适用于其他存储引擎(如 MEMORY 或 CSV)。此外,全文索引还受到MySQL 版本和配置的限制,因此在使用全文索引之前,需要先了解和确认 MySQL 版本和配置是否支持。
创建全文索引的语法
sql
CREATE FULLTEXT INDEX index_name ON table_name ( column_name ) [ WITH PARSER parser_name]
index_name 是要创建的索引的名称,table_name 是要创建索引的表的名称,column_name 是要创建索引的列的名称。WITH PARSER 子句是可选的,并且可以用于指定在创建索引时要使用的解析器。
全文索引只能用于 CHAR、VARCHAR、TEXT 和 BLOB 类型的字段。此外,在 MySQL 5.6 版本以前,全文索引只支持 MyISAM 存储引擎,而在 MySQL 5.6 版本以后,InnoDB 存储引擎也支持全文索引。
ngram 解析器
内置的 FULLTEXT 解析器通过查找特定的分隔符来确定单词的开始和结束位置,例如:空格、逗号、点号。如果单词之间没有分隔符(例如中文),则内置的 FULLTEXT 解析器无法确定单词的开始或结束位置。
这时可以使用 ngram 解析器插件(用于中文、日文或韩文)或 MeCab 解析器插件(用于日文)创建 FULLTEXT 索引。
自然语言模式和布尔模式
在 MySQL 中,全文搜索支持两种主要的查询模式:自然语言模式和布尔模式。这两种模式的主要区别在于它们如何处理搜索查询和返回结果。
自然语言模式(IN NATURAL LANGUAGE MODE)
全文搜索中的自然语言模式是默认模式,它使用自然语言处理技术来解析搜索查询并返回最相关的结果。自然语言模式会对搜索查询进行分词和停用词处理,并根据每个词语在文档中的重要性对文档进行打分。然后,MySQL 会根据文档的得分对搜索结果进行排序,并返回最相关的文档。
注意,自然语言模式并不要求查询的短语必须完全匹配,所以在准确率上存在一定的误差。
布尔模式(IN BOOLEAN MODE)
全文搜索中的布尔模式允许用户使用布尔运算符(AND、OR、NOT)来组合搜索条件,并通过对文档进行匹配来确定文档是否符合查询条件。在布尔模式下,MySQL 会将搜索查询视为布尔表达式,并使用布尔运算符来确定每个文档是否符合查询条件。
综上所述,自然语言模式和布尔模式都有各自的优缺点,在使用全文搜索时,应根据具体情况选择合适的查询模式。
- 自然语言模式通常更易于使用和理解,但可能会导致一些不准确的结果
- 布尔模式更灵活,可以更精确地控制搜索条件,但需要更多的查询语法知识
全文索引中常用的操作符
布尔模式操作符
- "+"符号:指定关键词必须存在
- "-"符号:指定关键词不能存在
- ">"符号:指定关键词要求存在,并且在搜索结果中具有更高的权重
- "<"符号:指定关键词要求存在,并且在搜索结果中具有更低的权重
- "*"符号:用于在关键词的末尾表示通配符,例如用于匹配单词的不同形态
自然语言操作符
- IN NATURAL LANGUAGE MODE 关键词:用于指定自然语言模式的全文搜索。在这种模式下,搜索引擎会根据自然语言的语法和语义进行匹配
全文索引与 LIKE
全文索引和 LIKE 操作都可以用于文本搜索,但它们有一些关键的区别。
全文索引是一种更高级的搜索方法,它使用特定的数据结构和算法来支持快速和高效的文本搜索。全文索引在搜索过程中考虑了词语的语义和上下文,可以实现更准确的匹配和更高的搜索性能。它支持高级搜索功能,如模糊匹配、近似匹配和排序,并且通常比使用 LIKE 更快。
相比之下,LIKE 操作是 SQL 中使用的一种基本的模式匹配方法。它根据通配符(如 % 和 _)来匹配字符串,并返回与匹配模式相符的结果。但是,LIKE 操作通常比全文索引更慢,尤其是在大型数据集上,因为它需要在整个文本字段上进行逐一比较。
全文索引的优点是可以快速查找特定的关键词、短语或表达式,而且在搜索过程中可以更好地理解文本的上下文关系。它适用于需要更高级搜索功能和更高性能的场景,例如全文搜索引擎或文本检索系统。
然而,如果只需要简单的模式匹配,而不需要考虑文本的语义或上下文关系,那么使用 LIKE 操作可能是足够的。
简单示例
sql
CREATE TABLE `schools` (
`id` BIGINT ( 0 ) NOT NULL AUTO_INCREMENT,
`name` VARCHAR ( 512 ) CHARACTER
SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '学校名称',
`pinyinName` VARCHAR ( 1024 ) CHARACTER
SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT '' COMMENT '学校名称拼音',
`shortName` VARCHAR ( 256 ) CHARACTER
SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '简称, 多个用逗号隔开',
`pinyinShortName` VARCHAR ( 512 ) CHARACTER
SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT '' COMMENT '简称拼音',
`regionId` BIGINT ( 0 ) NOT NULL COMMENT '地区id',
PRIMARY KEY ( `id` ) USING BTREE,
INDEX `schools_region_id` ( `regionId` ) USING BTREE,
FULLTEXT INDEX `schools_name` ( `name` ) WITH PARSER `ngram`,
FULLTEXT INDEX `schools_pinyin_name` ( `pinyinName` ),
FULLTEXT INDEX `schools_short_name` ( `shortName` )
) ENGINE = INNODB AUTO_INCREMENT = 1 CHARACTER
SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '学校表' ROW_FORMAT = Dynamic;
SELECT
`id`,
`name`,
`shortName`,
`pinyinName`,
`stages`,
`regionId`
FROM
`schools` AS `SchoolModel`
WHERE
( MATCH ( NAME ) AGAINST ( '+深圳市 +大鹏 +新区 +大鹏 +中心小学 深圳市大鹏新区大鹏中心小学' IN BOOLEAN MODE ) OR NAME LIKE '%深圳市大鹏新区大鹏中心小学%' )
AND `SchoolModel`.`regionId` IN ( 1 );
参考资料