MySQL 全文索引使用指南


Posted in MySQL onMay 25, 2021

全文索引需要特殊的查询语法。有没有索引都可以进行全文检索,但是存在索引时会提高匹配的速度。全文索引的索引通过特殊的结构存储以便于找到文档中包含搜索关键字对应的内容。在我们日常生活中,最常见的全文检索就是网络搜索引擎。虽然,网络搜索引擎的数据里十分庞大,并且通常也不会使用关系型数据库,但是原理是相似的。

全文索引支持通过基于字符(CHAR、VARCHAR 和 TEXT 类型的列)的检索,也可以支持自然语言模式(Natural Language Mode, 默认)和布尔模式 (Boolean Mode)。例如我们搜索“数据库引擎”的时候,内容中包括“数据库”、“引擎”和“数据库引擎”的内容都会检索出来。全文索引的实现有大量的限制,而且十分复杂。但是由于内置在MySQL服务端,而且对很多应用都能够满足要求,因此被广泛使用。

在MySQL5.6之前的版本中,只有 MyISAM 存储引擎支持全文索引。创建全文索引需要指定列标记为全文索引,如下面的 content 列。

CREATE TABLE t_news (
	id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
	content TEXT,
	author VARCHAR(32),
	title VARCHAR(128),
  FULLTEXT (content)
) ENGINE=InnoDB;

MySQL 5.6以前对中文搜索支持不是太好,需要自己进行分词后将段落预处理拆分成单词在入库。MySQL5.7.6后才有了内置的分词器 ngram。ngram 支持设置设置分词的长度,可以将中文按长度拆分为不同的单词(虽然不太智能,但满足大部分场景)。可以通过 MySQL 的全局变量ngram_token_size设置分词长度,默认是2,支持1-10可选。对于上面的例子,需要指定分词器构建全文索引。

CREATE TABLE t_news (
  id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
	content TEXT,
	author VARCHAR(32),
	title VARCHAR(128),
  FULLTEXT KEY idx(content) WITH PARSER ngram
) ENGINE=InnoDB;

插入一条数据测试。

INSERT INTO `t_news` 
(`id`, `content`, `author`, `title`) 
VALUES ('1', '我有一个数据库和引擎', '岛上码农', '数据库引擎');

在简单的模糊搜索中可以使用 LIKE 来完成,而对于全文检索需要使用如下方式的语句:

SELECT * FROM t_news 
WHERE MATCH (content) AGAINST ('数据 引擎' IN NATURAL LANGUAGE MODE)

通过这种方式可以检索出刚刚插入的内容,而如果使用 LIKE 是没法完成的。也支持使用相关性排序,再插入一条数据:

INSERT INTO `t_news`
(`id`, `content`, `author`, `title`) 
VALUES (2,'我有一个数据库','岛上码农','数据库')

然后执行排序查询:

SELECT *, MATCH (content) AGAINST ('数据 引擎' ) AS relevance
FROM t_news 
WHERE MATCH (content) AGAINST ('数据 引擎' ) 
ORDER BY relevance ASC

这里将匹配值作为一列查询,以便使用其别名进行排序。相关性越高,对应的 relevance 值越大,因此可以用作排序。入股不相关,那么 relevance 的值为0。

布尔模式可以做更多的控制,例如包括使用+号保留匹配结果和使用-号排除匹配结果,下面的就匹配了数据,而排除了包含引擎的数据。更多操作符可以参考 MySQL 的官方文档:全文索引操作符

SELECT * FROM t_news 
WHERE MATCH (content) AGAINST ('+数据* -引擎' IN BOOLEAN MODE);

以上就是MySQL 全文索引使用指南的详细内容,更多关于MySQL 全文索引的资料请关注三水点靠木其它相关文章!

MySQL 相关文章推荐
MySQL 分组查询的优化方法
May 12 MySQL
MySQL 存储过程的优缺点分析
May 20 MySQL
Mysql Online DDL的使用详解
May 20 MySQL
MySQL 发生同步延迟时Seconds_Behind_Master还为0的原因
Jun 21 MySQL
MySQL悲观锁与乐观锁的实现方案
Nov 02 MySQL
一文带你探究MySQL中的NULL
Nov 11 MySQL
Nebula Graph解决风控业务实践
Mar 31 MySQL
解决MySQL Varchar 类型尾部空格的问题
Apr 06 MySQL
Mysql查询时间区间日期列表,不会由于数据表数据影响
Apr 19 MySQL
MYSQL常用函数介绍
May 05 MySQL
讲解MySQL增删改操作
May 06 MySQL
MySql中的json_extract函数处理json字段详情
Jun 05 MySQL
52条SQL语句教你性能优化
May 25 #MySQL
简单了解 MySQL 中相关的锁
mysql在项目中怎么选事务隔离级别
.Net Core导入千万级数据至Mysql的步骤
May 24 #MySQL
MySQL大小写敏感的注意事项
May 24 #MySQL
MySQL 使用事件(Events)完成计划任务
May 24 #MySQL
MySQL触发器的使用
May 24 #MySQL
You might like
探讨:使用XMLSerialize 序列化与反序列化
2013/06/08 PHP
PHP动态页生成静态页的3种常用方法
2014/11/13 PHP
php实现搜索类封装示例
2016/03/31 PHP
Zend Framework前端控制器用法示例
2016/12/11 PHP
微信公众号开发之获取位置信息php代码
2018/06/13 PHP
JavaScript高级程序设计(第3版)学习笔记10 再访js对象
2012/10/11 Javascript
JavaScript中for..in循环陷阱介绍
2013/11/12 Javascript
Jquery实现侧边栏跟随滚动条固定(兼容IE6)
2014/04/02 Javascript
js获取select默认选中的Option并不是当前选中值
2014/05/07 Javascript
DOM节点深度克隆函数cloneNode()用法实例
2015/01/12 Javascript
jquery滚动特效集锦
2015/06/03 Javascript
基于Jquery easyui 选中特定的tab
2015/11/17 Javascript
jQuery拖拽排序插件制作拖拽排序效果(附源码下载)
2016/02/23 Javascript
jQuery 出现Cannot read property ‘msie’ of undefined错误的解决方法
2016/11/23 Javascript
使用vue.js2.0 + ElementUI开发后台管理系统详细教程(一)
2017/01/21 Javascript
JS实现数组去重方法总结(六种方法)
2017/07/14 Javascript
vue配置请求本地json数据的方法
2018/04/11 Javascript
vuex与组件联合使用的方法
2018/05/10 Javascript
Laravel 如何在blade文件中使用Vue组件的示例代码
2020/06/28 Javascript
解决ant design vue 表格a-table二次封装,slots渲染的问题
2020/10/28 Javascript
python的exec、eval使用分析
2017/12/11 Python
Python使用matplotlib实现基础绘图功能示例
2018/07/03 Python
基于Python实现迪杰斯特拉和弗洛伊德算法
2020/05/27 Python
详解python3 + Scrapy爬虫学习之创建项目
2019/04/12 Python
python selenium循环登陆网站的实现
2019/11/04 Python
Python实现ElGamal加密算法的示例代码
2020/06/19 Python
荷兰超市:DEEN
2018/03/14 全球购物
琳达·法罗眼镜英国官网:Linda Farrow英国
2021/01/19 全球购物
幼师专业求职推荐信
2013/11/08 职场文书
会议室标语
2014/06/21 职场文书
计算机网络专业自荐信
2014/07/04 职场文书
家庭贫困证明范本(经典版)
2014/09/22 职场文书
领导班子个人对照检查材料(群众路线)
2014/09/26 职场文书
2014最新自愿离婚协议书范本
2014/11/19 职场文书
贷款收入证明格式
2015/06/24 职场文书
毕业生自荐求职信书写的技巧
2019/08/26 职场文书