再现理想 发表于 2015-1-16 20:11:45

MYSQL教程之MySQL全文搜刮

每个人都在使用它。MySQL是开源LAMP组合的一个标准组件:Linux、Apache、MySQL和Perl/PHP。根据Evans的调查,LAMP组合的迅速推广很大程度上代表着MySQL的被广泛接受。全文索引在MySQL中是一个FULLTEXT范例索引。FULLTEXT索援用于MyISAM表,能够在CREATETABLE时或以后利用ALTERTABLE或CREATEINDEX在CHAR、VARCHAR或TEXT列上创立。关于年夜的数据库,将数据装载到一个没有FULLTEXT索引的表中,然后再利用ALTERTABLE(或CREATEINDEX)创立索引,这将长短常快的。将数据装载到一个已有FULLTEXT索引的表中,将长短常慢的。
全文搜刮经由过程MATCH()函数完成。
mysql>CREATETABLEarticles(
->idINTUNSIGNEDAUTO_INCREMENTNOTNULLPRIMARYKEY,
->titleVARCHAR(200),
->bodyTEXT,
->FULLTEXT(title,body)
->);
QueryOK,0rowsaffected(0.00sec)
mysql>INSERTINTOarticlesVALUES
->(NULL,MySQLTutorial,DBMSstandsforDataBase...),
->(NULL,HowToUseMySQLEfficiently,Afteryouwentthrougha...),
->(NULL,OptimisingMySQL,Inthistutorialwewillshow...),
->(NULL,1001MySQLTricks,1.Neverrunmysqldasroot.2....),
->(NULL,MySQLvs.YourSQL,Inthefollowingdatabasecomparison...),
->(NULL,MySQLSecurity,Whenconfiguredproperly,MySQL...);
QueryOK,6rowsaffected(0.00sec)
Records:6Duplicates:0Warnings:0
mysql>SELECT*FROMarticles
->WHEREMATCH(title,body)AGAINST(database);
+----+-------------------+------------------------------------------+
|id|title|body|
+----+-------------------+------------------------------------------+
|5|MySQLvs.YourSQL|Inthefollowingdatabasecomparison...|
|1|MySQLTutorial|DBMSstandsforDataBase...|
+----+-------------------+------------------------------------------+
2rowsinset(0.00sec)函数MATCH()对比一个文本集(包括在一个FULLTEXT索引中的一个或多个列的列集)实行一个天然言语搜刮一个字符串。搜刮字符串做为AGAINST()的参数被给定。搜刮以疏忽字母巨细写的体例实行。关于表中的每一个纪录行,MATCH()前往一个相干性值。即,在搜刮字符串与纪录行在MATCH()列表中指定的列的文本之间的类似性标准。
当MATCH()被利用在一个WHERE子句中时(参看下面的例子),前往的纪录行被主动地以相干性从高究竟的序次排序。相干性值长短负的浮点数字。零相干性意味着不类似。相干性的盘算是基于:词在纪录行中的数量、外行中独一词的数量、在会合词的全体数量和包括一个特别词的文档(纪录行)的数量。
它也能够实行一个逻辑形式的搜刮。这鄙人面的章节中被形貌。
后面的例子是函数MATCH()利用上的一些基础申明。纪录行以类似性递加的按次前往。
下一个示例显现怎样检索一个明白的类似性值。假如即没有WHERE也没有ORDERBY子句,前往行是不排序的。
mysql>SELECTid,MATCH(title,body)AGAINST(Tutorial)FROMarticles;
+----+-----------------------------------------+
|id|MATCH(title,body)AGAINST(Tutorial)|
+----+-----------------------------------------+
|1|0.64840710366884|
|2|0|
|3|0.66266459031789|
|4|0|
|5|0|
|6|0|
+----+-----------------------------------------+
6rowsinset(0.00sec)上面的示例更庞大一点。查询前往类似性并仍然以类似度递加的序次前往纪录行。为了完成这个了局,你应当指定MATCH()两次。这不会引发附加的开支,由于MySQL优化器会注重到两次一样的MATCH()挪用,并只挪用一次全文搜刮代码。
mysql>SELECTid,body,MATCH(title,body)AGAINST
->(SecurityimplicationsofrunningMySQLasroot)ASscore
->FROMarticlesWHEREMATCH(title,body)AGAINST
->(SecurityimplicationsofrunningMySQLasroot);
+----+-------------------------------------+-----------------+
|id|body|score|
+----+-------------------------------------+-----------------+
|4|1.Neverrunmysqldasroot.2....|1.5055546709332|
|6|Whenconfiguredproperly,MySQL...|1.31140957288|
+----+-------------------------------------+-----------------+
2rowsinset(0.00sec)MySQL利用一个十分复杂的分析器来将文天职隔成词。一个“词”是由笔墨、数据、“”和“_”构成的任何字符序列。任安在stopWord列表上呈现的,或太短的(3个字符或更少的)的“word”将被疏忽。
在集和查询中的每一个符合的词依据其在集与查询中的主要性权衡。如许,一个呈现在多个文档中的词将有较低的权重(大概乃至有一个零权重),由于在这个特定的会合,它有较低的语义值。不然,假如词是较少的,它将失掉一个较高的权重。然后,词的权重将被分离用于盘算纪录行的类似性。
如许一个手艺事情可很好地事情与年夜的集(实践上,它会当心地与之谐调)。关于十分小的表,词分类不敷以充份地反响它们的语义值,偶然这个形式大概发生奇异的了局。
mysql>SELECT*FROMarticlesWHEREMATCH(title,body)AGAINST(MySQL);
Emptyset(0.00sec)在下面的例子中,搜刮词MySQL却没有失掉任何了局,由于这个词在凌驾一半的纪录行中呈现。一样的,它被无效地处置为一个stopword(即,一个零语义值的词)。这是最幻想的举动--一个天然言语的查询不该该从一个1GB的表中前往每一个次行(secondrow)。
婚配表中一半纪录行的词很少大概找到相干文档。实践上,它大概会发明很多不相干的文档。我们都晓得,当我们在互联网上经由过程搜刮引擎试图搜刮某些器材时,这会常常产生。由于这个缘故原由,在这个特别的数据会合,如许的行被设置一个低的语义值。
到4.0.1时,MySQL也能够利用INBOOLEANMODE润色语来实行一个逻辑全文搜刮。
mysql>SELECT*FROMarticlesWHEREMATCH(title,body)
->AGAINST(+MySQL-YourSQLINBOOLEANMODE);
+----+------------------------------+-------------------------------------+
|id|title|body|
+----+------------------------------+-------------------------------------+
|1|MySQLTutorial|DBMSstandsforDataBase...|
|2|HowToUseMySQLEfficiently|Afteryouwentthrougha...|
|3|OptimisingMySQL|Inthistutorialwewillshow...|
|4|1001MySQLTricks|1.Neverrunmysqldasroot.2....|
|6|MySQLSecurity|Whenconfiguredproperly,MySQL...|
+----+------------------------------+-------------------------------------+这个查询前往一切包括词MySQL的纪录行(注重:50%的阈值没有利用),可是它没有包括词YourSQL。注重,一个逻辑形式的搜刮不会主动地以类似值的降序排序纪录行。你能够从下面的了局出看得出来,最高的类似值(包括MySQL两次的谁人)最列在最初,而不是第一名。一个逻辑全文搜刮即便在没有一个FULLTEXT索引的情形下也能够事情,但是它慢些。
逻辑全文搜刮撑持上面的操纵符:
+
一个领头的加号暗示,该词必需呈现在每一个前往的纪录行中。
-
一个领头的减号暗示,该词必需不呈现在每一个前往的纪录行中。
缺省的(当既没有加号也没有负号被指准时)词是随便的,可是包括它的纪录即将被分列地更高一点。这个仿照没有INBOOLEANMODE润色词的MATCH()...AGAINST()的举动。

这两个操纵符用于改动一个词的类似性值的基值。<操纵符削减基值,>操纵符则增添它。参看上面的示例。
()
圆括号用于对子表达式中的词分组。
~
一个领头的否认号的感化象一个否认操纵符,引发行类似性的词的基值为负的。它对标志一个噪声词很有效。一个包括如许的词的纪录将被分列得低一点,可是不会被完整的扫除,由于如许可使用-操纵符。
*
一个星号是截断操纵符。不想别的的操纵符,它应当被追加到一个词后,不加在后面。
"
短语,被包抄在双引号"中,只婚配包括这个短语(字面上的,就仿佛被键进的)的纪录行。
这里是一些示例:
applebanana
找最少包括下面词中的一个的纪录行
+apple+juice
...两个词均在被包括
+applemacintosh
...包括词“apple”,可是假如同时包括“macintosh”,它的分列将更高一些
+apple-macintosh
...包括“apple”但不包括“macintosh”
+apple+(>pie<strudel)
...包括“apple”和“pie”,大概包括的是“apple”和“strudel”(以任何序次),可是“applepie”分列得比“applestrudel”要高一点
apple*
...包括“apple”,“apples”,“applesauce”和“applet”
"somewords"
...能够包括“somewordsofwisdom”,但不是“somenoisewords”
全文的限定
MATCH()函数的一切参数必需是历来自于统一张表的列,同时必需是统一个FULLTEXT索引中的一部分,除非MATCH()是INBOOLEANMODE的。
MATCH()列列表必需切实地婚配表的某一FULLTEXT索引中界说的列列表,除非MATCH()是INBOOLEANMODE的。
AGAINST()的参数必需是一个常量字符串。
微调MySQL全文搜刮
不幸地,全文搜刮仍旧只要很少的用户可调参数,固然增添一些在TODO上分列很高。假如你有一个MySQL源码刊行,你能够发扬对全文搜刮的更多把持。
注重,全文搜刮为最好的搜刮效果,被细心地调剂了。修正默许值的举动,在年夜多半情形下,只会使搜刮了局更糟。不要修正MySQL的源代码,除非你晓得你在做甚么!
被索引的词的最小长度由MySQL变量ft_min_word_len指定。
stopword列表能够从ft_stopword_file变量指定的文件中读取。
50%阈值选择由所选择的特别的权衡形式断定。为了克制它,修正`myisam/ftdefs.h文件中上面的一行:
#defineGWS_IN_USEGWS_PROB改成:
#defineGWS_IN_USEGWS_FREQ然后从头编译MySQL。在这类情形下,不必要重修索引。注重:利用了这个,将严峻地削减MySQL为MATCH()供应充足的类似性值的才能。假如你的确必要搜刮如许的大众词,最好利用INBOOLEANMODE的搜刮取代,它不恪守50%的阈值。
偶然,搜刮引擎保护员但愿变动利用于逻辑全文搜刮的操纵符。这些由变量ft_boolean_syntax界说。关于这些变动,请求你重修你的FULLTEXT索引,关于一个MyISAM表,最简单的重修索引文件的体例以下面的语句:
mysql>REPAIRTABLEtbl_nameQUICK;全文搜刮TODO
使一切对FULLTEXT索引的操纵更快
临近(Proximity)操纵符
对"always-indexwords"的撑持。他们能够是用户但愿视为一个词处置的恣意字符串,比方"C++"、"AS/400"、"TCP/ip",等等
撑持在MERGE表中的全文搜刮
对多字节字符的撑持
按照数据的言语创建stopword列表
Stemming(固然,依附于数据的言语)
Genericuser-suppliableUDFpreparser.
使形式加倍天真(经由过程为CREATE/ALTERTABLE中的FULLTEXT增添某些可调剂参数)
通过支付一定费用,客户可以得到优先的24/7支持,访问内容丰富的在线知识库和联系一个专门的技术负责经理。

愤怒的大鸟 发表于 2015-1-18 18:27:22

然后最好有实践机会,能够把实践到的和实践结合起来,其实理论思考是个非常困扰和痛苦的事情

乐观 发表于 2015-1-25 19:57:21

然后最好有实践机会,能够把实践到的和实践结合起来,其实理论思考是个非常困扰和痛苦的事情

金色的骷髅 发表于 2015-2-3 20:00:13

你可以简单地认为适合的就是好,不适合就是不好。

飘飘悠悠 发表于 2015-2-9 05:27:34

我是一个ERP初学者,对于前台运用基本熟悉,但对于后台SQLServer的运用一点也不懂,特想学习下相关资料。至少懂得一些基本的运用。希望各位能给于建议,小弟再谢过!

只想知道 发表于 2015-2-27 03:24:40

备份方面可能还是一个老大难的问题。不能单独备份几个表总是感觉不爽。灵活备份的问题不知道什么时候才能解决。

海妖 发表于 2015-3-8 19:49:56

代替了原来VB式的错误判断。比Oracle高级不少。

第二个灵魂 发表于 2015-3-16 14:18:42

你觉得我的非分区索引无法对起子分区,你可以提醒我一下呀!没有任何的提醒,直接就变成了非分区表。不知道这算不算一个bug。大家也可以试试。

小魔女 发表于 2015-3-22 23:32:55

groupby子句可以将查询结果分组,并返回行的汇总信息Oracle按照groupby子句中指定的表达式的值分组查询结果。
页: [1]
查看完整版本: MYSQL教程之MySQL全文搜刮