当前位置: 首页 > news >正文

MySQL + ngram 最佳实践:轻量级中文 混合内容全文搜索方案

MySQL 的 FULLTEXT 配合 ngram 分词器,是一种 轻量但强大 的解决方案,适合处理中文、带符号文本(如 N3-2016-7语法7)的全文搜索。

本文将介绍 MySQL + ngram 的最佳使用方式,包括:

✅ 配置环境
✅ 建立索引
✅ 查询语法
✅ 性能优化
✅ 常见问题


🧠 一、ngram 分词器简介

ngram(N-Gram)分词 是一种固定长度切词的方式。
例如对词语 N3-2016

  • ngram_token_size = 2 → 分为:N33--2200116

  • ngram_token_size = 3 → 分为:N3-3-2-20201016

适合处理:

  • 无自然分隔符的语言(如中文)

  • 编码、编号、短词(如 SKU、题号、文章编号)


🛠️ 二、环境要求

  • ✅ MySQL 5.7.6+(推荐 8.0+)

  • ✅ 表引擎必须是 InnoDB

  • ✅ 字符集推荐使用 utf8mb4


⚙️ 三、开启 ngram 分词功能

1. 查看当前系统设置

SHOW VARIABLES LIKE 'ngram_token_size';

默认值是 2,你也可以全局修改:

SET GLOBAL ngram_token_size = 2;  -- 修改为 2-gram

⚠️ 注意:修改后需 重启 MySQL 服务生效,且需 重建全文索引


📑 四、表结构与索引设计

示例表:

CREATE TABLE t_question (
  id INT PRIMARY KEY AUTO_INCREMENT,
  question_content TEXT,
  FULLTEXT (question_content) WITH PARSER ngram
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

WITH PARSER ngram 是关键
✅ 推荐为 TEXT 字段创建全文索引


若已有表:

ALTER TABLE t_question
ADD FULLTEXT(question_content) WITH PARSER ngram;

🔍 五、查询语法示例

1. 普通全文搜索(自动分词)

SELECT * FROM t_question
WHERE MATCH(question_content)
AGAINST('N3 2016' IN BOOLEAN MODE);

✅ 空格隔开多个关键词
✅ 可匹配如 N3-2016-7语法7


2. 精准匹配(AND)

SELECT * FROM t_question
WHERE MATCH(question_content)
AGAINST('+N3 +2016' IN BOOLEAN MODE);

+ 表示必须包含


3. 模糊匹配(带通配符)

SELECT * FROM t_question
WHERE MATCH(question_content)
AGAINST('N3* 2016*' IN BOOLEAN MODE);

⚠️ 通配符仅在 BOOLEAN MODE 下部分生效,ngram 本身已实现了前缀模糊能力。


4. 预处理数据以提高匹配率

将符号(如 -/)替换为空格以便更好分词:

UPDATE t_question
SET question_content = REPLACE(question_content, '-', ' ');

也可以在搜索时处理关键词:

SELECT * FROM t_question
WHERE MATCH(question_content)
AGAINST(REPLACE('N3-2016-7', '-', ' ') IN BOOLEAN MODE);

🚀 六、性能优化建议

优化项建议
✅ 字段类型使用 TEXT 类型,不建议用 VARCHAR 超过 767 字节
✅ 字符集使用 utf8mb4,兼容所有字符
✅ 查询语法使用 BOOLEAN MODE 支持更多操作符
✅ 排序限制查询加 LIMIT、避免 ORDER BY MATCH() 造成排序慢
✅ 表数据变更更新/删除后需注意索引同步,定期优化表(OPTIMIZE TABLE

🧱 七、MySQL ngram 与其他方案对比

方案优点缺点适用场景
LIKE %keyword%简单性能差小数据量
FULLTEXT(默认)快、支持英文不支持中文英文搜索
FULLTEXT + ngram支持中文和符号、轻量精度略低于 NLP 分词中小项目、编码类内容搜索
Elasticsearch强大、支持复杂分析运维成本高搜索引擎、大数据量
Jieba / HanLP可控性强、精度高不支持数据库原生索引NLP 应用、离线分析

🧩 八、常见问题 FAQ

❓1. 中文搜索无结果?

请确认是否:

  • 使用了 WITH PARSER ngram

  • 字符集为 utf8mb4

  • 数据和查询内容一致

  • ngram_token_size 合适


❓2. 如何支持带符号内容(如 N3-2016)?

使用 ngram 可将其切割为 N33--2 等小词组,实现模糊匹配。


❓3. 索引是否生效?

可用以下命令查看全文索引:

SHOW INDEX FROM t_question;

也可 EXPLAIN 查询看是否使用了 FULLTEXT 索引。


✅ 九、最佳实践总结

项目推荐做法
✅ 字段TEXT 类型字段建全文索引
✅ 索引使用 WITH PARSER ngram
✅ 查询使用 AGAINST + BOOLEAN MODE + 空格关键词
✅ 兼容性使用 MySQL 8.0+,InnoDB 引擎
✅ 性能合理使用 LIMIT,避免排序瓶颈
✅ 文本规范化去除无意义符号、统一大小写,提升匹配率

用 MySQL 做中文和混合搜索?别忘了加上 ngram,轻量、原生、好用!

相关文章:

  • 秒杀系统设计方案
  • 一周学会Pandas2 Python数据处理与分析-NumPy数组的索引和切片
  • ResNet改进(21):基于ECA注意力机制的ResNet18网络实现
  • golang 内存逃逸 栈与堆区别
  • 如何解决:http2: Transport received Server‘s graceful shutdown GOAWAY
  • qemu仿真调试esp32,以及安装版和vscode版配置区别
  • 字符串操作栈和队列
  • MES生产工单管理系统,Java+Vue,含源码与文档,实现生产工单全流程管理,提升制造执行效率与精准度
  • C++使用Qt Charts可视化大规模点集
  • matlab中排序函数sortrows的用法
  • 快速入手-前后端分离Python权限系统 基于Django5+DRF+Vue3.2+Element Plus+Jwt
  • SQL注入流量分析
  • 【算法】二分查找
  • 单片机实现触摸按钮执行自定义任务组件
  • IntelliJ IDEA下开发FPGA——FPGA开发体验提升__下
  • 量子计算模拟中的GPU加速:从量子门操作到Shor算法实现
  • 嵌入式硬件实战基础篇(三)-四层板PCB设计-步进电机驱动(TMC2208/TMC2209)
  • 双周报Vol.69: C FFI 支持 borrow、新增.mbt.md测试与调试、WASM 后端支持extern type..
  • Python----计算机视觉处理(Opencv:道路检测完整版:透视变换,提取车道线,车道线拟合,车道线显示,)
  • 解决:Fontconfig head is null, check your fonts or fonts configurat
  • 人民网:激发博物馆创新活力,让“过去”拥有“未来”
  • 陈刚:推动良好政治生态和美好自然生态共生共优相得益彰
  • 法律顾问被控配合他人诈骗酒店资产一审判8年,二审辩称无罪
  • 独家 |《苏州河》上海上演,编剧海飞:上海的风能吹透我
  • “大型翻车现场”科技满满,黄骅打造现代化港口和沿海新城典范
  • 张广智︱“编年事辑”:打开学人心路历程的窗户