如何在MySQL中获得更好的全文搜索结果
如何在MySQL中获得更好的全文搜索结果
很多互联网应用程序都提供了全文搜索功能,用户可以使用一个词或者词语片断作为查询项目来定位匹配的记录。在后台,这些程序使用在一个SELECT 查询中的LIKE语句来执行这种查询,尽管这种方法可行,但对于全文查找而言,这是一种效率极端低下的方法,尤其在处理大量数据的时候。
mysql针对这一问题提供了一种基于内建的全文查找方式的解决方案。在此,开发者只需要简单地标记出需要全文查找的字段,然后使用特殊的MySQL方法在那些字段运行搜索,这不仅仅提高了性能和效率(因为MySQL对这些字段做了索引来优化搜索),而且实现了更高质量的搜索,因为MySQL使用自然 语言来智能地对结果评级,以去掉不相关的项目。
这篇文章将向您讲述在MySQL中如何进行全文搜索。
在进行数据库查询时,有完整查询和模糊查询之分。
SELECT 字段 FROM 表 WHERE 某字段 Like 条件
其中关于条件,SQL提供了四种匹配模式:
1,%:表示任意0个或多个字符。可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示。
比如 SELECT * FROM [user] WHERE u_name LIKE '%三%'
将会把u_name为“张三”,“张猫三”、“三脚猫”,“唐三藏”等等有“三”的记录全找出来。
另外,如果需要找出u_name中既有“三”又有“猫”的记录,请使用and条件
SELECT * FROM [user] WHERE u_name LIKE '%三%' AND u_name LIKE '%猫%'
若使用 SELECT * FROM [user] WHERE u_name LIKE '%三%猫%'
虽然能搜索出“三脚猫”,但不能搜索出符合条件的“张猫三”。
2,_: 表示任意单个字符。匹配单个任意字符,它常用来限制表达式的字符长度语句:
比如 SELECT * FROM [user] WHERE u_name LIKE '_三_'
只找出“唐三藏”这样u_name为三个字且中间一个字是“三”的;
再比如 SELECT * FROM [user] WHERE u_name LIKE '三__';
只找出“三脚猫”这样name为三个字且第一个字是“三”的;
3,[ ]:表示括号内所列字符中的一个(类似正则表达式)。指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。
比如 SELECT * FROM [user] WHERE u_name LIKE '[张李王]三'
将找出“张三”、“李三”、“王三”(而不是“张李王三”);
如 [ ] 内有一系列字符(01234、abcde之类的)则可略写为“0-4”、“a-e”
SELECT * FROM [user] WHERE u_name LIKE '老[1-9]'
将找出“老1”、“老2”、……、“老9”;
4,[^ ] :表示不在括号所列之内的单个字符。其取值和 [] 相同,但它要求所匹配对象为指定字符以外的任一个字符。
比如 SELECT * FROM [user] WHERE u_name LIKE '[^张李王]三'
将找出不姓“张”、“李”、“王”的“赵三”、“孙三”等;
SELECT * FROM [user] WHERE u_name LIKE '老[^1-4]';
将排除“老1”到“老4”,寻找“老5”、“老6”、……
5,查询内容包含通配符时
由于通配符的缘故,导致我们查询特殊字符“%”、“_”、“[”的语句无法正常实现,而把特殊字符用“[ ]”括起便可正常查询。据此我们写出以下函数:
function sqlencode(str)
str=replace(str,"[","[[]") '此句一定要在最前
str=replace(str,"_","[_]")
str=replace(str,"%","[%]")
sqlencode=str
end function
在查询前将待查字符串先经该函数处理即可。
1、设置基本表格
从创建例子表格开始,使用以下的SQL命令:
mysql> CREATE TABLE reviews (id INT(5) PRIMARY KEY NOT NULL AUTO_INCREMENT, data TEXT);
以上命令创建了一个简单的音乐专集资料库(主要是整段的文字),然后向这个表格中添加一些记录:
mysql> INSERT INTO `reviews` (`id`, `data`) VALUES
(1, 'Gingerboy has a new single out called Throwing Rocks. It\'s great!');
mysql> INSERT INTO `reviews` (`id`, `data`) VALUES
(2, 'Hello all, I really like the new Madonna single.
One of the hottest tracks currently playing...I\'ve been listening to it all day');
mysql> INSERT INTO `reviews` (`id`, `data`)
VALUES (3, 'Have you heard the new band Hotter Than Hell?
They have five members and they burn their instruments when they play in concerts.
These guys totally rock! Like, awesome, dude!');
验证数据的正确录入:
mysql> SELECT * FROM reviews;
+----+--------------------------------------------+
id data
+----+--------------------------------------------+
1 Gingerboy has a new single out called ...
2 Hello all, I really like the new Madon ...
3 Have you heard the new band Hotter Than...
+----+--------------------------------------------+
3 rows in set (0.00 sec)
2、定义全文搜索字段
接下来,定义您要作为全文搜索索引的字段
mysql> ALTER TABLE reviews ADD FULLTEXT INDEX (data);
Query OK, 3 rows affected (0.21 sec)
Records: 3 Duplicates: 0 Warnings: 0
使用SHOW INDEXES命令来检查索引已经被添加了:
mysql> SHOW INDEXES FROM reviews;
+---------+---------------+--------+------+------------+---------+
Table Column_name Packed Null Index_type Comment
----------+---------------+--------+------+------------+---------+
reviews id NULL BTREE
reviews data NULL YES FULLTEXT
+---------+---------------+--------+------+------------+---------+
3、运行全文搜索
当您拥有了数据和索引,就可以使用MySQL的全文搜索了,最简单的全文搜索方式是带有MATCH...AGAINST语句的SELECT查询,以下是一个简单的例子,可以来查找含有单词“single”的记录:
mysql> SELECT id FROM reviews WHERE MATCH (data) AGAINST ('single');+----+
id
+----+
1
2
+----+
2 rows in set (0.00 sec)
在此,MATCH()将作为参数传递给它的字段中的文字与传递给AGAINST()的参数进行比较,如果有匹配的,那就按照正常的方式返回。注意您可以传递不止一个字段用MATCH()来查看-只需用逗号来分割字段列表。
当MySQL收到了一个全文搜索的请求,它就在内部对每个记录进行评分,不匹配的记录得分为零,而“更相关”的记录会得到比“不太相关”的记录相对更高的分数。相关性是由MySQL的一系列区分标准来决定的,查看MySQL的用户手册可以得到更多的信息。
想看到每个记录的评分如何,只需要返回MATCH()方法作为结果集的一部分,如下所示:
mysql> SELECT id, MATCH (data) AGAINST ('rock') FROM reviews;
+----+-------------------------------+
id MATCH (data) AGAINST ('rock')
+----+-------------------------------+
1 0
2 0
3 1.3862514533815
+----+-------------------------------+
3 rows in set (0.00 sec)
4、使用逻辑搜索修饰符(Boolean search modifiers)
您还可以使用逻辑搜索修饰符来进行更精确的搜索,这通过在AGAINST语句中添加特殊的IN BOOLEAN MODE修饰符来实现,在以下的例子中,将查找含有单词“single”但是没有“Madonna”的记录:
mysql> SELECT id FROM reviews WHERE MATCH (data) AGAINST ('+single -madonna' IN BOOLEAN MODE);
+----+
id
+----+
1
+----+
1 row in set (0.00 sec)
这一搜索特性通常用于搜索单词片断(而不是完整的词语),这可以通过在IN BOOLEAN MODE语句中的*(星号)操作符来实现,以下的例子展示了如何查找单词中含有“hot”的记录:
mysql> SELECT id FROM reviews WHERE MATCH (data) AGAINST ('hot*' IN BOOLEAN MODE);+----+
id
+----+
3
2
+----+
2 rows in set (0.00 sec)
您还可以使用这种方法来查找至少一个传递到AGAINST的参数中,以下的例子查找了至少包含单词“hell”和“rocks”中的一个的记录:
mysql> SELECT id FROM reviews WHERE MATCH (data) AGAINST ('hell rocks' IN BOOLEAN MODE);
+----+
id
+----+
1
3
+----+
3 rows in set (0.00 sec)
以上的这些例子演示了相对于传统的SELECT...LIKE语句,进行全文搜索的更有效的方法,当您下一次需要编写MySQL数据库搜索界面的时候,您可以尝试这一方法。 最终发现使用不了,原因是只有MyISAM引擎才支持全文索引,晕。好吧,还是用like进行搜索。。。
如何在MySQL中获得更好的全文搜索结果的更多相关文章
- 如何在MySQL中查询每个分组的前几名【转】
问题 在工作中常会遇到将数据分组排序的问题,如在考试成绩中,找出每个班级的前五名等. 在orcale等数据库中可以使用partition语句来解决,但在mysql中就比较麻烦了.这次翻译的文章就是专门 ...
- 如何在mysql中存储音乐和图片文件
如何在mysql中存储音乐和图片文件? 果你想把二进制的数据,比如说图片文件和HTML文件,直接保存在你的MySQL数据库,那么这篇文章就是为你而写的! 我将告诉你怎样通过HTML表单来储存这些文件, ...
- 如何在MySQL中分配innodb_buffer_pool_size
如何在MySQL中分配innodb_buffer_pool_size innodb_buffer_pool_size是整个MySQL服务器最重要的变量. 1. 为什么需要innodb buffer p ...
- 关于如何在mysql中插入一条数据后,返回这条数据的id
简单的总结一下如何在mysql中出入一条数据后,返回该条数据的id ,假如之后代码需要这个id,这样做起来就变得非常方便,内容如下: <insert id="insertAndGetI ...
- 如何在mysql中查询每个分组的前几名
问题 在工作中常会遇到将数据分组排序的问题,如在考试成绩中,找出每个班级的前五名等. 在orcale等数据库中可以使用partition 语句来解决,但在MySQL中就比较麻烦了.这次翻译的文章就是 ...
- 如何在mysql中实现自然排序
背景 熟悉mysql的同学应该清楚,mysql在对字符串做order by排序时是按照字典序进行排序的,但是如果字符串中包含数字的话(我们称这种类型的字符串为alphanumeric),仅按照字典序的 ...
- 如何在MySQL中设置外键约束
引用:http://blog.sina.com.cn/s/blog_53729e4601011wja.html MySql外键设置详解 (1) 外键的使用: 外键的作用,主要有两个: 一个是 ...
- 如何在MySQL中输入中文
解决MySQL中的Incorrect string value MySQL中输入中文:在MySQL建标的时候,直接往表中的varchar(255)中输入中文的话是会报错的,大概是因为数据库的默认编码是 ...
- [转]Sphinx+Mysql+中文分词安装-实现中文全文搜索
From : http://blog.csdn.net/lgm252008/article/details/5373436 1.什么是SphinxSphinx 是一个在GPLv2 下发布的一个全文检索 ...
随机推荐
- Runtime机制之结构体及操作函数
一.动态语言 Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:具有灵活性,比如:消息转发,方法交换等.它有一个运行时系统Ob ...
- Debian的一个命令
dpkg是一个Debian的一个命令行工具,它可以用来安装.删除.构建和管理Debian的软件包.下面是它的一些命令解释:1)安装软件命令行:dpkg -i <.deb file name> ...
- iOS中精确时间的获取
下面是一段无法查证出处的英文和自己的翻译 A quick and easy way to measure the performance of a piece of iOS code is to di ...
- django中添加用户
在django中添加用户,直接在auth_user表中添加会有问题,因为这里密码是加密的,可以通过manage.py shell加入 创建User: 1 >>> from djang ...
- 在yii中使用gearman
最近项目需要将利用gearman进行任务调度,目前所用框架为yii,在部署好gearman后,试图在yii中调用gearman,一直报错: 提示reverse函数没有定义,明明已经定义了啊!可能是当时 ...
- html中button的type属性
接触web开发不久,今天遇到了一个问题,点击button按钮,浏览器没有反应,尝试了自己可以想到的所有办法,还是无果.只得请教他人,才发现是button的type属性搞得怪,原来: ...
- hibernate进阶--一对多映射配置
hibernate作为一款优秀的ORM框架,广受大家喜爱,也被Java社区公认为持久层的首选.虽然jdbc为Java数据库操 作带来了诸多便利,但是并没有统一SQL语句的写法,而且具体操作数据库的代码 ...
- Java基础——异常体系
在Java中,异常对象都是派生于Throwable类的一个实例,Java的异常体系如下图所示: 所有的异常都是由Throwable继承而来,在下一层立即分解为两个分支,Error和Exception. ...
- 【Hibernate 8】Hibernate的调优方法:抓取策略
在上一篇博客中,介绍了Hibernate的缓存机制.合理的配置缓存,可以极大程度上优化Hibernate的性能.这篇博客,介绍另外一个调优方式:抓取策略. 一.什么是抓取策略 抓取策略(fetchin ...
- zedboard如何从PL端控制DDR读写(一)
看了一段时间的DDR手册,感觉大体有一点了解了,想要实际上板调试,然而实验室可用的开发板不多,拿了一块zynq板看了看,DDR确实有,但是已经集成了控制器,而且控制器还放到了PS端,PL只能通过AXI ...