zoukankan      html  css  js  c++  java
  • MySQL——检索进阶

    禁止码迷,布布扣,豌豆代理,码农教程,爱码网等第三方爬虫网站爬取!

    子查询

    所谓子查询,其实就是对检索的结果进行检索,也就是一种查询的嵌套,即我在查询到的数据中再次查询想要的数据。

    子查询过滤

    因为子查询是对检索的结果进行检索,可以理解为限定条件的查询,那么子查询应当有过滤功能。

    这段代码发生了什么?可以被拆分为 2 步:

    当然子查询是可以一直嵌套的,不仅局限于 2 层而已。

    子查询计算字段

    可以利用计算字段的构造实现子查询,即将查询的结果作为一个新的字段进行操作。

    这个时候的子查询会因为检索出来的行数而重复执行多次,也就是每检索一次就使用一次子查询。

    • 使用计算字段实现子查询必须使用完全限定列名,否则会因为嵌套而产生二义性。

    联结表

    联结

    联结是 SQL 的必杀技之一,可以在数据检索的时候实现联结表。在学习联结之前,需要先了解一下关系表的基本概念,给出一个写得不错的博客连接——数据库-表关系。这里只强调外键,所谓外键为某个表的一个列,该列是另一个表的主键,通过外键可以使 2 个表产生关联。
    将数据存储于多个表中,可以通过组合的方式使得数据可以适应更多、更好的功能,因此如何将这些分散的数据联结为一个新的我们想要的表,就需要使用联结。
    联结有一些注意事项,首先是使用联结时需要指定联结类型,第二是联结的条件需要给出,并且要保证书写正确。下面的讲解将对这些进行强调。

    创建联结

    想要创建联结,就需要包含多个表,同时为了消除二义性,所有的列都需要用完全限定列名来指定。

    • 这里需要注意结合 WHERE 语句进行过滤,否则联结的表将会把所有被包含的行统统都联结。

    也可以这么来写,使用 INNER JOIN 来指定来源于哪些表,然后用 ON 来指定联结的规则。

    这种联结方式称之为等值联结内部联结,这是根据 2 个表之间相同的字段进行联结的方式。
    联结的表的个数也是没有限制的,在开销允许的范围内可以联结多个表。

    表别名

    联结是允许使用表别名的,使用表别名可以使重复调用表变得容易,表别名是服务器的内部行为。

    自联结

    自联结顾名思义,也就是一个表自己和自己按照一定的规则进行联结的用法。对于自联结我们可能要根据需求取一些表别名,因为表本身的关键字都是一样的,因此自联结会有二义性,取一些表别名更便于管理数据。

    当然这个功能也可以用子查询来实现,不同的是往往自联结的用法,开销会比子查询小得多。

    自然联结

    所谓自然联结,指的是对表进行联结时应该至少有一个列出现在多个表中,并排除多次出现,使每个列只返回一次。自然联结我们往往这么用,选择一个表获取全部列,然后用这份数据来规定其他表使用的字段。前面讨论的都是内联结,所谓内联结根据 2 个表之间相同的字段进行联结的方式,可以理解为取交集,所有的内联结都是自然联结。

    外部联结

    现在来看看外联结,所谓外联结就是联结表包含了没有关联的行。外联结有 2 种,分别是左外联结右外联结,分别使用关键字 LEFT OUTER JOINRIGHT OUTER JOIN,他们分别表示是从左边的表选择所有行还是右边的表。我们首先先来看看内联结和外联结的区别:


    可以看到,外联结会把没有关联的行一并联结进来。现在看看左外联结和右外联结的区别:

    由于右联结是以右侧的表为基准的,因此有些数据并没有出现。不过你也发现了,右联结其实就是左联结的 2 个表顺序倒过来写,效果是一样的。

    联结使用聚集函数

    在进行联结操作的时候,可以使用聚集函数来一并参与数据处理。比较典型的用法就是构建分组,然后利用分组来做联结操作。聚集函数对内联结和外联结来说都是适用的。

    在这里首先对 “orders” 的 “order_num” 字段构建分组,然后将这个分组当做一个新的列去参与联结操作。

    组合查询

    前面我们讨论过一个检索中使用多个 SELECT 语句的检索方式,也就是子查询,子查询中 SELECT 是一种嵌套关系。现在看看组合查询,所谓组合查询就是执行多个 SELECT,然后将这些查询结果进行合并,最后返回一个结果。组合查询有 2 种比较常见的用法,一种是对单个表进行了多次查询,一种是单个查询中操作了不同的表,对此可以进行合并。

    创建组合查询

    要创建组合查询就需要使用 UNION 操作符来实现,用这个操作符可以合并几个 SELECT 返回的结果。语法框架为:

    SELECT expression1, expression2, ... expression_n
    FROM tables
    [WHERE conditions]
    UNION [ALL | DISTINCT]
    SELECT expression1, expression2, ... expression_n
    FROM tables
    [WHERE conditions];
    

    UNION 操作符有以下注意事项:

    1. 必须有不小于 2 个的 SELECT 才能使用 UNION 操作符;
    2. 被组合的 SELECT 必须拥有相同的列、表达式、聚集函数;
    3. 列与列之间的数据类型需要时兼容的。

    UNION 操作符使用方式是放在需要组合的 SELECT 的中间,例如:

    这个结果就是从以下 2 个结果组合的:


    不过,其实这个也可以用 WHERE 来过滤,也能起到相同的效果。具体使用哪种写法,还要具体问题具体分析。

    是否去重

    UNION 操作符返回的是去重后的数据,如果我不希望去重的话可以为 UNION 指定一个 ALL 参数即可。

    组合查询排序

    对组合查询的结果当然可以排序,不过对被组合的每个 SELECT 进行排序是没有意义的,一组合就又乱序了。因此在组合查询时只能有 1 个 ORDER BY,位于最后一行表示对分组查询的整体结果进行排序。

    全文本检索

    更智能的搜索

    之前我们使用的通配符或正则表达式进行对关键字的检索,效果很好,但是还是有一些不足的。首先是这样的检索就需要对所有的行进行检索,那么当数据量过多时就会带来性能问题。第二是这样的检索都是完全匹配的,对于模糊查找或者是部分索引而言,没有很强大的功能。这个时候我们就需要更为智能的检索方式,一种不错的选择是使用全文本搜索
    全文本搜索有以下注意事项:

    1. 被添加入非用词列表的词和短词(默认 3 个字符及以下的词)将会被自动忽略;
    2. 某个词出现频率很高时将被自动添加入非用词列表;
    3. 检索的表中若行数少于 3 行,不返回任何结果;
    4. 词之间的单引号将被自动忽略,即 “ it's ” 将被认为是 “its”;
    5. MySQL 暂不支持临近操作符。

    数据库引擎

    数据库的搜索基于对数据库引擎的使用,例如 MyISAMInnoDB,但是并不是所有引擎都可以支持全文本检索,例如 InnoDB 引擎就不支持。

    建立索引

    所谓全文本搜索,并不是对全部的字段进行匹配,而是通过一种名为索引的功能。所谓索引就是在指定的列中指定一些词,用这些词构建一个索引,然后进行检索时就可以根据这些词进行更高效的检索。
    在一张表被建立时,可以使用 FULLTEXT 子句启用全文本搜索。通过在该子句中指定构建检索的列,列的数量可以是多个,定义之后 MySQL 将会自动维护索引。当我需要全文本搜索时,就可以根据建立的检索进行匹配。检索可以在建表的时候进行指定,也可以在后续指定。值得一提的是导入数据时,数据的量是过多的,还没有根据需要进行管理。这个时候启用全本文检索的话,对维护检索的开销是很大的,因此全文本搜索应该避免在数据大量变动时启用。

    ENGINE 则是用于指定这个表的搜索引擎。

    进行搜索

    要进行全文本搜索,就需要使用 Match() 函数和 Against() 函数进行联合工作。Match() 函数用于指定被搜索的列,其中指定的列必须已经被 FULLTEXT 子句所建立检索,Against() 函数用于指定搜索的内容。

    当然这个搜索也可以使用 LIKE 子句实现,不同在于全文本搜索更为智能。例如全文本搜索的结果会自动排序,例如可以按照检索词的出现位置的前后进行排序,这样对于数据的组织更为方便。这个功能的机理是什么?在全文本搜索时 Match() 函数和 Against() 函数会根据搜索的效果,通过一定的规则计算出一个值,用这个值来度量检索的相关度,依次决定是否回显和次序。

    查询拓展

    所谓查询拓展,也就是对一个关键字进行相关性查询,即使这个结果没有包含检索词,也能通过一定的规则判断是否相关。要实现这个功能,就需要基于全文本搜索找到所需要的数据,然后通过这些信息为参考进行一次新的全文本搜索,此时的结果将根据相关性返回更多信息。例如对于一次全文本搜索:

    对其使用查询扩展,将会返回具有相关性的数据,例如复现的单词。

    Bool 文本搜索

    布尔方式

    使用 布尔方式 (boolean mode) 可以使文本搜索能够附带更多信息,例如需要匹配的词、排斥的词、回显数据优先级等信息。由于这种方式比较精确,因此一般会结合全文本搜索来进行,保证效率。想要使用布尔方式,就需要加入关键字 IN BOOLEAN MODE

    布尔操作符

    操作符 功能
    + 包含检索词
    - 排除检索词
    > 包含检索词并提高优先级
    < 包含检索词并减少优先级
    () 将词组成表达式
    ~ 取消词的排序值
    * 词尾的通配符
    "" 定义短语
    • 将被组成的表达式可以被包含、排除或排序。

    实例

    这个例子可以排除包含指定字符的所有行。

    这个例子查找同时包含指定单词的所有行。

    这个例子查找存在指定单词的所有行。

    这个例子查找同时包含指定短语的所有行。

    这个例子给定了指定单词的优先级。

    这个例子查找了表达式。

    参考资料

    《MySQL Crash Course》[英] Ben Forta 著,刘晓霞 钟鸣 译,人民邮电出版社
    菜鸟教程——MySQL 教程

  • 相关阅读:
    记某b/s项目维护思路及心得
    Csla.Net架构学习总结
    ado.net entity framework使用odp.net(ODAC for .net)连接oracle11g体验
    向北走,还是向南走。也谈创业...
    星级豪华酒店如何提高利润回报率
    .net compact framework2.0 Wince智能设备开发项目经验分享 .net拖空间之进阶篇
    Cipherlab CPT9300手持扫描枪开发体验
    LogMiner日志分析工具的使用
    微软首度承认Linux威胁Windows
    有关SYSDATE与DBLINK的问题
  • 原文地址:https://www.cnblogs.com/linfangnan/p/12892504.html
Copyright © 2011-2022 走看看