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 21 MySQL
解决Navicat for MySQL 连接 MySQL 报2005错误的问题
May 29 MySQL
MySQL8.0无法启动3534的解决方法
Jun 03 MySQL
mysql left join快速转inner join的过程
Jun 30 MySQL
mysql脏页是什么
Jul 26 MySQL
MySQL学习之基础操作总结
Mar 19 MySQL
MySQL中优化SQL语句的方法(show status、explain分析服务器状态信息)
Apr 09 MySQL
MySQL 条件查询的常用操作
Apr 28 MySQL
MYSQL中文乱码问题的解决方案
Jun 14 MySQL
MySQL约束(创建表时的各种条件说明)
Jun 21 MySQL
详解MySQL的内连接和外连接
May 08 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
使用TinyButStrong模板引擎来做WEB开发
2007/03/16 PHP
给apache2.2加上mod_encoding模块後 php5.2.0 处理url出现bug
2007/04/12 PHP
获取用户Ip地址通用方法与常见安全隐患(HTTP_X_FORWARDED_FOR)
2013/06/01 PHP
PHP实现对数组分页处理实例详解
2017/02/07 PHP
利用PHP获取汉字首字母并且分组排序详解
2017/10/22 PHP
深入理解JavaScript系列(6) 强大的原型和原型链
2012/01/15 Javascript
Javascript 闭包引起的IE内存泄露分析
2012/05/23 Javascript
setInterval()和setTimeout()的用法和区别示例介绍
2013/11/17 Javascript
Node.js入门教程:在windows和Linux上安装配置Node.js图文教程
2014/08/14 Javascript
jQuery中removeProp()方法用法实例
2015/01/05 Javascript
javascript实现密码强度显示
2015/03/18 Javascript
jQuery实现鼠标经过弹出提示信息的地图热点效果
2015/08/07 Javascript
jQuery+Ajax+PHP+Mysql实现分页显示数据实例讲解
2015/09/27 Javascript
最全面的JS倒计时代码
2016/09/17 Javascript
jsp 自动编译机制详细介绍
2016/12/01 Javascript
Textarea输入字数限制实例(兼容iOS&安卓)
2017/07/06 Javascript
Three.js利用顶点绘制立方体的方法详解
2017/09/27 Javascript
浅谈Vue.js组件(二)
2019/04/09 Javascript
纯异步nodejs文件夹(目录)复制功能
2019/09/03 NodeJs
通过GASP让vue实现动态效果实例代码详解
2019/11/24 Javascript
Vue学习之axios的使用方法实例分析
2020/01/06 Javascript
jQuery插件simplePagination的使用方法示例
2020/04/28 jQuery
Python splitlines使用技巧
2008/09/06 Python
Python中的pprint折腾记
2015/01/21 Python
python实现最长公共子序列
2018/05/22 Python
解决django model修改添加字段报错的问题
2019/11/18 Python
Python实现多线程下载脚本的示例代码
2020/04/03 Python
HTML5的结构和语义(3):语义性的块级元素
2008/10/17 HTML / CSS
皇家道尔顿官网:Royal Doulton
2017/12/06 全球购物
C++如何引用一个已经定义过的全局变量
2014/08/25 面试题
医学生个人求职信范文
2013/09/24 职场文书
妇女儿童发展规划实施方案
2014/03/16 职场文书
推广普通话演讲稿
2014/05/23 职场文书
幼儿园师德师风心得体会
2016/01/12 职场文书
《和时间赛跑》读后感3篇
2019/12/16 职场文书
Java 轮询锁使用时遇到问题
2022/05/11 Java/Android