仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 559|回复: 8
打印 上一主题 下一主题

[学习教程] 公布合适做复杂搜刮的MySQL数据库全文索引

[复制链接]
简单生活 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 20:13:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
每个人都在使用它。MySQL是开源LAMP组合的一个标准组件:Linux、Apache、MySQL和Perl/PHP。根据Evans的调查,LAMP组合的迅速推广很大程度上代表着MySQL的被广泛接受。全文索引在MySQL中是一个FULLTEXT范例索引。FULLTEXT索援用于MyISAM表,能够在CREATETABLE时或以后利用ALTERTABLE或CREATEINDEX在CHAR、VARCHAR或TEXT列上创立。关于年夜的数据库,将数据装载到一个没有FULLTEXT索引的表中,然后再利用ALTERTABLE(或CREATEINDEX)创立索引,这将长短常快的。将数据装载到一个已有FULLTEXT索引的表中,将长短常慢的。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">全文搜刮经由过程MATCH()函数完成:<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">mysql>CREATETABLEarticles(<Pstyle="TEXT-INDENT:2em">->idINTUNSIGNEDAUTO_INCREMENTNOTNULLPRIMARYKEY,<Pstyle="TEXT-INDENT:2em">->titleVARCHAR(200),<Pstyle="TEXT-INDENT:2em">->bodyTEXT,<Pstyle="TEXT-INDENT:2em">->FULLTEXT(title,body)<Pstyle="TEXT-INDENT:2em">->);<Pstyle="TEXT-INDENT:2em">QueryOK,0rowsaffected(0.00sec)<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">mysql>INSERTINTOarticlesVALUES<Pstyle="TEXT-INDENT:2em">->(NULL,MySQLTutorial,DBMSstandsforDataBase...),<Pstyle="TEXT-INDENT:2em">->(NULL,HowToUseMySQLEfficiently,Afteryouwentthrougha...),<Pstyle="TEXT-INDENT:2em">->(NULL,OptimisingMySQL,Inthistutorialwewillshow...),<Pstyle="TEXT-INDENT:2em">->(NULL,1001MySQLTricks,1.Neverrunmysqldasroot.2....),<Pstyle="TEXT-INDENT:2em">->(NULL,MySQLvs.YourSQL,Inthefollowingdatabasecomparison...),<Pstyle="TEXT-INDENT:2em">->(NULL,MySQLSecurity,Whenconfiguredproperly,MySQL...);<Pstyle="TEXT-INDENT:2em">QueryOK,6rowsaffected(0.00sec)<Pstyle="TEXT-INDENT:2em">Records:6Duplicates:0Warnings:0<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">mysql>SELECT*FROMarticles<Pstyle="TEXT-INDENT:2em">->WHEREMATCH(title,body)AGAINST(database);<Pstyle="TEXT-INDENT:2em">+----+-------------------+------------------------------------------+<Pstyle="TEXT-INDENT:2em">|id|title|body|<Pstyle="TEXT-INDENT:2em">+----+-------------------+------------------------------------------+<Pstyle="TEXT-INDENT:2em">|5|MySQLvs.YourSQL|Inthefollowingdatabasecomparison...|<Pstyle="TEXT-INDENT:2em">|1|MySQLTutorial|DBMSstandsforDataBase...|<Pstyle="TEXT-INDENT:2em">+----+-------------------+------------------------------------------+<Pstyle="TEXT-INDENT:2em">2rowsinset(0.00sec)<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">函数MATCH()对比一个文本集(包括在一个FULLTEXT索引中的一个或多个列的列集)实行一个天然言语搜刮一个字符串。搜刮字符串做为AGAINST()的参数被给定。搜刮以疏忽字母巨细写的体例实行。关于表中的每一个纪录行,MATCH()前往一个相干性值。即,在搜刮字符串与纪录行在MATCH()列表中指定的列的文本之间的类似性标准。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">当MATCH()被利用在一个WHERE子句中时(参看下面的例子),前往的纪录行被主动地以相干性从高究竟的序次排序。相干性值长短负的浮点数字。零相干性意味着不类似。相干性的盘算是基于:词在纪录行中的数量、外行中独一词的数量、在会合词的全体数量和包括一个特别词的文档(纪录行)的数量。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">它也能够实行一个逻辑形式的搜刮。这鄙人面的章节中被形貌。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">后面的例子是函数MATCH()利用上的一些基础申明。纪录行以类似性递加的按次前往。下一个示例显现怎样检索一个明白的类似性值。假如即没有WHERE也没有ORDERBY子句,前往行是不排序的。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">mysql>SELECTid,MATCH(title,body)AGAINST(Tutorial)FROMarticles;<Pstyle="TEXT-INDENT:2em">+----+-----------------------------------------+<Pstyle="TEXT-INDENT:2em">|id|MATCH(title,body)AGAINST(Tutorial)|<Pstyle="TEXT-INDENT:2em">+----+-----------------------------------------+<Pstyle="TEXT-INDENT:2em">|1|0.64840710366884|<Pstyle="TEXT-INDENT:2em">|2|0|<Pstyle="TEXT-INDENT:2em">|3|0.66266459031789|<Pstyle="TEXT-INDENT:2em">|4|0|<Pstyle="TEXT-INDENT:2em">|5|0|<Pstyle="TEXT-INDENT:2em">|6|0|<Pstyle="TEXT-INDENT:2em">+----+-----------------------------------------+<Pstyle="TEXT-INDENT:2em">6rowsinset(0.00sec)<Pstyle="TEXT-INDENT:2em">上面的示例更庞大一点。查询前往类似性并仍然以类似度递加的序次前往纪录行。为了完成这个了局,你应当指定MATCH()两次。这不会引发附加的开支,由于MySQL优化器会注重到两次一样的MATCH()挪用,并只挪用一次全文搜刮代码。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">mysql>SELECTid,body,MATCH(title,body)AGAINST<Pstyle="TEXT-INDENT:2em">->(SecurityimplicationsofrunningMySQLasroot)ASscore<Pstyle="TEXT-INDENT:2em">->FROMarticlesWHEREMATCH(title,body)AGAINST<Pstyle="TEXT-INDENT:2em">->(SecurityimplicationsofrunningMySQLasroot);<Pstyle="TEXT-INDENT:2em">+----+-------------------------------------+-----------------+<Pstyle="TEXT-INDENT:2em">|id|body|score|<Pstyle="TEXT-INDENT:2em">+----+-------------------------------------+-----------------+<Pstyle="TEXT-INDENT:2em">|4|1.Neverrunmysqldasroot.2....|1.5055546709332|<Pstyle="TEXT-INDENT:2em">|6|Whenconfiguredproperly,MySQL...|1.31140957288|<Pstyle="TEXT-INDENT:2em">+----+-------------------------------------+-----------------+<Pstyle="TEXT-INDENT:2em">2rowsinset(0.00sec)<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">MySQL利用一个十分复杂的分析器来将文天职隔成词。一个“词”是由笔墨、数据、“”和“_”构成的任何字符序列。任安在stopWord列表上呈现的,或太短的(3个字符或更少的)的“word”将被疏忽。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">在集和查询中的每一个符合的词依据其在集与查询中的主要性权衡。如许,一个呈现在多个文档中的词将有较低的权重(大概乃至有一个零权重),由于在这个特定的会合,它有较低的语义值。不然,假如词是较少的,它将失掉一个较高的权重。然后,词的权重将被分离用于盘算纪录行的类似性。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">如许一个手艺事情可很好地事情与年夜的集(实践上,它会当心地与之谐调)。关于十分小的表,词分类不敷以充份地反响它们的语义值,偶然这个形式大概发生奇异的了局。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">mysql>SELECT*FROMarticlesWHEREMATCH(title,body)AGAINST(MySQL);<Pstyle="TEXT-INDENT:2em">Emptyset(0.00sec)<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">在下面的例子中,搜刮词MySQL却没有失掉任何了局,由于这个词在凌驾一半的纪录行中呈现。一样的,它被无效地处置为一个stopword(即,一个零语义值的词)。这是最幻想的举动--一个天然言语的查询不该该从一个1GB的表中前往每一个次行(secondrow)。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">婚配表中一半纪录行的词很少大概找到相干文档。实践上,它大概会发明很多不相干的文档。我们都晓得,当我们在互联网上经由过程搜刮引擎试图搜刮某些器材时,这会常常产生。由于这个缘故原由,在这个特别的数据会合,如许的行被设置一个低的语义值。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">到4.0.1时,MySQL也能够利用INBOOLEANMODE润色语来实行一个逻辑全文搜刮。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">mysql>SELECT*FROMarticlesWHEREMATCH(title,body)<Pstyle="TEXT-INDENT:2em">->AGAINST(+MySQL-YourSQLINBOOLEANMODE);<Pstyle="TEXT-INDENT:2em">+----+------------------------------+-------------------------------------+<Pstyle="TEXT-INDENT:2em">|id|title|body|<Pstyle="TEXT-INDENT:2em">+----+------------------------------+-------------------------------------+<Pstyle="TEXT-INDENT:2em">|1|MySQLTutorial|DBMSstandsforDataBase...|<Pstyle="TEXT-INDENT:2em">|2|HowToUseMySQLEfficiently|Afteryouwentthrougha...|<Pstyle="TEXT-INDENT:2em">|3|OptimisingMySQL|Inthistutorialwewillshow...|<Pstyle="TEXT-INDENT:2em">|4|1001MySQLTricks|1.Neverrunmysqldasroot.2....|<Pstyle="TEXT-INDENT:2em">|6|MySQLSecurity|Whenconfiguredproperly,MySQL...|+----+------------------------------+-------------------------------------+
<Pstyle="TEXT-INDENT:2em"><Pclass=a14cstyle="TEXT-INDENT:2em"><SPANclass=a14cid=zoom><Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">这个查询前往一切包括词MySQL的纪录行(注重:50%的阈值没有利用),可是它没有包括词YourSQL。注重,一个逻辑形式的搜刮不会主动地以类似值的降序排序纪录行。你能够从下面的了局出看得出来,最高的类似值(包括MySQL两次的谁人)最列在最初,而不是第一名。一个逻辑全文搜刮即便在没有一个FULLTEXT索引的情形下也能够事情,但是它慢些。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">逻辑全文搜刮撑持上面的操纵符:“+”一个领头的加号暗示,该词必需呈现在每一个前往的纪录行中,“-”一个领头的减号暗示,该词必需不呈现在每一个前往的纪录行中。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">缺省的(当既没有加号也没有负号被指准时)词是随便的,可是包括它的纪录即将被分列地更高一点。这个仿照没有INBOLEANMODE润色词的MATCH()...AGAINST()的举动。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">这两个操纵符用于改动一个词的类似性值的基值。<操纵符削减基值,>操纵符则增添它。参看上面的示例。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">()圆括号用于对子表达式中的词分组。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">~一个领头的否认号的感化象一个否认操纵符,引发行类似性的词的基值为负的。它对标志一个噪声词很有效。一个包括如许的词的纪录将被分列得低一点,可是不会被完整的扫除,由于如许可使用-操纵符。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">*一个星号是截断操纵符。不想别的的操纵符,它应当被追加到一个词后,不加在后面。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">"短语,被包抄在双引号"中,只婚配包括这个短语(字面上的,就仿佛被键进的)的纪录行。<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">这里是一些示例:<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">applebanana<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">找最少包括下面词中的一个的纪录行<Pstyle="TEXT-INDENT:2em"><Pstyle="TEXT-INDENT:2em">1.+apple+juice...两个词均在被包括<Pstyle="TEXT-INDENT:2em">2.+applemacintosh...包括词“apple”,可是假如同时包括“macintosh”,它的分列将更高一些<Pstyle="TEXT-INDENT:2em">3.+apple-macintosh...包括“apple”但不包括“macintosh”<Pstyle="TEXT-INDENT:2em">4.+apple+(>pie
飘灵儿 该用户已被删除
沙发
发表于 2015-1-18 18:52:48 | 只看该作者
对一张百万级别的表建游标,同时又没有什么过滤条件,取得游标效率是如果直接SQL查询百万条数据;如果再对每条记录做处理,耗时将更长。
山那边是海 该用户已被删除
板凳
发表于 2015-1-25 08:58:11 来自手机 | 只看该作者
大家注意一点。如下面的例子:
飘飘悠悠 该用户已被删除
地板
发表于 2015-2-2 21:29:25 | 只看该作者
其实可以做一下类比,Oracle等数据库产品老早就支持了java编程,而且提供了java池参数作为用户配置接口。但是现在有哪些系统大批使用了java存储过程?!连Oracle自己的应用都不用为什么?!
5#
发表于 2015-2-8 06:24:14 | 只看该作者
从底层原理到表层引用,书籍多的很。个人认为没有什么那本书好?这样的说法。主要看和个人的学习方法是否适合。
谁可相欹 该用户已被删除
6#
发表于 2015-2-24 21:39:36 | 只看该作者
无法深入到数据库系统层面去了解和探究
因胸联盟 该用户已被删除
7#
发表于 2015-3-7 13:49:43 | 只看该作者
无法深入到数据库系统层面去了解和探究
老尸 该用户已被删除
8#
发表于 2015-3-15 07:33:56 | 只看该作者
其实可以做一下类比,Oracle等数据库产品老早就支持了java编程,而且提供了java池参数作为用户配置接口。但是现在有哪些系统大批使用了java存储过程?!连Oracle自己的应用都不用为什么?!
第二个灵魂 该用户已被删除
9#
发表于 2015-3-21 22:57:16 | 只看该作者
但换公司用MSSQL2K感觉自己好像根本就不了解MSSQL。什么DTS触发器以前根本没用过。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 12:04

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表