0%

《MySQL必知必会》读书笔记 第十五章 连结表

联结

联结是利用SQL的SELECT能执行的最重要的操作。

关系表

假如有由同一供应商生产的多种物品,将供应商信息和产品信息分开存储的理由如下。

  • 因为同一供应商生产的每个产品的供应商信息都是相同的,对每个产品重复此信息既浪费时间又浪费存储空间。
  • 如果供应商信息改变,只需改动一次即可。
  • 如果有重复数据,很难保证每次输入该数据的方式都相同。不一致的数据在报表中很难利用。

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

products表只存储产品信息,它除了存储供应商ID外不存储其他供应商信息。vendors表的主键又叫作products的外键,它将vendors表与products表关联。

为什么要使用联结

如果数据存储在多个表中,怎样用单条SELECT语句检索出数据?答案是使用联结。

联结是一种机制,用来在一条SELECT语句中关联表。

创建联结

1
2
3
4
SELECT vend_name, prod_name, prod_pricce
FROM vendors, products
WHERE vendors.vend_id = products.vend_id
ORDER BY vend_name, prod_name

在引用的列可能出现二义性时,必须使用完全限定列名。

WHERE子句的重要性

在一条SELECT语句中联结几个表时,相应的关系是在运行中构造的。在数据库表的定义中不存在能指示MySQL如何对表进行联结的东西。

在联结两个表时,实际上是将第一个表中的每一行与第二个表中的每一行配对。所以增加要过滤条件去匹配指定的行。

叉联结会返回笛卡尔积。

内部联结

等值联结基于两个表之间的相等测试,这种联结也称为内部联结。

内部联结还有一种不同的语法:

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

使用这种语法时,联结条件用特定的ON子句而不是WHERE子句给出。

联结多个表

SQL对一条SELECT语句中可以联结的表的数目没有限制。

1
2
3
4
5
SELECT prod_name, vend_name, prod_price, quantity
FROM orderitems, products, vendors
WHERE products.vend_id = vendors.vend_id
AND orderitems.prod_id = products.prod_id
AND order_num = 20005;

MySQL在运行时关联指定的每个表以处理联结。这种处理可能是非常耗费资源的。联结的表越多,性能下降越厉害。

查询订购产品TNT2的客户列表,可以使用子查询或联结

1
2
3
4
5
SELECT cust_name, cust_contact
FROM customers, orders, orderitems
WHERE customers.cust_id = orders.cust_id
AND orderitems.order_num = orders.order_num
AND prod_id = 'TNT2';

性能可能会受操作类型、表中数据量、是否存在索引或键以及其他一些条件的影响。因此,有必要对不同的选择机制进行实验,以找出最适合具体情况的方法。