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中 unique列插入重复值该怎么解决呢
May 26 MySQL
MySQL不使用order by实现排名的三种思路总结
Jun 02 MySQL
MySQL 常见的数据表设计误区汇总
Jun 07 MySQL
SQL实现LeetCode(196.删除重复邮箱)
Aug 07 MySQL
解决Mysql多行子查询的使用及空值问题
Jan 22 MySQL
你真的会用Mysql的explain吗
Mar 31 MySQL
Golang连接并操作MySQL
Apr 14 MySQL
Mysql查询时间区间日期列表,不会由于数据表数据影响
Apr 19 MySQL
深入理解MySQL中MVCC与BufferPool缓存机制
May 25 MySQL
MySQL数据库安装方法与图形化管理工具介绍
May 30 MySQL
MySQL数据库之内置函数和自定义函数 function
Jun 16 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
php自动给文章加关键词链接的函数代码
2012/11/29 PHP
PHP设计模式之迭代器模式的深入解析
2013/06/13 PHP
体育彩票排列三组选三算法分享
2014/03/07 PHP
php基于环形链表解决约瑟夫环问题示例
2017/11/07 PHP
Laravel validate error处理,ajax,json示例
2019/10/25 PHP
JavaScript小技巧 2.5 则
2010/09/12 Javascript
JQuery将文本转化成JSON对象需要注意的问题
2011/05/09 Javascript
JQuery实现简单时尚快捷的气泡提示插件
2012/12/20 Javascript
jquery通过select列表选择框对表格数据进行过滤示例
2014/05/07 Javascript
js实现照片墙功能实例
2015/02/05 Javascript
一系列Bootstrap导航条使用方法分享
2016/04/29 Javascript
React Native验证码倒计时工具类分享
2017/10/24 Javascript
js导出Excel表格超出26位英文字符的解决方法ES6
2017/11/15 Javascript
原生JS实现列表子元素顺序反转的方法分析
2018/07/02 Javascript
Webstorm2016使用技巧(SVN插件使用)
2018/10/29 Javascript
Vue 一键清空表单的实现方法
2020/02/07 Javascript
Nuxt.js 静态资源和打包的操作
2020/11/06 Javascript
[05:31]DOTA2英雄梦之声_第04期_光之守卫
2014/06/23 DOTA
[00:43]拉比克至宝魔导师密钥展示
2018/12/20 DOTA
Python线性方程组求解运算示例
2018/01/17 Python
python实现在图片上画特定大小角度矩形框
2018/10/24 Python
python3+openCV 获取图片中文本区域的最小外接矩形实例
2020/06/02 Python
Python如何将装饰器定义为类
2020/07/30 Python
Python发送邮件实现基础解析
2020/08/14 Python
安装pyecharts1.8.0版本后导入pyecharts模块绘图时报错: “所有图表类型将在 v1.9.0 版本开始强制使用 ChartItem 进行数据项配置 ”的解决方法
2020/08/18 Python
HTML5制作表格样式
2016/11/15 HTML / CSS
手机配件第一品牌:ZAGG
2017/05/28 全球购物
葡萄牙语专业个人求职信
2013/12/10 职场文书
给老师的一封建议书
2014/03/13 职场文书
社区网格化管理实施方案
2014/03/21 职场文书
委托书格式范文
2015/01/28 职场文书
保安辞职信范文
2015/02/28 职场文书
学校党员干部承诺书
2015/05/04 职场文书
2015年高一班主任工作总结
2015/05/13 职场文书
Python绘制散乱的点构成的图的方法
2022/04/21 Python
关于mysql中string和number的转换问题
2022/06/14 MySQL