`

利用MySQL内置函数实现全文搜索功能

阅读更多

MATCH (col1,col2,...) AGAINST (expr [IN BOOLEAN MODE | WITH QUERY EXPANSION])

MySQL支持全文索引和搜索功能。MySQL中的全文索引类型FULLTEXT的索引。  FULLTEXT 索引仅可用于 MyISAM 表;他们可以从CHAR、VARCHAR或TEXT列中作为CREATE TABLE语句的一部分被创建,或是随后使用ALTER TABLE 或 CREATE INDEX被添加。对于较大的数据集,将你的资料输入一个没有FULLTEXT索引的表中,然后创建索引,其速度比把资料输入现有FULLTEXT索引的速度更为快。

全文搜索同MATCH()函数一起执行。

mysql> CREATE TABLE articles (
    ->   id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
    ->   title VARCHAR(200),
    ->   body TEXT,
    ->   FULLTEXT (title,body)
    -> );
Query OK, 0 rows affected (0.00 sec)
 
mysql> INSERT INTO articles (title,body) VALUES
    -> ('MySQL Tutorial','DBMS stands for DataBase ...'),
    -> ('How To Use MySQL Well','After you went through a ...'),
    -> ('Optimizing MySQL','In this tutorial we will show ...'),
    -> ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
    -> ('MySQL vs. YourSQL','In the following database comparison ...'),
    -> ('MySQL Security','When configured properly, MySQL ...');
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0
 
mysql> SELECT * FROM articles
    -> WHERE MATCH (title,body) AGAINST ('database');
+----+-------------------+------------------------------------------+
| id | title             | body                                     |
+----+-------------------+------------------------------------------+
|  5 | MySQL vs. YourSQL | In the following database comparison ... |
|  1 | MySQL Tutorial    | DBMS stands for DataBase ...             |
+----+-------------------+------------------------------------------+
2 rows in set (0.00 sec)

MATCH()函数对于一个字符串执行资料库内的自然语言搜索。一个资料库就是1套1个或2个包含在FULLTEXT内的列。搜索字符串作为对AGAINST()的参数而被给定。对于表中的每一行, MATCH() 返回一个相关值,即, 搜索字符串和 MATCH()表中指定列中该行文字之间的一个相似性度量。

在默认状态下, 搜索的执行方式为不区分大小写方式。然而,你可以通过对编入索引的列使用二进制排序方式执行区分大小写的全文搜索。 例如,可以向一个使用latin1字符集的列给定latin1_bin 的排序方式,对于全文搜索区分大小写。

如上述所举例子,当MATCH()被用在一个 WHERE 语句中时,相关值是非负浮点数。零相关的意思是没有相似性。相关性的计算是基于该行中单词的数目, 该行中独特子的数目,资料库中单词的总数,以及包含特殊词的文件(行)数目。

对于自然语言全文搜索,要求MATCH() 函数中命名的列和你的表中一些FULLTEXT索引中包含的列相同。对于前述问讯, 注意,MATCH()函数(题目及全文)中所命名的列和文章表的FULLTEXT索引中的列相同。若要分别搜索题目和全文,应该对每个列创建FULLTEXT索引。

或者也可以运行布尔搜索或使用查询扩展进行搜索。

上面的例子基本上展示了怎样使用返回行的相关性顺序渐弱的MATCH()函数。而下面的例子则展示了怎样明确地检索相关值。返回行的顺序是不定的,原因是  SELECT 语句不包含 WHERE或ORDER BY 子句:

mysql> SELECT id, MATCH (title,body) AGAINST ('Tutorial')
-> FROM articles;
+----+-----------------------------------------+
| id | MATCH (title,body) AGAINST ('Tutorial') |
+----+-----------------------------------------+
|  1 |                        0.65545833110809 |
|  2 |                                       0 |
|  3 |                        0.66266459226608 |
|  4 |                                       0 |
|  5 |                                       0 |
|  6 |                                       0 |
+----+-----------------------------------------+
6 rows in set (0.00 sec)

下面的例子则更加复杂。询问返回相关值,同时对行按照相关性渐弱的顺序进行排序。为实现这个结果,你应该两次指定 MATCH(): 一次在 SELECT 列表中而另一次在 WHERE子句中。这不会引起额外的内务操作,原因是MySQL 优化程序注意到两个MATCH()调用是相同的,从而只会激活一次全文搜索代码。

mysql> SELECT id, body, MATCH (title,body) AGAINST
-> ('Security implications of running MySQL as root') AS score
-> FROM articles WHERE MATCH (title,body) AGAINST
-> ('Security implications of running MySQL as root');
+----+-------------------------------------+-----------------+
| id | body                                | score           |
+----+-------------------------------------+-----------------+
|  4 | 1. Never run mysqld as root. 2. ... | 1.5219271183014 |
|  6 | When configured properly, MySQL ... | 1.3114095926285 |
+----+-------------------------------------+-----------------+
2 rows in set (0.00 sec)

表中有2行(0.00 秒)

MySQL FULLTEXT 执行将任何单字字符原形 (字母、数字和下划线部分)的序列视为一个单词。这个序列或许也包含单引号 ('),但在一行中不会超过一个。 这意味着 aaa'bbb 会被视为一个单词,而 aaa''bbb则被视为2个单词。位于单词之前或其后的单引号会被FULLTEXT分析程序去掉; 'aaa'bbb' 会变成   aaa'bbb。

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

一些词在全文搜索中会被忽略:

◆ 任何过于短的词都会被忽略。 全文搜索所能找到的词的默认最小长度为 4个字符。

◆ 停止字中的词会被忽略。禁用词就是一个像“the” 或“some” 这样过于平常而被认为是不具语义的词。存在一个内置的停止字, 但它可以通过用户自定义列表被改写。

词库和询问中每一个正确的单词根据其在词库和询问中的重要性而被衡量。  通过这种方式,一个出现在许多文件中的单词具有较低的重要性(而且甚至很多单词的重要性为零),原因是在这个特别词库中其语义价值较低。反之,假如这个单词比较少见,那么它会得到一个较高的重要性。然后单词的重要性被组合,从而用来计算该行的相关性。

这项技术最适合同大型词库一起使用 (事实上, 此时它经过仔细的调整 )。对于很小的表,单词分布并不能充分反映它们的语义价值, 而这个模式有时可能会产生奇特的结果。例如, 虽然单词 “MySQL” 出现在文章表中的每一行,但对这个词的搜索可能得不到任何结果:

mysql> SELECT * FROM articles
-> WHERE MATCH (title,body) AGAINST ('MySQL');

找不到搜索的词(0.00 秒)

这个搜索的结果为空,原因是单词 “MySQL” 出现在至少全文的50%的行中。 因此, 它被列入停止字。对于大型数据集,使用这个操作最合适不过了----一个自然语言问询不会从一个1GB 的表每隔一行返回一次。对于小型数据集,它的用处可能比较小。

一个符合表中所有行的内容的一半的单词查找相关文档的可能性较小。事实上, 它更容易找到很多不相关的内容。我们都知道,当我们在因特网上试图使用搜索引擎寻找资料的时候,这种情况发生的频率颇高。可以推论,包含该单词的行因其所在特别数据集 而被赋予较低的语义价值。 一个给定的词有可能在一个数据集中拥有超过其50%的域值,而在另一个数据集却不然。

当你第一次尝试使用全文搜索以了解其工作过程时,这个50% 的域值提供重要的蕴涵操作:若你创建了一个表,并且只将文章的1、2行插入其中, 而文中的每个单词在所有行中出现的机率至少为  50% 。那么结果是你什么也不会搜索到。一定要插入至少3行,并且多多益善。需要绕过该50% 限制的用户可使用布尔搜索代码。

分享到:
评论

相关推荐

    MYSQL数据库管理器 (易语言源代码)

    易语言的MYSQL支持库已经通过内置命令的方式支持了大部分的MYSQL命令,现在通过设计一个图形界面,让用户使用鼠标点选下就可以实现这个命令的绝大部分命令,而不用去记忆那些枯燥、乏味的命令,通过这个图形...

    MYSql高级教程-存储引擎和SQL优化

    第二层架构主要完成大多数的核心服务功能,如SQL接口,并完成缓存的查询,SQL的分析和优化,部分内置函数的执行。所有跨存储引擎的功能也在这一层实现,如 过程、函数等。在该层,服务器会解析查询并创建相应的内部...

    MySQL利用procedure analyse()函数优化表结构

    procedure analyse()函数是MySQL内置的对MySQL字段值进行统计分析后给出建议的字段类型。 语法 procesure analyse(max_elements,max_memory) max_elements 指定每列非重复值的最大值,当超过这个值的时候,MySQL...

    PHP源码之 ext/mysql扩展部分

    我写过一个外部模块扩展,现在开始看PHP源码中的mysql扩展,它是可以被集成到PHP内部... ps:该目录下有tags文件,所以可以利用ctags的各种特性,直接找到函数、宏定义等。 ps:linux下mysql的启动 sudo mysql-dir/bin/

    易语言-MYSQL数据库管理器易语言源码(易语言2005年大赛三等奖)

    易语言的MYSQL支持库已经通过内置命令的方式支持了大部分的MYSQL命令,现在通过设计一个图形界面,让用户使用鼠标点选下就可以实现这个命令的绝大部分命令,而不用去记忆那些枯燥、乏味的命令,通过这个图形...

    利用Python做数据分析

    Python的设计哲学是“优雅”、“明确”、“简单。Python用途极广。图形处理:有PIL、Tkinter等图形库支持,能...黑客编程:python有一个hack的库,内置了你熟悉的或不熟悉的函数,但是缺少成就感。 用Python写简单爬虫

    响应式机械设备制造网站源码系统 v5.2.zip

    程序主体采用PHP MYSQL构架,Thinkphp5内核开发 此建站系统拥有独立自主开发的一整套函数、标签系统,方便二次开发,功能都已开发出来,前端可以很容易设计出需求的模板。 响应式机械设备制造网站源码系统特点 1、...

    智能发票识别系统后台.zip

    使用shiro作为安全管理框架,通过其内置session实现安全登录,使用shiro注解完成权限管理。 算法端 使用Bag of Words + CNN完成票据分类,根据分类结果查询并获取相应的发票模板。 使用SIFT特征匹配和配准思路完成...

    Java典型模块

    18.3.2 通过FileDir类实现列举文件和目录的功能 18.3.3 File类提供的属性和方法 18.3.4 文件访问的基本概念 18.3.5 文件的基本访问方式——字节方式 18.3.6 文件的基本访问方式——字符方式 18.3.7 文件的高级访问...

    双语企业通用红色系网站模板 v2.7.zip

    双语企业通用红色系模板,...15、[安全]全部模板中过滤含有的php执行函数eval,防止被利用注入; 16、[安全]ajax的图片删除改为post提交与验证; 企业通用红色系模板前台截图 相关阅读 同类推荐:站长常用源码

    魅魔MacCms视频电影程序ASP版 V6.1 20120511.rar

    仿MVC模板分离,内置标签,asp自定义函数标签接口,强大的自定义采集功能,只要你会HTML就可以轻松做出个性化的网站。程序易用性和功能上一直以来都积极采纳广大站长提出的各种好的建议,迅速响应各种紧急问题,我们...

    html+css+js 简易微博系统.zip

    利用html+css+js作为前端语言和php作为后台语言,采用前端与后台分离的设计方式,主要实现新用户注册,用户登录,发微博(包括文字,表情,音乐,视频),评论微博,转发微博,关注用户,私信等功能。 PHP(全称:...

    PHP+MySQL 手工注入语句大全 推荐

    利用内置函数暴数据库信息 version() database() user()  不用猜解可用字段暴数据库信息(有些网站不适用): and 1=2 union all select version() /* and 1=2 union all select database() /* and 1=2 union all ...

    苹果cms电影程序MacCms v8.x UTF8 bulid2017.09.27

    仿MVC模板分离,内置标签,asp自定义函数标签接口,强大的自定义采集功能,只要你会HTML就可以轻松做出个性化的网站。程序易用性和功能上一直以来都积极采纳广大站长提出的各种好的建议,迅速响应各种紧急问题,我们...

    从python读取sql的实例方法

    1、利用python内置的open函数读入sql文件; 2、利用第三方库pymysql中的connect函数连接mysql服务器; 3、利用第三方库pandas中的read_sql方法读取传入的sql文件即可。 python 直接读取 sql 文件,达到使用 read_sql...

    JSP高级编程

    7.4.1 功能实现和技术要点 7.4.2 代码和分析 7.5 下一步 第二部分 高级JSP技术 第8章 JSP开发平台的搭建:J2EE 8.1 J2SDKEE的安装和使用 8.1.1 软硬件的支持 8.1.2 安装 8.2 J2SDKEE的配置 8.2.1 ...

    苹果电影程序MacCms 电影网站源码

    仿MVC模板分离,内置标签,asp自定义函数标签接口,强大的自定义采集功能,只要你会HTML就可以轻松做出个性化的网站。程序易用性和功能上一直以来都积极采纳广大站长提出的各种好的建议,迅速响应各种紧急问题,我们...

    红色农家乐美食客房旅馆源码 v3.8.zip

    6、[安全]全部模板中过滤含有的php执行函数eval,防止被利用注入; 7、[安全]ajax的图片删除改为post提交与验证; 8、[安全]修复后台存在文件上传漏洞,禁止上传php扩展名的文件; 9、[优化]前台文档内容、单页...

Global site tag (gtag.js) - Google Analytics