基本查询一节的示例中,我们有从 instructor 和 teaches 表组合信息,匹配条件是 instructor.ID 等于 teaches.ID 的查询,ID 属性是两个表中具有相同名称的所有属性,按照两个表中所有相同名称属性组合实际上是一种通用情况,即 from 子句中的匹配条件在最自然的情况下需要在所有匹配名称的属性上相等。因此,SQL 提供了完成这种操作的运算,称之为自然连接(natural join)。实际上,SQL 还支持更丰富的连接(join)运算,后面会提到。

自然连接运算作用于两个关系,并产生一个关系作为结果,不同于两个关系上的笛卡尔积,笛卡尔积将第一个关系的每个元组与第二个关系的所有元组都进行连接;自然连接只考虑那些在两个关系模式中都出现的属性上取值相同的元组对。

因此,回到 instructor 和 teaches 关系的例子上,它们的自然连接只考虑在唯一共有属性 ID 上取值相同的元组对。

mysql> select name, course_id
    -> from instructor natural join teaches;
+------------+-----------+
| name       | course_id |
+------------+-----------+
| Srinivasan | CS-101    |
| Srinivasan | CS-315    |
| Srinivasan | CS-347    |
| Wu         | FIN-201   |
| Mozart     | MU-199    |
| Einstein   | PHY-101   |
| El Said    | HIS-351   |
| Katz       | CS-101    |
| Katz       | CS-319    |
| Crick      | BIO-101   |
| Crick      | BIO-301   |
| Brandt     | CS-190    |
| Brandt     | CS-190    |
| Brandt     | CS-319    |
| Kim        | EE-181    |
+------------+-----------+
15 rows in set (0.01 sec)

我们知道 from 子句可以涉及多个关系,现在我们可以说,这些关系也可以是自然连接的结果,这是很直观的,因为自然连接的结果也是一个关系。

考虑查询,列出教师的名字以及他们讲授课程的名称。

mysql> select name, title
    -> from instructor natural join teaches, course
    -> where teaches.course_id = course.course_id;
+------------+----------------------------+
| name       | title                      |
+------------+----------------------------+
| Crick      | Intro. to Biology          |
| Crick      | Genetics                   |
| Srinivasan | Intro. to Computer Science |
| Katz       | Intro. to Computer Science |
| Brandt     | Game Design                |
| Brandt     | Game Design                |
| Srinivasan | Robotics                   |
| Katz       | Image Processing           |
| Brandt     | Image Processing           |
| Srinivasan | Database System Concepts   |
| Kim        | Intro. to Digital Systems  |
| Wu         | Investment Banking         |
| El Said    | World History              |
| Mozart     | Music Video Production     |
| Einstein   | Physical Principles        |
+------------+----------------------------+
15 rows in set (0.01 sec)

这个查询首先计算 instructor 和 teaches 的自然连接,如前所见,再计算这个救过和 course 的笛卡尔积,然后按照 where 子句筛选出结果,注意 where 子句中的 teaches.course_id 表示自然连接结果中的 course_id 域,这是因为该域最终来自 teaches 关系。

下面的查询给出的结果虽然在当前模式下相同,但其实是有问题的。

mysql> select name, title
    -> from instructor natural join teaches natural join course;
+------------+----------------------------+
| name       | title                      |
+------------+----------------------------+
| Crick      | Intro. to Biology          |
| Crick      | Genetics                   |
| Srinivasan | Intro. to Computer Science |
| Katz       | Intro. to Computer Science |
| Brandt     | Game Design                |
| Brandt     | Game Design                |
| Srinivasan | Robotics                   |
| Katz       | Image Processing           |
| Brandt     | Image Processing           |
| Srinivasan | Database System Concepts   |
| Kim        | Intro. to Digital Systems  |
| Wu         | Investment Banking         |
| El Said    | World History              |
| Mozart     | Music Video Production     |
| Einstein   | Physical Principles        |
+------------+----------------------------+
15 rows in set (0.00 sec)

它的问题在于 course 关系和 instructor 关系中都包含了 dept_name 属性,因此它们自然连接的结果要在这个属性上相同,这样的查询会遗漏以下模式的元组对,教师所讲授的课程不是他所在系的课程,前一个查询能够正确输出这样的元组对。

为了应付这个问题,即在保留自然连接的简洁性的同时规避过多的属性匹配,SQL 提供了一种自然连接的构造形式,允许用户来指定需要哪些列相等。

mysql> select name, title
    -> from (instructor natural join teaches) join course using (course_id);
+------------+----------------------------+
| name       | title                      |
+------------+----------------------------+
| Crick      | Intro. to Biology          |
| Crick      | Genetics                   |
| Srinivasan | Intro. to Computer Science |
| Katz       | Intro. to Computer Science |
| Brandt     | Game Design                |
| Brandt     | Game Design                |
| Srinivasan | Robotics                   |
| Katz       | Image Processing           |
| Brandt     | Image Processing           |
| Srinivasan | Database System Concepts   |
| Kim        | Intro. to Digital Systems  |
| Wu         | Investment Banking         |
| El Said    | World History              |
| Mozart     | Music Video Production     |
| Einstein   | Physical Principles        |
+------------+----------------------------+
15 rows in set (0.00 sec)

join ... using 运算中需要给定一个属性名列表,其两个输入中都必须具有指定名称的属性,考虑运算 r1 join r2 using (A1, A2),它与 r1 和 r2 的自然连接类似,只不过在 t1.A1 = t2.A1t1.A2 = t2.A2 的情况下就能匹配 r1 的元组 t1 和 r2 的元组 t2,即使它们都有属性 A3,也不考虑这个属性的事。

基于 MySQL 的数据库实践(自然连接)的更多相关文章

  1. 基于 MySQL 的数据库实践(基本查询)

    首先根据准备工作中的操作导入大学模式,打开数据库连接后进入到 MySQL 的交互界面,再使用命令 use db-book; 切换到 db-book 数据库. 单关系查询 SQL 查询的基本结构由三个子 ...

  2. 基于 MySQL 的数据库实践(准备工作)

    背景 本学期在北京大学选修了<数据库概论>的实验班课程,由于 SQL 语法并不是特别理论的内容,因此课上暂时也没有特别展开.出于探索数据库领域的兴趣,使用国内普遍使用的数据库软件 MySQ ...

  3. (原创)大数据时代:基于微软案例数据库数据挖掘知识点总结(Microsoft 决策树分析算法)

    随着大数据时代的到来,数据挖掘的重要性就变得显而易见,几种作为最低层的简单的数据挖掘算法,现在利用微软数据案例库做一个简要总结. 应用场景介绍 其实数据挖掘应用的场景无处不在,很多的环境都会应用到数据 ...

  4. Python操作MySQL以及数据库索引

    目录 python操作MySQL 安装 使用 SQL注入问题 MySQL的索引 为什么使用索引 索引的种类 主键索引 唯一索引 普通索引 索引优缺点 不会命中索引的情况 explain 索引覆盖 My ...

  5. 新浪微博基于MySQL的分布式数据库实践

    提起微博,相信大家都是很了解的.但是有谁知道微博的数据库架构是怎样的呢?在今天举行的2011数据库技术大会上,新浪首席DBA杨海潮为我们详细解读了新浪微博的数据库架构——基于MySQL的分布式数据库实 ...

  6. mysql,SQL标准,多表查询中内连接,外连接,自然连接等详解之查询结果集的笛卡尔积的演化

    先附上数据. CREATE TABLE `course` ( `cno` ) NOT NULL, `cname` ) CHARACTER SET utf8 NOT NULL, `ctime` ) NO ...

  7. 企业运维 | MySQL关系型数据库在Docker与Kubernetes容器环境中快速搭建部署主从实践

    [点击 关注「 WeiyiGeek」公众号 ] 设为「️ 星标」每天带你玩转网络安全运维.应用开发.物联网IOT学习! 希望各位看友[关注.点赞.评论.收藏.投币],助力每一个梦想. 本章目录 目录 ...

  8. 在Jena框架下基于MySQL数据库实现本体的存取操作

    在Jena框架下基于MySQL数据库实现本体的存取操作 转自:http://blog.csdn.net/jtz_mpp/article/details/6224311 最近在做一个基于本体的管理系统. ...

  9. 数据库连接池(基于MySQL数据库)

    使用JDBC是怎么保证数据库客户端和数据库服务端进行连接的? 通过代码: conn=DriverManager.getConnection(url, username, password); JDBC ...

随机推荐

  1. 笔记:Hibernate 查询缓存

    Hibernate 的一级缓存和二级缓存都是对实体进行缓存,他不会缓存普通属性,如果想对普通熟悉进行缓存,可以考虑使用查询缓存. 对于查询缓存来说,他缓存的Key就是查询所用的 HQL 或者 SQL ...

  2. 笔记:Struts2 文件上传和下载

    为了上传文件必须将表单的method设置为POST,将 enctype 设置为 muiltipart/form-data,只有设置为这种情况下,浏览器才会把用户选择文件的二进制数据发送给服务器. 上传 ...

  3. 【Linux】 环境变量与shell配置&执行

    ■ 变量与环境变量 shell环境通常存在很多变量,变量可以通过echo $VAR或${VAR}的方式查看.set命令可以查看当前环境中的所有变量(包括一般的自定义变量和环境变量) 变量的设置通过简单 ...

  4. Spring MVC核心技术

    目录 异常处理 类型转换器 数据验证 文件上传与下载 拦截器 异常处理 Spring MVC中, 系统的DAO, Service, Controller层出现异常, 均通过throw Exceptio ...

  5. Jmeter中正则表达式提取器使用详解

    在使用Jmeter过程中,会经常使用到正则表达式提取器提取器,虽然并不直接涉及到请求的测试,但是对于数据的传递起着很大的作用,本篇博文就是主要讲解关于正则表达式及其在Jmeter的Sampler中的调 ...

  6. Android 的消息队列模型

    Android 的消息队列模型 Android是参考Windows的消息循环机制来实现Android自身的消息循环的.    Android通过Looper.Handler来实现消息循环机制,Andr ...

  7. zabbix通过SNMP监控服务器硬件及构建触发器

    公司的服务器没装系统无法使用IPMI协议来监控服务器硬件信息,所以我们使用SNMP来获取,下面介绍如何通过SNMP监控服务器硬件信息. 1.HP服务器进入iLO开启SNMP协议. 2.查看服务器温度信 ...

  8. 安装LR11 时,安装Microsoft Visual c++2005 sp1运行时组件,就会提示命令行选项语法错误,键入“命令/?”可获取帮肋信息

    1.进入loadrunner-11\Additional Components\IDE Add-Ins\MS Visual Studio .NET 2.安装:LRVS2005IDEAddInSetup ...

  9. 【django之权限组件】

    一.需求分析 RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,一个角色拥有若干权限.这样,就构造成& ...

  10. g第十四周,十五周作业

    1.数组中偶数的和 #include <stdio.h> int main(){ ; ]; ;i<=;i++) { scanf("%d ",&a[i]); ...