《MySQL必知必会》个人实现全记录(5)——15~18章

前言

上一节链接:《MySQL必知必会》个人实现全记录(4)——11~14章-CSDN博客

上一节末尾,我们谈到了相关子查询和完全限定列名,这标志着我们的检索对象从一张表逐渐拓展到多张表。本节进一步学习多表之间的检索。

本节内容:联结表、创建高级联结、组合查询、全文本搜索。本节结束后,课本涉及的select的高级功能学习完毕。


第15章:联结表

本章将介绍什么是联结,为什么要使用联结,如何编写使用联结的 SELECT语句。

关系表和联结

关系表的设计就是要保证把信息分解成多个表,一类数据 一个表。各表通过某些常用的值(即关系设计中的关系(relational))互 相关联。

外键(foreign key) :外键为某个表中的一列,它包含另一个表 的主键值,定义了两个表之间的关系。

联结是一种机制,用来在一条SELECT 语句中关联表,因此称之为联结。使用特殊的语法,可以联结多个表返 回一组输出,联结在运行时关联表中正确的行。

维护引用完整性 ,通过在表的定义中指定主键和外键来实现的。

创建联结

SELECT vend_name,prod_name,prod_price
FROM vendors,products
WHERE vendors.vend_id=products.vend_id
ORDER BY vend_name,prod_name;

SELECT vend_name,prod_name,prod_price
FROM vendors INNER JOIN products
ON vendors.vend_id=products.vend_id;

两段代码效果一致,并且都使用了联结,第一种被称为等值联结,第二种称为内部联结,一般推荐使用第二种语法。用on代替where子句,效果是完全一致的。

联结可以联结若干个表,但是联结的越多,性能越差,尽可能避免联结太多表。


第16章:创建高级联结

本章将讲解另外一些联结类型(包括它们的含义和使用方法),介绍如何对被联结的表使用表别名和聚集函数。

使用表别名

一个例子就足够了

SELECT cust_name,cust_contact
FROM customers AS c,orders AS o,orderitems AS oi
WHERE c.cust_id=o.cust_id
AND oi.order_num=o.order_num
AND prod_id='TNT2';

自联结、自然联结、外部联结

#自联结
SELECT p1.prod_id,p1.prod_name
FROM products AS p1,products AS p2
WHERE p1.vend_id=p2.vend_id
AND p2.prod_id='DTNTR';
#自然联结
SELECT *
FROM vendors NATURAL JOIN products
WHERE vendors.vend_id=products.vend_id;
#外部联结
SELECT customers.cust_id,orders.order_num
FROM customers LEFT OUTER JOIN orders
#FROM customers RIGHT OUTER JOIN orders
ON customers.cust_id=orders.cust_id;

自联结用于自己检索自己,必须使用表别名,使用自联结的原因是子检索不能很方便检索自己。

自然联结要求两个表必须有相同的表列,任何内部联结都是自然联结。

外部联结允许null值,强调联结那些本没有关联行的行

总结:

  • 内部联结:匹配两个表格中完全匹配的行
  • 自然联结:自动基于所有同名列匹配,可以看作是隐式的内部联结
  • 外部联结:至少给出左表或右表所有的行,同时给出两个表匹配的行
  • 自联结:用来操作自己

内部联结inner join、自联结(必须使用别名)、自然联结natural join、外部联结right/left outer join,非常重要,必须非常熟悉

使用带聚集函数的联结

一个例子,一看就明白

SELECT customers.cust_name,
       customers.cust_id,
       COUNT(orders.order_num) AS num_ord
FROM customers
LEFT OUTER JOIN orders
ON customers.cust_id=orders.cust_id
GROUP BY customers.cust_id;

第17章:组合查询

本章讲述如何利用UNION操作符将多条SELECT语句组合成一个结果集。

创建组合查询

使用union关键字,关键点:

  • UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分隔(因此,如果组合4条SELECT语句,将要使用3个 UNION关键字)。
  • UNION中的每个查询必须包含相同的列、表达式或聚集函数(不过各个列不需要以相同的次序列出)。
  • 列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含地转换的类型(例如,不同的数值类型或不同的日期类型)
  • 默认会取消重复的行,如果想包含返回所有行,使用union all
  • 只能使用一个order by子句,它放到最后,排序整个检索结果

一个例子

SELECT vend_id,prod_id,prod_price
FROM products
WHERE prod_price<=5
UNION ALL
SELECT vend_id,prod_id,prod_price
FROM products
WHERE vend_id IN (1001,1002)
ORDER BY vend_id,prod_price;

第18章:全文本搜索

本章将学习如何使用MySQL的全文本搜索功能进行高级的数据查询 和选择。

MySQL创建指定列中各词的一个索引,搜索可以针对这些词进 行。这样,MySQL可以快速有效地决定哪些词匹配(哪些行包含它们), 哪些词不匹配,它们匹配的频率,等等。

启用全文本搜索

在创建表的时候使用fulltext子句,给出全文本搜索的索引。然后使用两个函数Match()和Against()执行全文本搜索, 其中Match()指定被搜索的列,Against()指定要使用的搜索表达式。

放一段代码作为例子

SELECT note_text
FROM productnotes
WHERE MATCH(note_text) AGAINST('rabbit');

结果是两段文本

Customer complaint: rabbit has been able to detect trap, food apparently less effective now.

Quantity varies, sold by the sack load.
All guaranteed to be bright and orange, and suitable for use as rabbit bait.

注意事项:

  1. 传递给Match()的值必须与 FULLTEXT()定义中的相同。如果指定多个列,则必须列出它们(而且次序正确)。
  2. 除非使用BINARY方式,否则全文本搜索不区分大小写。

查询扩展

使用WITH QUERY EXPANSION关键字。不仅可以查询出原来搜索条件的文本,还能把检索出来的文本作为新的搜索条件二次检索。

布尔文本搜索

使用IN BOOLEAN MODE开启布尔文本搜索模式,以布尔方式,可以提供关于如下内容的细节:

  • 要匹配的词;
  • 要排斥的词(如果某行包含这个词,则不返回该行,即使它包含 其他指定的词也是如此);
  • 排列提示(指定某些词比其他词更重要,更重要的词等级更高);
  • 表达式分组;
  • 另外一些内容。

结语

这篇博客最重要的就是联结部分,必须熟练掌握。剩下的全文本搜索知道即可。

距离上一篇数据库博客发布已经过了很久,今天抽时间学了以下全文本搜索,把这部分学完吧。

mysql必知必会还有一篇博客的内容。包含视图、存储过程、触发器、事务处理的内容。我觉得这些都比较重要,打算改天专门抽一上午好好学一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值