SQL最强大的的一个特性是能够在数据检索查询内自由的连接表。连接是使用SQL SELECT可以执行的最重要操作之一。
外键:
一个表中的一列,其中包含另一个表中的主键值,因此定义了两个表之间的关系。
使用外键好处:
可以高效的存储和轻松的操作关系数据。因此,关系数据库的可扩展性比非关系型数据库要好得多。
**可扩展性:**能够处理越来越多的负载,而不会出现失败。设计良好的数据库或应用程序被称为可扩展性良好。
注意参照完整性
连接不是一个物理实体,换句话说,它并不存在于实际的数据表中。
创建连接非常简单,必须指定要包括的所有表,以及它们彼此之间如何关联。
SELECT vend_name, prod_name, prod_price
FROM vendors, products
WHERE vendors.vend_id = products.vend_id
ORDER BY vend_name, prod_name;
警告:完全限定列名
无论何时,为了防止引用的列可能出现歧义,都必须使用完全限定的列名(用点号把表和列分隔开)。如果引用一个有歧义的列名,而没有利用表名对其进行完全限定,Oracle就会返回一条错误消息。
在select与语句中连接表时,关系将是自由构造的。数据库表的定义中并未指示Oracle如何连接表,你必须自己执行这个任务。在连接两个表时,实际上所做的事情是把第一个表中的每一行与第二个表中的每一行进行配对。WHERE子句充当过滤器,以只包括与指定的过滤条件(在这里是连接条件)匹配的行。如果没有WHERE子句,将把第一个表中的每一行与第二个表中的每一行进行配对,而无论它们在逻辑上是否相配。
笛卡尔积:
由不带有连接条件的表关系返回的结果。检索的行数是第一个表中的行数乘以第二个表中的行数。
SELECT vend_name, prod_name, prod_price
FROM vendors, products
ORDER BY vend_name, prod_name;
从上面的输出可以看出,大部分笛卡尔积都不是我们想要的。
警告:
一定要确保所有的连接都具有where子句,否则Oracle将返回比你所想要的多的多的数据。类似的,还要确保where子句是正确的。
提示:
有时,返回笛卡尔积的连接类型被称为交叉连接
目前为止,我们使用的连接称为等值连接–基于两个表之间的相等性测试的连接,这类连接也称为内连接
内连接的标准用法:
SELECT vend_name, prod_name, prod_price
FROM vendors INNER JOIN products
ON vendors.vend_id = products.vend_id;
在此,两个表之间关系是指定为inner join的from子句的一部分。当使用这种语法时,使用特殊的On子句代替where子句来指定连接条件。传递给ON的实际条件于传递给where的条件相同。
注意:使用那种语法?
依据ANSI SQL规范,使用INNER JOIN语法更可取。
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 = 20005;
这里的from子句列出了3个表,where子句定义了两个连接条件。
警告:警惕性能下降
Oracle在运行时处理连接,按指定的规则把每个表相关联。这个过程可能非常消耗资源,因此要小心谨慎,不可连接不必要的表。连接的表越多,性能将降级得越厉害。