MySql的Ngram全文索引

article/2025/9/26 19:15:24

前言

在我们日常开发中,很多时候会遇到对数据库中某个字段模糊查询的需求,也就是like某个字段,但是很多公司像阿里,京东都禁止使用like来对数据库进行模糊查询,原因是啥呢?
我们先来看下面三条语句

其中title添加了索引

1.SELECT id,title from test_user where title like '张三%'
2.SELECT id,title from test_user where title like '%张三'
3.SELECT id,title from test_user where title like '%张三%'

上面三条语句只有第一条可能走索引,是否走索引还要看MySQL查询时索引的选择性问题,如果表中有十万条数据,title中含有张三的数据只有几百条时,索引的选择性很好,MySQL就会使用title索引,如果十万条数据中有九万九千条数据的title含有张三,那这次查询的索引选择性会非常差,就会走全表扫描,效率极其低下。
第二条和是第三条语句是一定不会走索引的,因为MySQL的索引是按照从前到后依次排列的。

方案1

可能这时候会想到新增一个专门用来做全文检索的工具,比如ElasticSearch,利用阿里的Canal中间件来订阅MySQL的binlog,将MySQL中的数据同步到ElasticSearch,但是如果之前没用ElasticSearch,只是只是对短文本全文检索而去新增ElasticSearch,显然有点得不偿失而且会增加开发和运维的成本,而且像ElasticSearch这种数据库也一定要保证高可用,就需要最少三台来组成一个高可用集群,而且通过订阅binlog的方式,也会影响数据的一致性,需要在架构和编码的过程中新增很多需要考虑的因素,所以要尽量简单方便的情况下实现全文检索,使用ElasticSearch并不是一个最好的方案。

方案2

这时候我们可以考虑一下用MySql5.7.6之后新增的全文解析器Ngram
ngram全文解析器适合对短文本来进行全文检索,如果是长文本或者大数据量的话ElasticSearch仍然是不可或缺的。

ngram的使用特点

  1. 可以支持中文、日文、韩文分词
  2. 只有char、varchar、text类型字段能创建全文索引
  3. 英文分词用空格,逗号;中文分词用 ngram_token_size 设定

ngram的检索方式

自然语言模式(NATURAL LANGUAGE MODE)

自然语言模式是MySQL 默认的全文检索模式。自然语言模式不能使用操作符,不能指定关键词必须出现或者必须不能出现等复杂查询

BOOLEAN模式(BOOLEAN MODE)

BOOLEAN模式可以使用操作符,可以支持指定关键词必须出现或者必须不能出现或者关键词的权重高还是低等复杂查询

BOOLEAN的关键字

1.'dog cat'
字段当中加一个空格,表示查询结果中包含dog或者cat
2.'+dog +cat'
字段前面加'+',表示必须同时包含dog和cat
3.'+dog cat'
表示必须包含dog,对cat并不强制,如果出现cat,则相关性会更高
4.'+dog -cat'
表示必须包含dog,必须不包含cat
5.'+dog ~cat'
表示必须包含dog,对cat并不强制,如果出现cat,则相关性会变低
6.'+dog +(>cat <pig)'
表示必须包含dog和cat或者包含dog和pig,但是dog cat的相关性比dog pig的相关性高
7.'dog*'
表示包含以dog开头的内容

ngram的使用方法

  1. 添加全文索引

在这里插入图片描述
2. 查询

// 不指定模式,默认使用自然语言模式
SELECT * FROM articles WHERE MATCH (title) AGAINST ('文言文');
//使用 boolean mode通配符模式。
select * from articles where match(title) AGAINST('cal*' in boolean mode);
使用Boolean中 cal*的方式,查询以cal*开头的内容

默认自然语言模式不需要指定查询模式,而使用Boolean模式时需要指定
in boolean mode

ngram的配置相关参数

innodb_ft_min_token_size
默认3,表示最小3个字符作为一个关键词,增大该值可减少全文索引的大小
innodb_ft_max_token_size
默认84,表示最大84个字符作为一个关键词,限制该值可减少全文索引的大小
ngram_token_size
默认2,表示2个字符作为内置分词解析器的一个关键词,如对“abcd”建立全文索引,关键词为’ab’,‘bc’,‘cd’
当使用ngram分词解析器时,innodb_ft_min_token_size和innodb_ft_max_token_size 无效

如何设置ngram_token_size

第一种

mysqld --ngram_token_size=1

第二种

在配置文件中[mysqld]ngram_token_size=1

这三个参数均不可动态修改,修改了这些参数,需重启MySQL服务,并重新建立全文索引!!

结尾

MySQL的ngram的使用方式粗略介绍完了,在需要全文检索的情况下还是要取舍,如果是大数据,大文档的全文检索,改用ElasticSearch还是要用,如果是短文本的全文检索,就可以考虑一下Ngram,还是要根据实际的使用情况来决定,毕竟架构设计还是在于取舍,而不是一股脑的将所有东西都加进去。

谢谢观看,请关注点赞,感谢支持。


http://chatgpt.dhexx.cn/article/8hs95m6W.shtml

相关文章

语言模型-Ngram

总结工作中用到和学习的知识,也算自己的一个笔记。 语言模型 语言模型简单来讲,就是计算一个句子的概率,更确切的说是计算组成这个句子一系列词语的概率。 举个简单的例子,我们知道“武松打死了老虎”相比于“老虎了死武松打”,更像是一句正常的话,这是因为前者出…

N-gram算法

语言模型 语言模型起源于语音识别(speech recognition)&#xff0c;输入一段音频数据&#xff0c;语音识别系统通常会生成多个句子作为候选&#xff0c;究竟哪个句子更合理&#xff1f;就需要用到语言模型对候选句子进行排序。 语言模型&#xff1a;对于任意的词序列&#xf…

N-Gram语言模型

一、n-gram是什么 wikipedia上有关n-gram的定义&#xff1a; n-gram是一种统计语言模型&#xff0c;用来根据前(n-1)个item来预测第n个item。在应用层面&#xff0c;这些item可以是音素&#xff08;语音识别应用&#xff09;、字符&#xff08;输入法应用&#xff09;、词&am…

MATLAB 离散傅里叶变换(DFT)、逆离散傅里叶变换(IDFT)、快速傅里叶变换(FFT)的实现

离散傅里叶变换&#xff08;DFT&#xff09;、逆离散傅里叶变换&#xff08;IDFT&#xff09;的实现 代码如下&#xff0c;其中xn为时序序列 clc;clear; xn[7,6,5,4,3,2]; Xkdft(xn,6); xidft(Xk,6);subplot(2,2,1);stem(0:5,abs(Xk),filled); axis([0,5,0,1.1*max(abs(Xk))]…

图像处理基础(三)DFT与IDFT变换

傅里叶变换(DFT) 首先来看看傅里叶(DFT)变换的公式 (1) FP\frac {1}{N}\sum_{x0}^{N-1}\sum_{y0}^{N-1}P_{x,y}\exp(-j(\frac{2 \pi}{N})(uxvy)) 幅度 (2) w\sqrt{u^2v^2} 其中 u,v代表空间频率&#xff0c;即灰度梯度&#xff0c;梯度由坐标与灰度值求导的向量 w代表 振幅…

第4章 Python 数字图像处理(DIP) - 频率域滤波7 - 二维DFT和IDFT的一些性质 - 傅里叶频谱和相角

目录 二维DFT和IDFT的一些性质傅里叶频谱和相角 二维DFT和IDFT的一些性质 傅里叶频谱和相角 F ( u , v ) R ( u , v ) j I ( u , v ) ∣ F ( u , v ) ∣ e j ϕ ( u , v ) (4.86) F(u, v) R(u, v) jI(u, v) |F(u, v)|e^{j\phi(u,v)} \tag{4.86} F(u,v)R(u,v)jI(u,v)∣F(…

实数序列频谱的共轭对称性(DFT与IDFT仿真实现)

一、基础知识 1、傅里叶变换&#xff1a;通俗来讲&#xff0c;是以时间为自变量的信号与以频率为自变量的“频谱函数”之间的某种转换关系。 DFT&#xff1a;即离散傅里叶变换&#xff0c;对离散序列进行傅里叶变换。设x(n)为长度为M的有限长序列&#xff0c;其N点DFT定义(公…

第4章 Python 数字图像处理(DIP) - 频率域滤波8 - 二维DFT和IDFT的一些性质 - 二维离散卷积定理

目录 二维DFT和IDFT的一些性质二维离散卷积定理二维离散傅里叶变换性质的小结 二维DFT和IDFT的一些性质 二维离散卷积定理 二维循环卷积表达式&#xff1a; ( f ⋆ h ) ( x , y ) ∑ m 0 M − 1 ∑ n 0 N − 1 f ( m , n ) h ( x − m , y − n ) (4.94) (f \star h)(x, …

FFT学习笔记(DFT,IDFT)

昨天参悟了一天FFT,总算是理解了&#xff0c;今天的莫比乌斯反演也不太懂&#xff0c;干脆弃疗&#xff0c;决定来认真水一发博客。 什么是FFT&#xff1f; FFT&#xff08;Fast Fourier Transformation&#xff09;&#xff0c;即为快速傅氏变换&#xff0c;是离散傅氏变换&…

【OpenCV4】图像的傅里叶变换 cv::dft() 和逆变换 cv::idft() 解析(c++)

图像傅里叶变换的作用&#xff1a; 频谱分析&#xff0c;获取图像中高频低频的分布情况快速卷积&#xff0c;两个矩阵的傅里叶变换结果相乘 案例代码&#xff1a; cv::Mat TestOpencvDft() {cv::Mat lena cv::imread("lena.jpg", 0);cv::resize(lena, lena, cv::…

Matlab如何进行利用离散傅里叶逆变换iDFT 从频谱恢复时域信号

文章目录 1. 定义2. 变换和处理3. 函数4. 实例演示例1&#xff1a;单频正弦信号&#xff08;整数周期采样&#xff09;例2&#xff1a;含有直流分量的单频正弦信号例3&#xff1a;正弦复合信号例4&#xff1a;含有随机干扰的正弦信号例5&#xff1a;实际案例 5. 联系作者 1. 定…

离散傅里叶变换(DFT/IDFT、FFT/IFFT)运算量的讨论

前言&#xff1a;关于为什么要写这个博客 最近在重新看《合成孔径雷达成像 算法与实现》这本书&#xff0c;看到“离散傅里叶变换记其逆变换的运算量级为”这句话&#xff0c;就想起当初在学《数字信号处理》中FFT那章节时&#xff0c;书中有对比DFT和FFT的运算量的一些文字&am…

OpenCV-离散傅里叶变换cv::dftcv::idft

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 函数原型 void dft(InputArray src, OutputArray dst, int flags 0, int nonzeroRows 0); void idft(InputArray src, Output…

12点的idft c语言,【整理】用IDFT实现UF-OFDM和OFDM的模拟调制

cooperate with Liu Lei 用IDFT实现OFDM的代码如下&#xff1a; N32; xrandint(1,N,[0 3]); x1qammod(x,4); f1:N; t0:0.001:1-0.001; w2*pi*f.*t; % w12*pi*(f0.2).*t; y1x1*exp(j*w);%子载波调制 x2ifft(x1,N); %ifft figure(1); plot(t,abs(y1)); hold on; stem(0:1/N:1-1/N…

离散傅立叶变换推导(DF、IDFT)

mazonex离散傅立叶变换视频笔记 需要先了解傅里叶变换推导(FT、IFT) 本文仅作为笔记&#xff0c;推导思想和图片来自视频 周期为 2 π 2\pi 2π的函数的复数形式展开(傅里叶级数) 在上一篇文章中part4中提到周期 T 2 L T2L T2L函数的复数形式展开为&#xff1a; f ( t ) ∑…

浅谈傅里叶——8. 一维iDFT的实现

这是本系列的最后一章&#xff0c;原先计划是把这部分内容一并挪到上一章里的&#xff0c;不过喜欢凑一个整数&#xff0c;而且想骗一点流量&#xff0c;所以把它们拆成了两部分。我们在前面的内容中&#xff0c;通过使用不同的频率信号对原始信号进行采样&#xff0c;从而分析…

idft重建图像 matlab_1周学FFT——第2天 DFT和IDFT的MATLAB实现

根据定义式&#xff0c;可写出DFT的MATLAB代码如下[从玉良&#xff0c;2009&#xff0c;p72]&#xff1a; function [f, Xk] mydft(xn, fs, N) % DFT n [0:1:N-1]; k n; WN exp(-j*2*pi/N); nk n * k; % N^2 times multiply Xk xn(1:N) * WN.^nk; % N^3 times multiply f …

FT,DTFT,DFT,IDFT,FFT含义

1.傅立叶变换FT(Fourier Transform) 性质&#xff1a;时域连续&#xff0c;频域连续 周期信号只有傅立叶级数&#xff0c;严格意义上讲&#xff0c;没有傅立叶变换&#xff1b;但可以令周期信号的周期趋于无穷大&#xff0c;这样&#xff0c;将周期信号变为非周期信号&#x…

DFT与IDFT

DFT与IDFT 一.方法简介 序列x(n)(n0,1,…N-1)的DFT定义为 X &#xff08; k &#xff09; ∑ n 0 N − 1 x ( n ) e − j 2 π n k N X&#xff08;k&#xff09;\sum_{n0}^{N-1}x(n)e^{-j\frac{2\pi nk}{N}} X&#xff08;k&#xff09;n0∑N−1​x(n)e−jN2πnk​ 设 x …

IDFT的python实现

IDFT IDFT(Inverse Discrete Fourier Transform), 傅里叶逆变换&#xff0c;可以将频域信号转换到时域中, 它的公式非常简单&#xff1a; x [ n ] 1 N ∑ k 0 N − 1 X [ k ] e j 2 π k n / N x[n] \frac{1}{N} \sum_{k0}^{N-1} X[k] e^{j2\pi kn/N} x[n]N1​k0∑N−1​X…