登陆注册
19122000000029

第29章 MySQL的全文搜索(3)

程序运行,在搜索栏中输入词语“princess”,单击“搜索”按钮,执行全文搜索,在文本区域中显示结果。”

类似地,在搜索栏中输入“bobby”,单击“搜索”按钮。

6.3.2Web应用

使用PHP开发一个Web应用程序,连接MySQL数据库,执行全文搜索。这个案例只作为演示。

只含有一个文件mysql.php,代码如下:

mysql.php

<form action=mysql.php method=post>

<input name=search><input type=submit value="search"name="submit">

</form>

<?php

if(isset($ POST["submit"]))

{

echo"<table border=2bordercolor=red>";

$ connect=@ mysql connect("localhost","root","tianen");//连接数据库服务器

if(!$ connect)//验证连接是否成功

{

echo"wrong.";

exit;

}

mysql select db("tianen",$ connect);//选择数据库

$ query="select*from en where match(title,body)against("".$ POST["search"]."")";

//构造sql选择语句

$ result=mysql query($ query);//执行sql语句,将结果赋予$ result

$ rows=@ mysql num rows($ result);//返回记录数目

for($ i=0;$ i<$ rows;$ i++)//遍历记录

{

@ mysql data seek($ result,$ i);//定位记录

$ data=@ mysql fetch array($ result);//获得记录数组$ data

$ id=$ data[0];//获得相应字段值

$ title=$ data[1];

$ body=$ data[2];

echo"<tr><td>".$ id."</td><td>".$ title."</td><td>".$ body."</td>

</tr>";

}

echo"</table>";

mysql free result($ result);

mysql close($ connect);//关闭数据库连接

}

?>

在搜索栏中输入词语“princess”,单击“搜索”按钮,执行全文搜索,在网页上显示结果。

6.4中文问题

在英文排版时,词语间是以空格区分的,所以英文的分词是基于空格的。但是涉及中文等文字就没有这么简单了,因为中文词间并没有明显的区隔,所以中文的分词则是按照字典、词库的匹配和词的频度统计,或是基于句法、语法分析的分词,而MySQL并不具备此功能,所以MySQL对中文全文检索的支持几乎为零。

然而,中国也有很多使用MySQL的应用程序,许多程序都需要全文搜索的支持,该怎么办呢?

想了一下,可以进行编码。把汉字编成英文字符,字与字之间加上空格,然后MySQL就会识别这些字符了,并对其进行分词。

6.4.1编码解决

把汉字编成英文字符,这是什么意思?汉字怎么能变成英文字符?

1.拼音编码

可以看这个例子,“我爱祖国”,把其中的每个字变成拼音,中间再加上空格,然后得到的结果就是“wo ai zu guo”,在这种情况下,MySQL会把“wo”,“ai”等都当成英文单词。我们希望输入“祖国”,能和“我爱祖国”进行对比,但做不到。所以,用拼音作为桥梁,输入“zu guo”,然后和“wo ai zu guo”进行对比,还是可以找到一些结果的。

这就是网上某人的发明,写一个拼音转换程序,可以得到汉字的拼音表示,然后实现拼音和拼音之间的对比。

举个例子,现在数据库中有两条记录:“我爱计算机”和“努力学习”。

搜索的词是“学习”

这个时候,程序把“学习”变成“xue xi”,把数据库的两条记录变成:“wo ai ji suan ji”和“nuli xue xi”。

然后执行MySQL的全文搜索,当然,可以搜到结果。

这个方法有很多弊端。

它需要修改MySQL被编入索引单词的最小长度,把4改成2,因为汉字的拼音都是很短的。

需要编写一个程序实现数据库内信息的自动拼音转换,以及把原汉字文档保留副本等。

当然,这个程序并不难写。

输入“奴隶”,会查到“努力”,即便可以标出声调,比如“奴隶”是“nu2li4”,“努力”是“nu3li4”,但还是会有很多问题,汉语中同音不同意的词太多了。

不管怎样,它可以作为一种折中的方案,至少可以搜出一点东西来,不致于看着数据傻眼。

类似的方案有无数种,拼音只是编码方式的一种,而且是不怎么样的一种,有多少种编码方式就有多少种折中方案。

这里举一个例子,来说明通过汉字编码方式来解决中文全文搜索问题。

首先,在tianen数据库中建立一个新表格,语句如下:

CREATE TABLE ZH

id INTAUTO INCREMENT NOT NULL PRIMARY KEY,

title VARCHAR(200),

body TEXT,

new TEXT,

FULLTEXT(new),

FULLTEXT(body)

)type=MyISAM;

title是标题,body是汉字内容,new是编码后存储到数据库中的内容。对body和new分别作了全文索引。

向表格中添加若干测试数据,语句如下:

INSERT INTO ZH(title,body,new)VALUES("祖国","我爱祖国","wo ai zu guo");

INSERT INTO ZH(title,body,new)VALUES("人民","我爱人民","wo ai ren min");

INSERT INTO ZH(title,body,new)VALUES("山川","我爱山川","wo ai shan chuan");

现在,执行全文搜索,语句如下:

select*from zh where match(new)against("shan chuan");

select*from zh where match(new)against("zu guo");

可以看出来,“shan chuan”可以搜索出结果,这说明MySQL已经把它按照英文去处理了。

但“zu guo”无法搜索出结果,这是因为它们的长度都不到4,没有被键入索引。

依据这个原理去开发数据库程序,可以在数据库中新增一列,专门存储汉字搜索列的拼音拆分结果,这样,就可以搜索出一些结果来,虽然不准确,但还是可以凑合用。

2.汉字内码

在拼音编码方案里有一个问题,就是不同的汉字编码之后结果会相同,如“花”,“华”。由此导致的搜索不准确是可以避免的,因为汉字各不相同,把它们按照某种算法加密之后,应该也可以让它们的加密结果各不相同。这种加密算法是非常多的。MD5曾经是用得最广泛的算法,但是后来已经证明,不同的字符串经过MD5加密之后能得到相同的值,因此MD5不再是理想的单项加密算法了。SHA1算法目前被证明是非常好的加密算法,不妨尝试一下。

计算机上使用的汉字有两类代码,一类称为外码,用来输入汉字,如拼音码、郑码、五笔字型码等。由于人们不断寻求更佳的汉字输入法,因此外码也就层出不穷。不同的外码规则也不同,如果计算机内部存储汉字时,也采用这些五花八门的编码,势必使汉字系统过于复杂。

因此,不论用什么输入法输入的汉字,在存入存储器时,都将它的外码转换成一种统一的代码,这就是汉字内码。

一个汉字的内码由两个字节组成。汉字内码与区位码之间有一个简单的关系:

内码第一字节=区码+160

内码第二字节=位码+160

比如,查区位码表知道,“啊”字在16区01位,它的内码为:

第一字节=16+160=176

第二字节=1+160=161

英文字符的代码ASCII只用一个字节表示。为什么一个汉字要用两个字节来表示呢?

这是因为一个字节(8位二进制数)能表示的最大整数范围是0~255,也就是说最多能表示256种不同的状态,这用于表示几十个英文字符足够了。但是汉字有成千上万个,所以至少要用两个字节(16位二进制数)来编码。两个字节最多可有65536种不同的编码。

由于大多英文软件只处理单字节对象,而汉字内码又是双字节的,这就会带来一些问题。

比如我们用vi编辑一个文本文件,要删掉其中的一个汉字时,要敲两次删除键才能删掉。若是只删了一下,后面的汉字就变得面目全非了。道理很简单:删一下,只删掉了汉字内码的一个字节,剩下的一个字节和下一个汉字的头一个节就构成了另一个汉字或符号的内码,于是就显示出和这个内码对应的汉字或符号。依次错位,后面的汉字就全变了。

在PHP里面,ord()函数可以获得字符的内码第一字节,下面的案例,使用了sha1和ord两个函数来编码字符。

案例名称:编码中文

程序名称:zh.php

<?php

echo ord("我")."<br>";

echo ord("爱")."<br>";

echo ord("山")."<br>";

echo ord("川")."<br>";

echo"<hr>";

echo sha1("我")."<br>";

echo sha1("爱")."<br>";

echo sha1("山")."<br>";

echo sha1("川")."<br>";

?>

比较一下,不难看出SHA1算法生成的字符串太长,而ORD算法比较适合于编码中文,优于拼音编码。

6.4.2建议和提示

除了这种编码方法之外,还有其他的一些中文编码方法。

要注意,只有MyISAM类型的表才支持全文搜索,所以建立表格时应该标示出“type=MyISAM”。

CREATE TABLE EN

id INTAUTO INCREMENT NOT NULL PRIMARY KEY,

title VARCHAR(200),

body TEXT,

FULLTEXT(title,body)

)type=MyISAM;

如果一个表原本不是MyISAM类型的,要将其修改为MyISAM类型,可以使用下面的语句:

alter table EN type=MyISAM;

为一个表增加全文索引的方法如下:

alter table EN add fulltext(title);

小结

本章介绍了MySQL全文搜索的原理和使用方法。并且探讨了解决中文搜索的方案。需要重点掌握的是MySQL进行全文搜索的格式。

思考与练习

1.MySQL数据库有哪些优良特性?

2.使用PHP和MySQL开发一套全文搜索系统。

同类推荐
  • 政治学(第二版)

    政治学(第二版)

    书在系统总结已有政治学理论研究成果的基础上,介绍和评述了现当代许多国内外学者在政治学方面的一些重要学术观点,对国家形态、政治权力、政党政治、政治参与、政治发展、政治民主、政治文化等政治学核心范畴作了较为深入并富有新意的分析和阐述,比较客观地反映了政治学科发展中的一些带有普遍意义的现象和规律,使抽象的理论更贴近中外政治发展的现实。本书作为复旦版MPA(公共管理硕士)系列教材之一,既可作为MPA课程的基本教材,又可作为大专院校政治学专业和行政管理学专业的本科和专科的专业教材。
  • 语文新课标必读——伊索寓言精选

    语文新课标必读——伊索寓言精选

    《伊索寓言》是全世界拥有读者最多的一本书,它对西方伦理道德、政治思想影响最大。它是东西方民间文学的精华,劳动人民智慧的结晶。它也是影响人类文化的100本书之一。
  • 改变孩子先改变自己

    改变孩子先改变自己

    这本书是著名家庭教育专家、网瘾戒除专家、2012年中国家庭教育“十佳公益人物”贾容韬老师成为一个好爸爸的心理历程及他这么多年教育方法的汇集。贾容韬老师原来是做企业的,由于孩子教育出了问题,成为年级倒数第一名,还差点被学校开除,痛心之余,贾老师决定做陪读爸爸。在这个过程中,贾老师也进行了反思,发现孩子的问题其实主要是家长教育方法的问题,他开始从书本上学习,看了上千本书,做了80多万字的教育笔记,同时调整自己的教育方法,他的教育方法改变了,孩子也发生了根本变化,逐渐好学上进,最后还考上了全国重点大学。贾老师把自己摸索出的经验用于指导其他咨询他的家长,指导了几千个家庭,都取得了非常好的效果。
  • 法制教育七年级(上)

    法制教育七年级(上)

    本书主要介绍各种法的有关内容。例如:野生动物是人类的朋友,是宝贵的自然资源。野生动物保护法正是为了保护、拯救珍贵濒危野生动物,保护、发展和合理利用野生动物资源,维护生态平衡而制定的。学习野生动物保护法,能够帮助同学们从小树立爱护野生动物的观念。
  • 中小学生综合实践活动-日常体育学习指导

    中小学生综合实践活动-日常体育学习指导

    综合实践活动是现代教育中的个性内容、体验内容和反思内容,与传统教育片面追求教育个体的发展、共性和知识有所不同,综合实践活动提供了一个相对独立的学习生态化空间,学生是这个空间的主导者,学生具有整个活动绝对的支配权和主导权,能够以自我和团队为中心,推动活动的进行。在这个过程中,学生更谋求独立完成整个活动,而不是聆听教诲和听取指导。教师在综合实践活动这个生态化空间里,只是一个绝对的引导者、指导者和旁观者。
热门推荐
  • 凤于九天:云梦泽之苍龙劫

    凤于九天:云梦泽之苍龙劫

    古老的神话里,有一个极为美丽的国度,并且有着一个梦幻般的名字——云梦泽。一次偶然的机会,她与他的男友穿越到了这边古国里,并对这神仙般的地方产生了倦恋。然,天地惊变,日月失辉,已化身公主的她,又有了保家卫国的念头!龙凤剑,天下定,他们相信,凭他们的智慧,一定能把云梦泽拉回平静的!(内容纯属虚构,请勿模仿)
  • EXO之月球背面

    EXO之月球背面

    很久很久以前,上帝创造出宇宙后,给每个行星分配了不同的技能,而最特殊的是——月亮。月亮上有着十二个魔法王国,几百年、几千年、几万年,从未战争,和谐相处。可是,他们最大的敌人出现了——地球上的人类。近几年来,人类一直想挖掘每个行星的秘密,月亮上的人们报告了上帝,上帝不得不把整个月球王国缩小,移至月球背面,至少,几十年人类还不能到达月球背面。上帝让每个王国派1个人去地球生活,得到一些信息来帮助自己的星球。魔法加冕仪式开始了。那十二个人将在地球发生什么事情?虐心,才真正开始……
  • 异界天才与中二少年

    异界天才与中二少年

    这是一个来自异大陆的天才魔法师胤与中二高中生张杨互换了身体的故事……看天才魔法师如果在现世处理从未经历的人情世故,在看中二少年如何探险异世界
  • 邪肆天下

    邪肆天下

    魔族邪尊洛邪,以玩的一手巧妙的毒术、医术出名。一身亦正亦邪的性格还有莫测的实力也是让人头疼,落入空间虫洞进入另一个世界,又将翻起怎样一阵风雨?
  • 战神物语

    战神物语

    “嗯,因为我是少林寺的住持,所以必须要做好防范啦,对不起。”少女自然的谈吐间,似乎说出了什么值得注意的话。而后,少年呆呆地重复道他所注意的部分:“少林寺……的住持?”眼前的这个少女,是少林寺的住持?
  • 火影之武道巅峰

    火影之武道巅峰

    国术杀手遭受强敌伏杀,死于枪弹之下,意外之际竟然穿越到火影之中成为热血青春的少年李洛克,且看冷酷追求武道巅峰的国术高手如何在火影之中成就巅峰!三观绝对正若是喜欢请收藏!
  • 灵魂之所地球最后一百人的希望

    灵魂之所地球最后一百人的希望

    原本作为一个坚定不移的足控张浩瀚活的虽然颓废,倒也是挺滋润的原本平凡,有点小聪明,小胆怯的少年哪知自己被选为地球最优秀的100位年轻人又怎能料到他能够拯救整个地球拜托,他只想做个低调的足控变态好不好
  • 恋上同桌你的萌

    恋上同桌你的萌

    刚开始及不情愿的做他的同桌,然后慢慢开始接纳他的搞怪,接着我喜欢上他的一切……
  • 如画山河

    如画山河

    很简单,现代人穿越古代,发大财混高干的故事。故事里有点小感动,有点小热血,一路走来,体会人生百味,道尽世事蹉跎,挺好看,挺耐读,大抵如此。精心编一个故事,给大家消遣娱乐,仅此而已。顺便拜求支持,躬身拜谢。
  • 千年之梦之魔王战记

    千年之梦之魔王战记

    在经过了几千年前光明神加路菲尔与黑暗神阿玛迪斯的传说后,波卡大陆进入了人类的时代.而在现在帝国逐渐向整个大陆发动统一战争趋势与教会的势力渗透入整个世界时,以光明与黑暗之名两人的出现究竟代表着传说还是真实?