第十五章 联结表

学习目标:
了解什么是联结,为什么要使用联结,如何编写使用联结的SELECT语句。
 
联结:
SQL最强大的功能之一就是能在数据检索查询的执行中联结(join)表。
 
关系表:
关系表的设计就是要保证把信息分解成多个表,一类数据 一个表。各表通过某些常用的值(即关系设计中的关系(relational))互相关联。
 
外键(foreign key)外键为某个表中的一列,它包含零一个表的主键值,定义了两个表之间的关系。
 
可伸缩性(scale)能够适应不不断增加的工作量而不失败。设计良好的数据库或应用程序称之为可伸缩性好(scale well)。
 
为什么要使用联结:
为了解决用单条SELECT语句检索出存储在多个表中的数据。
 
维护引用完整性:
联结不是物理实体,它在实际的数据库表中不存在。联结是由MySQL根据需要建立, 它存在于查询的执行当中。
 
在使用关系表时,仅在关系列中插入合法的数据非常重要。如果products表中插入拥有非法供应商ID(即没有在venders表中出现)的供应商生产的产品,则这些产品是不可以访问的,因为它们没有关联到某个供应商。
 
为了防止这种情况的发生,可指示MySQL只允许在products表的供应商ID列出现合法值(及出现在venders表中的供应商)。这就是维护引用完整性,它是通过表的定义中指定主键和外键来实现的。
 
创建联结:
联结的创建非常简单,规定要联结的所有表及它们如何关联即可。
 
SELECT vend_name, prod_name,prod_price
FROM vendors, products
WHERE vendors.vend_id = products.vend_id (完全限定列名)
ORDER BY vend_name, prod_name;
 
WHERE子句的重要性:
WHERE子句作为过滤条件指示MySQL如何对表进行联结。
 
笛卡尔积(cartesian product):
由没有联结条件的表关系返回的结果为笛卡尔积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。
 
SELECT vend_name, prod_name,prod_price
FROM vendors, products
ORDER BY vend_name, prod_name;
 
不要忘了WNERE子句,应该保证所有联结都有WHERE子句,否则MySQL将返回比想要的数据多得多的数据。同理,应该保证WHERE子句的正确性。不正确的过滤条件将导致MySQL返回不正确的数据。
 
叉联结(cross join)
 
内部联结(equijoin):
目前为止所用的联结称为等值联结(equijoin),它基于两个表之间的 相等测试。这种联结也称为内部联结。
 
SELECT vend_name, prod_name,prod_price
FROM vendors INNER JOIN products
ON vendors.vend_id = products.vend_id;
 
ANSI SQL规范首选INNER JOIN语法。
 
联结多个表:
SQL对一条SELECT语句中可以联结的表的数目没有限制。创建联结的基本规则也相同。
 
Q:显示编号为20005的订单中的物品。
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在运行时关联指定的每个表以处理联结。这种处理可能是非常耗费资源的,因此应该仔细,不要联结不必要表。联结的表越多,性能下降的越厉害。
 
 
##Q返回订购产品TNT2的客户列表;语句的书写层次,从外到里。
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';

posted @ 2018-10-23 18:31  慕木林  阅读(119)  评论(0编辑  收藏  举报