SQL必知必会—联结表

《SQL必知必会》读书笔记

1.关系表

这里写图片描述

将这些数据与产品信息分开存储的理由市:

  • 同一个供应商生产的每个产品,其供应商信息都是相同的,对每个产品重复此信息既浪费时间又浪费存储空间;
  • 如果供应商信息发生变化,例如供应商迁址或电话号码变动,只需修改一次即可;
  • 如果有重复数据(即每种产品都存储供应商信息),则很难保证每次输入该数据的方式都相同。不一致的数据在报表中就很难利用。

关键是,相同的数据出现多次决不是一件好事,这是关系数据库设计的基础。关系表的设计就是要把信息分解成多个表,一类数据一个表。各表通过共同的值互相关联(所以才叫关系数据框)。

所以建立两个表:一个存储供应商信息,另一个存储产品信息。

Vendors表包含所有供应商信息,每个供应商占一行,具有唯一的标识。此标识称为主键,可以是供应商ID或任何其他唯一值。

Products表只存储产品信息,除了存储供应商ID(Vendors表的主键)外,它不存储其他有关供应商的信息。

Vendors表的主键将Vendors表与Products表关联,利用Products的供应商ID能从Vendors表中找出相应供应商的详细信息。

这样做的好处是:

  • 供应商信息不重复,不会浪费时间和空间;
  • 如果供应商信息变动,可以只更新Vendors表中的单个记录,相关表中的数据不用改动;
  • 由于数据不重复,数据显然是一致的,使得处理数据和生成报表更简单。

总之,关系数据库可以有效地存储,方便地处理。因此,关系数据库地可伸缩性远比非关系数据库要好。

2.为什么使用联结

如前所述,将数据分解为多个表能更有效地存储,更方便地处理,并且可伸缩性更好。但是这些好处是有代价的。

如果数据存储在多个表中,怎么用一条SELECT语句就检索出数据呢?

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

3.创建联结

SELECT vend_name,prod_name,prod_price
FROM Vendors, Products
WHERE Vendors.vend_id = Products.vend_id;

这里写图片描述

3.WHERE子句的重要性

WHERE子句作为过滤条件,只包含那些匹配给定条件(这里是联结条件)的行。

没有WHERE子句,第一个表中的每一行将与第二个表中的每一行配对,而不管它们逻辑上是否能配在一起。

笛卡尔积:

由没有联结条件的表关系返回的结果为笛卡尔积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。

提示:叉联结

有时,返回笛卡尔积的联结,也称叉联结。

这里写图片描述

这里写图片描述

这里写图片描述

从上面的输出可以看出,相应的笛卡儿积不是我们想要的。这里返回的数据用每个供应商匹配每个产品,包括了供应商不正确的产品(即使供应商根本就没有产品)。

4.内联结

目前为止使用的联结称为等值联接,它基于两个表之间的相等测试。这种联结也称为内联结。

其实,可以对这种联结使用稍微不同的语法,明确指定联结的类型。

下面的SELECT语句返回与前面例子完全相同的数据:

SELECT vend_name, prod_name, prod_price
FROM Vendors INNER JOIN Products
ON Vendors.vend_id  = Products.vend_id;

这里,两个表之间的关系是以INNER JOIN指定的部分FROM子句。在使用这种语法时,联结条件用特定的ON子句而不是WHERE子句给出。

5.联结多个表

SQL不限制一条SELECT语句中可以联结的表的数目。创建联结的基本规则也相同。

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 = 20007;

注意:性能考虑

DBMS在运行时关联指定的每个表,以处理联结。这种处理可能非常耗费资源,因此应该注意,不要联结不必要的表。联结的表越多,性能下降越厉害。

注意:联结中表的最大数目

虽然SQL本身不限制每个联结约束中表的数目,但实际上许多DBMS都有限制。

现在回顾一下第11课中的例子,如下的SELECT语句返回订购产品RGAN01的顾客列表:

SELECT cust_name,cust_contact
FROM Customers
WHERE cust_id IN(
                SELECT cust_id 
                FROM Order
                WHERE order_num IN(
                                SELECT order_num 
                                FROM OrderItems
                                WHERE prod_id = 'RGAN01'
                                )
                )

如第11课所述,子查询并不总是执行复杂SELECT操作的最有效方法,下面时是以联结的相同查询:

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_idc = 'RGAN01';

cust_name       cust_contact
Fun4All         Denise L. Stephens
The Toy Stores  Kim Howard          
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值