先来看看对一个字段做全文索引,作为一个数据库系统需要做哪些工作?

假设一个文章表里面包含几个字段:文章id、文章作者、文章标题、文章内容

比如,我们对文章内容这个字段artilce_content建立全文索引,这样方便对文章里面的内容使用关键词搜索。

数据库系统首先需要从文章内容(这个字段内容)中提取关键词,因为只有提取了关键词,才好建立类似索引目录—类似于新华字典那样的笔画页码对应关系,当你搜索一个词语”beijing”的时候,就直接去索引中查找,然后就可以定位到数据行的具体位置了,不需要扫描文章表很多行。

这就像,如果我想去新华字典中查找一个汉字,我直接按照笔画或者按照拼音来查找(这个就是新华字典的索引),避免把新华字典从头翻到尾部,这样的效率多低。没错,如果没有索引,数据库系统就是需要这样子遍历扫描整个表才能得到数据的。

ps:机器其实是死的,你写的代码让他做什么就做什么。而人有眼睛,可以通过眼睛来看,比如大体翻看一下新华字典,也许眼睛就看到我需要的汉字了呢。

数据库系统中的关于那个索引结构大体可以这样理解:

关键词  包含此关键词的文档列表(也可以理解成行)

beijing    1,2,3…

索引就是方便快速查找,根据这个索引结构,搜索的时候就可以快速定位到数据位置了。

mysql对一个字段做全文索引的时候,他从文章内容中提取关键词,

mysql的全文检索解析器在提取关键词默认是按照空格来识别单词的。也就是中文”我喜欢打篮球” 这一串文字中没有空格,那么mysql不会把这个当成好几个单词的。

如果故意进行空格分开,mysql就容易识别处理关键词,比如变成”我 喜欢 打 篮球”

像上面这样子,mysql可能会把篮球当成关键词提取出来进入索引中去。为什么只是可能?有空格只是保证mysql识别成单词,但会不会建立成索引,其实我不是很清楚。因为没看过mysql源码,不是很清楚。

因为对文章表的”文章内容”字段建立了成了全文索引,那么每次往表中新加入一行数据,数据库系统都会去提取文章新行数据中的文章内容字段,看有没有关键词,继续往索引表里面加单词或者更新数据。比如原来的索引文件有个单词”beijing”,现在新加入的文章内容中提取到有beijing这个词语,那要更新索引表了,意思是记录下新加的文档哪里存在beijing这个词语。

beijing  8,9,10

新加入的文档id为20,刚好其中文章内容被提取到了词语beijing

那么索引就要更新成如下形式:

beijing 8,9,20

这样解释是方便理解,理解就好。

大体是这样子的模式。具体实现会跟这个存在差异的。把复杂的问题解释得通俗化,简单化是而容易理解,是我进行总结的目的。

ps:mysql的一个表的所有字段的索引数据都在一张一个”表名称.MYI”文件中。

理解了上面的实现原理,

现在也好理解一句话了,这是从mysql手册中中的一句话:

对于较大的数据集,将你的资料输入一个没有FULLTEXT索引的表中,然后创建索引, 其速度比把资料输入现有FULLTEXT索引的速度更为快。

我是这么理解,比如,把100行数据同时插入文章表中,而文章内容字段是建立成全文索引,那么新插入的数据在入库的同时,要提取关键词(对文章内容字段),然后更新索引,速度当然会慢下来。关键问题就是在插入数据的时候就会去分词和更新索引。整个insert 操作就会延长时间了。

上面已经建立文章内容字段为全文索引,现在mysql是怎么进行全文查询的呢?

select  id,title FROM 文章表 WHERE MATCH(article_content) AGAINST ('search keyword')

match()中指定字段名称。表示against()中出现的字符串要去哪个字段中匹配。这里可以指定多个字段

against()中的字符串,难道不是单个词语,mysql会自动对受到的字符串进行分词吗?

AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);

+号表示,MYSQL这个单词必须出现在每一行的开头位置?

‘’里面是单词,多个单词之间需要使用空格分开吗?

来看看对英文进行分词有什么天然优势

英文的特点,每个英文单词就是一个词语,单词与单词之间有非常明显的分割符号—空格

比如

my  name is wangxiaoming

this city is beijing…..

citye 和beijing可以看成是两个关键词,用来搜索

mysql内部对要提取关键词的时候,哪些可以作为关键词来建立索引呢?

它可以以空格来分割开来。把city 和 beijing都当成是两个关键词来建立索引(理解成新华字典中的笔画与页数的目录结构)。

总结一下

英文:除了少数特殊字符和标点几乎都是以空格分隔的,所以要对一段英文进行分词(也就是从中提取关键词),这样子比较容易。按照空格、逗号等特别的符号来识别即可。

来看看,中文分词为什么就比较麻烦

由于中文比较特殊,像”理发师” 理发可以是一个关键词,理发师也可以是一个关键词。关键词之间并没有明显的分割符号,我们看到紧挨着的。这就需要mysql去提取哪些是关键词。是把”理”发作为关键词来索引,还是”理发”或者”理发师”都算关键词,没法识别。

一般百度这些搜索引擎是怎么提取关键词,他们有个专门的关键词库的,也就是中文关键词词库。这样就知道把什么当成是关键词。显然,mysql是又国外人做的一个软件,它不会单独给你去做一个关键词库。

计算机怎么知道哪个算是词语呢?比如输入一串文字 ”我来自北京,我很喜欢运动、听音乐…,喜欢听周华健的歌曲”

在这一句话中,北京算不算关键词呢。”周华健”算不算关键词呢?

像我们常见的中文切词,我了解到有几种分词算法:

1、  就是根据词库来进行对比的。

2、  二元分词法

3、  统计法

对比:二元分词方法和统计方法是不依赖于词典的,而最大匹配法分词方法是依赖于词典的,词典的内容决定分词结构的好坏。

现在总结一下:MySQL不会断中文字:MySQL内建的字依据是空白、逗号和点来断词语。

mysql手册中原文如下:

FULLTEXT分析程序会通过寻找某些分隔符来确定单词的起始位置和结束位置,例如' ' (间隔符号)、 , (逗号)以及 . (句号 )。假如单词没有被分隔符分开,(例如在中文里 ), 则 FULLTEXT 分析程序不能确定一个词的起始位置和结束位置。为了能够在这样的语言中向FULLTEXT 索引添加单词或其它编入索引的术语,你必须对它们进行预处理,使其被一些诸如"之类的任意分隔符分隔开

…………………

诸如汉语和日语这样的表意语言没有自定界符。因此, FULLTEXT分析程序不能确定在这些或其它的这类语言中词的起始和结束的位置。其隐含操作及该问题的一些工作区在12.7节,“全文搜索功能”有详细论述。

==================================结束

中文与西方文字如英文的一个重要区别在于,西方文字以单词为单位,单词与单词之间以空格分隔。而中文以字为单位,词由一个或多个字组成,词与词之间没有空格分隔。当试图在一个含有中文字符的字段中使用全文搜索时,不会得到正确的结果,原因在于中文中没有像英文空格那样对词定界,不能以空格作为分割,(于是不方便)对中文词语进行索引。

现在归纳一下,mysql不能很好地支持中文全文索引的解决办法

1、针对对myql全文检索解析器内建机制特点,白痴解决方法是,存中文字时自行塞入空白断字。

这样就适应了mysql的切词机制了。不过这样子做比较别扭。因为哪有把”我是中国人”古意分开成”我 是 中国人”这样的形式呢。

显示文章内容的时候就比较别扭,不能显示成”我 是 中国人”给用户看,需要需要自己再次处理。

2、使用切词插件。mysql应该是意识到单靠自己来提供分词,永远无法满足世界上各种各样语言的特殊需求。于是从5.1版本开始,Mysql全文检索的解析器以插件的方式提供。让大家可以以插件的形式挂到mysql下面去(实际上就是作为mysql的一个存储引擎,比如sphinx就是插件挂上去)

挂载到mysql中的插件所完成是一个什么样的角色呢?

使用插件,就是可以按照你自己的方式去分词

当数据量很大的时候,比较成熟的做法是使用专门的全文索引系统,用这些专业的全文索引系统来分词,以mysql数据库中的数据作为数据源,来分词建立索引结构。查询的时候,先从全文索引系统中查询,获取文档编号,然后根据文档编号去mysql中查询数据。对于全文搜索插件sphinx-for-chinese,曾经在公司的服务器上配置过,通过那次配置加深了对它的理解。中途遇到一些问题,一直想以文字的形式总结出来,以备忘。有时间会上一篇关于它的操作总结出来。

个人理解不正确之处,欢迎指正!

本文未完待补充

mysql中文进行全文索引支持问题的更多相关文章

  1. MySQL中文全文索引插件 mysqlcft 1.0.0 安装使用文档[原创]

    [文章+程序 作者:张宴 本文版本:v1.0 最后修改:2008.07.01 转载请注明原文链接:http://blog.zyan.cc/post/356/] MySQL在高并发连接.数据库记录数较多 ...

  2. mysql 中文支持

    show variables like 'character%';  SHOW VARIABLES LIKE 'collation_%'; recommend to use utf8mb4 inste ...

  3. 解决springmvc+mybatis+mysql中文乱码问题【转】

    这篇文章主要介绍了解决java中springmvc+mybatis+mysql中文乱码问题的相关资料,需要的朋友可以参考下 近日使用ajax请求springmvc后台查询mysql数据库,页面显示中文 ...

  4. MySQL 全文搜索支持, mysql 5.6.4支持Innodb的全文检索和类memcache的nosql支持

    背景:搞个个人博客的全文搜索得用like啥的,现在mysql版本号已经大于5.6.4了也就支持了innodb的全文搜索了,刚查了下目前版本号都到MySQL Community Server 5.6.1 ...

  5. php mysql 中文乱码解决方法

    本文章向码农们介绍php mysql 中文乱码解决方法,对码农们非常实用,需要的码农可以参考一下. 从MySQL 4.1开始引入多语言的支持,但是用PHP插入的中文会出现乱码.无论用什么编码也不行 解 ...

  6. Java连接MySQL中文乱码处理【转载】

    本文转载地址:http://developer.51cto.com/art/200906/130425.htm 感谢相关作者! MySQL默认编码是latin1 mysql> show vari ...

  7. MySQL编程(0) - Mysql中文乱码问题解决方案

    MySQL 5.6 for Windows 解压缩版配置安装: http://jingyan.baidu.com/article/f3ad7d0ffc061a09c3345bf0.html MySQL ...

  8. c++ poco 使用mysql中文乱码问题

    poco 是c++ 一个比较好的库,现在正在学习使用它,碰到一些问题记录在此. poco版本:poco-1.46-all ,带有数据库的支持模块 操作系统:ubuntu 1.使用poco的MySQL模 ...

  9. 关于Mysql中文乱码问题该如何解决(乱码问题完美解决方案)(转)

    这篇文章给大家介绍关于Mysql中文乱码问题该如何解决(乱码问题完美解决方案)的相关资料,还给大家收集些关于MySQL会出现中文乱码原因常见的几点,小伙伴快来看看吧   最近两天做项目总是被乱码问题困 ...

随机推荐

  1. 恢复Ext3下被删除的文件

    下面是这个教程将教你如何在Ext3的文件系统中恢复被rm掉的文件. 假设我们有一个文件名叫 ‘test.txt’  $ls -il test.txt 15 -rw-rw-r– 2 root root ...

  2. 跟我学SharePoint 2013视频培训课程——怎样创建列表和列表项(7)

    课程简介 第7天,怎样在SharePoint 2013中创建列表和列表项 视频 SharePoint 2013 交流群 41032413

  3. 有关java调用方法参数传递的分析

    这个问题好多文章都讲过了,在此本人补充一下,加深理解,有不足之处请指教. 相信做java开发同学们都知道,调用方法传递参数时,不论是基本类还是引用类型, java都是值传递,不存在引用传递(称引用传递 ...

  4. jumpserver 3.2修改排序规则

    在默认的情况下,我们使用jumpserver的时候 这里我使用xshell 客户端连接到堡垒机的时候, 这里我的显示规则是根据IP排序的,但是我这里的服务器的hostname 都是根据场景设置的hos ...

  5. ubuntu18.04下安装Anaconda及numpy、matplotlib

    为了学习深度学习,我需要首先掌握利用python进行科学计算的知识,顺便复习一下线性代数.微积分.概率论.当然,现在我要做的是安装Anaconda. 1.官网下载,linux版本:https://ww ...

  6. vue-cli 本地数据模拟

    方法一: 使用express搭建静态服务 mock数据写在json文件中,proxyTable 里将接口代理到具体mock数据json文件上.具体方法: 创建 mock 文件夹 build/dev-s ...

  7. 使用jquery插件ajaxfileupload一次上传多个文件,示例

    @{ ViewBag.Title = "Index"; Layout = ""; } <!DOCTYPE html PUBLIC "-//W3C ...

  8. 菜鸟学SSH(一)——Struts实现简单登录(附源码)

    从今天开始,一起跟各位聊聊java的三大框架——SSH.先从Struts开始说起,Struts对MVC进行了很好的封装,使用Struts的目的是为了帮助我们减少在运用MVC设计模型来开发Web应用的时 ...

  9. android笔记---百度地图api应用 (一)

    package com.example.bdtest; import com.baidu.mapapi.MKEvent; import com.baidu.mapapi.MKPlanNode; imp ...

  10. 《转》冯森林:手机淘宝中的那些Web技术(2014年)

    Native APP与Web APP的技术融合已经逐渐成为一种趋势,使用标准的Web技术来开发应用中的某些功能,不仅可以降低开发成本,同时还可以方便的进行功能迭代更新.但是如何保证Web APP的流畅 ...