美文网首页
十二、联结表

十二、联结表

作者: 曾经像素有点低 | 来源:发表于2023-02-24 19:52 被阅读0次
    工程师加油💪🏻.png
    • 什么是联结
    • 为什么使用联结
    • 如何编写使用联结的SELECT 语句。

    1 联结

    SQL 最强大的功能之一就是能在数据查询的执行中联结(join)表。联结
    是利用 SQL 的 SELECT 能执行的最重要的操作,很好地理解联结及其语
    法是学习 SQL 的极为重要的部分。

    1.1关系表

    举例:

    • 场景:
      有一个包含产品目录的数据库表,其中每类物品占一行。对于每一种物品,要存储的信息包括产品描述、价格,以及生产该产品的供应商。
      现在有同一供应商生产的多种物品,那么在何处存储供应商名、地址、联系方法等供应商信息呢?

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

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

    关键是,相同的数据出现多次决不是一件好事,这是关系数据库设计的基础。关系表的设计就是要把信息分解成多个表,一类数据一个表。各表通过某些共同的值互相关联(所以才叫关系数据库)。
    在这个例子中可建立两个表:一个存储供应商信息,另一个存储产品信息。
    Vendors 表包含所有供应商信息,每个供应商占一行,具有唯一的标识。此标识称为主键(primary key),可以是供应商 ID 或任何其他唯一值。
    Products 表只存储产品信息,除了存储供应商 ID(Vendors 表的主键)外,它不存储其他有关供应商的信息。
    Vendors 表的主键将 Vendors 表 与 Products 表关联,利用供应商 ID 能从 Vendors 表中找出相应供应商的详细信息。

    这样做的好处是:

    • a 供应商信息不重复,不会浪费时间和空间;
    • b 如果供应商信息变动,可以只更新 Vendors 表中的单个记录,相关表中的数据不用改动;
    • c 由于数据不重复,数据显然是一致的,使得处理数据和生成报表更简单。
    总之,关系数据可以有效地存储,方便地处理。因此,关系数据库的可伸缩性远比非关系数据库要好。

    可伸缩(scale)
    能够适应不断增加的工作量而不失败。设计良好的数据库或应用程序称为可伸缩性好(scale well)

    1.2 为什么使用联结

    答:
    因为将数据分解为多个表能更有效地存储,更方便地处理,并且可伸缩性更好。

    但这些好处是有代价的:如果数据存储在多个表中,
    怎样用一条 SELECT 语句就检索出数据呢?
    答:使用联结。
    简单说,联结是一种机制,用来在一条 SELECT 语句中关联表,因此称为联结。使用特殊的语法,可以联结多个表返回一组输出,联结在运行时关联表中正确的行。

    **说明:使用交互式 DBMS 工具 **
    重要的是,要理解联结不是物理实体。换句话说,它在实际的数据库表中并不存在。
    DBMS 会根据需要建立联结,它在查询执行期间一直存在。许多 DBMS 提供图形界面,用来交互式地定义表关系。这些工具极其有助于维护引用完整性。在使用关系表时,仅在关系列中插入合法数据是非常重要的。
    回到这里的例子,如果 Products 表中存储了无效
    的供应商 ID,则相应的产品不可访问,因为它们没有关联到某个供应商。为避免这种情况发生,可指示数据库只允许在 Products 表的供应商 ID 列中出现合法值(即出现在 Vendors 表中的供应商)。引用完整性表示 DBMS 强制实施数据完整性规则。这些规则一般由提供了界面的 DBMS 管理。

    2 创建联结

    创建联结非常简单,指定要联结的所有表以及关联它们的方式即可。请看下面的例子:

    SELECT vend_name, prod_name, prod_price
    FROM Vendors, Products
    WHERE Vendors.vend_id = Products.vend_id;
    
    vend_name prod_name prod_price
    Doll House Inc. Fish bean bag toy 3.4900
    Doll House Inc. Bird bean bag toy 3.4900
    Doll House Inc. Rabbit bean bag toy 3.4900
    Bears R Us 8 inch teddy bear 5.9900
    Bears R Us 12 inch teddy bear 8.9900
    Bears R Us 18 inch teddy bear 11.9900
    Doll House Inc. Raggedy Ann 4.9900
    Fun and Games King doll 9.4900
    Fun and Games Queen doll 9.4900
    • 我们来看这段代码。SELECT 语句与前面所有语句一样指定要检索的列。这里最大的差别是所指定的两列(prod_name 和 prod_price)在一个表中,而第一列(vend_name)在另一个表中。

    • 现在来看 FROM 子句。与以前的 SELECT 语句不一样,这条语句的 FROM子句列出了两个表:Vendors 和 Products。它们就是这条 SELECT 语句联结的两个表的名字。这两个表用 WHERE 子句正确地联结,WHERE 子句指示 DBMS 将 Vendors 表中的 vend_id 与 Products 表中的 vend_id 匹配起来。

    • 可以看到,要匹配的两列指定为 Vendors.vend_id 和 Products.vend_id。这里需要这种完全限定列名,如果只给出 vend_id,DBMS 就不知道指的是哪一个(每个表中有一个)。从前面的输出可以看到,一条 SELECT 语句返回了两个不同表中的数据。

    警告:完全限定列名
    在引用的列可能出现歧义时,必须使用完全限定
    列名(用一个句点分隔表名和列名)。如果引用一个没有用表名限制的具有歧义的列名,大多数 DBMS 会返回错误。

    2.1 WHERE子句的重要性

    使用 WHERE 子句建立联结关系似乎有点奇怪,但实际上是有个很充分的理由的。要记住,在一条 SELECT 语句中联结几个表时,相应的关系是在运行中构造的。在数据库表的定义中没有指示 DBMS 如何对表进行联结的内容。你必须自己做这件事情。在联结两个表时,实际要做的是将第一个表中的每一行与第二个表中的每一行配对。WHERE 子句作为过滤条件,只包含那些匹配给定条件(这里是联结条件)的行。没有 WHERE子句,第一个表中的每一行将与第二个表中的每一行配对,而不管它们逻辑上是否能配在一起。

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

    要保证所有联结都有WHERE 子句
    否则 DBMS 将返回比想要的数据多得多的数据。同理,要保证 WHERE 子句的正确性。不正确的过滤条件会导致 DBMS 返回不正确的数据。

    提示:叉联结
    有时,返回笛卡儿积的联结,也称叉联结(cross join)。

    2.2 内联结

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

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

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

    相关文章

      网友评论

          本文标题:十二、联结表

          本文链接:https://www.haomeiwen.com/subject/jlvxldtx.html