MySQL 5.7+ 使用 ngram 实现中文全文检索
在早期的 MySQL 版本(5.7.6之前)中,全文索引仅支持英文,无法直接对中文进行分词检索。若要在中文场景下使用全文搜索,往往需要引入 Elasticsearch 等专用搜索引擎。然而,从 MySQL 5.7.6 开始,InnoDB 引擎内置了 ngram 全文解析器,能够原生支持中文、日文和韩文的单字或短语切分。本文将演示如何在 MySQL 5.7 及更高版本中,利用 ngram 实现无需额外中间件的中文全文检索。
1. 准备数据表与创建全文索引
在使用 ngram 之前,确保你的表引擎为 InnoDB,且字符集支持 UTF-8(通常使用 utf8mb4)。可以在建表语句的 FULLTEXT KEY 定义末尾指定 WITH PARSER 'ngram'。
CREATE TABLE `tbl_article_content` (
`id` bigint(40) NOT NULL AUTO_INCREMENT,
`article_title` varchar(60) COMMENT '标题',
`article_summary` varchar(120) COMMENT '摘要',
`article_content` text NOT NULL COMMENT '正文内容',
`create_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`) USING BTREE,
FULLTEXT KEY `ft_content` (`article_content`) WITH PARSER `ngram`
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
关键点说明:
- 解析器指定:
WITH PARSER 'ngram'明确告诉 MySQL 使用该分词器处理该列。 - 最小长度限制:
ngram默认最小搜索长度为 2 个字符(即“二分”切分)。例如搜索 “人工智能”,会拆分为 “人工”、“工智”、“智能”。可通过全局变量ngram_token_size调整,但需注意磁盘占用增加。
2. 动态添加全文索引
如果已经创建了表,可以通过 ALTER TABLE 追加全文索引,同样需要指定解析器:
ALTER TABLE `tbl_article_content`
ADD FULLTEXT INDEX `idx_ngram_content` (`article_content`) WITH PARSER `ngram`;
3. 导入测试数据
插入包含中文内容的记录:
INSERT INTO `tbl_article_content` (`article_title`, `article_content`) VALUES
('AI技术趋势', '近年来人工智能技术在各个行业得到了广泛应用。'),
('深度学习基础', '卷积神经网络是图像识别的核心算法之一。');
4. 执行中文全文检索
使用 MATCH ... AGAINST 语法进行自然语言搜索(Natural Language Mode):
SELECT * FROM tbl_article_content
WHERE MATCH(article_content) AGAINST('人工智能');
由于 ngram 的分词特性:
- 连续匹配:输入“人工智能”,因为包含了连续的子串组合,能命中第一条数据。
- 短词过滤:如果你搜索单个汉字如 “人”,可能不会返回结果,因为默认
ngram_token_size = 2,系统认为 1 个字不足以构成有意义的 token。
5. 进阶:布尔模式与修改搜索大小
布尔全文搜索 (Boolean Full-Text Search)
若需要进行更复杂的逻辑判断(如排除特定词),可使用 IN BOOLEAN MODE:
SELECT * FROM tbl_article_content
WHERE MATCH(article_content) AGAINST('人工智能 -深度' IN BOOLEAN MODE);
这会查找包含“人工智能”但不包含“深度”的记录。
调整 Ngram Token Size
若业务场景需要按单字(如搜索“电”)进行搜索,可修改全局变量(重启后失效,建议写入 my.cnf):
SET GLOBAL ngram_token_size = 1;
注意:修改此参数后,现有的 ngram 全文索引将不可用,必须重建所有相关表的全文索引,否则查询会报错或结果为空。
总结
对于中小型项目,利用 MySQL 5.7+ 的 ngram 解析器可以避免引入 ES 带来的架构复杂性。虽然它在分词粒度上不如专业分词器灵活,但足以应对大多数基于关键词匹配的业务需求。关键在于理解其 ngram_token_size 的限制以及适用 Match...Against 的标准语法。以上就是 MySQL 5.7+ 使用 ngram 实现中文全文检索的详细内容,更多关于 MySQL 全文索引优化的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









