MySQL中的关联查询

MySQL中的关联查询

(1)Question:关联是什么

关联是SQL语言中使用SELECT操作表的一种操作机制,用来联系两个或者多个表。SELECT是SQL中的查询语句,用于查询数据库中的数据。将SELECT与关联结合,就产生了关联查询。

(2)Question :为什么要使用关联

假设一个班级有30名学生,每个学生都有自己的姓名、学号、班级、班主任等这些属性,可以发现,姓名学号是每个学生独有的,而班级、班主任、班主任电话等等信息是学生们共有的。现在如果要将这个班级的信息存储在数据库中,那么有两种存储方式。

① 建一张表,将数据都存在这一张表中,如下。

班级 班主任 班主任电话 学生姓名 学号
六年一班 阿福 13131313131 小夫 1
六年一班 阿福 13131313131 大熊 2
六年一班 阿福 13131313131 静香 3

② 建多张表,将数据归类后存放,如下。

(1)

班级 班主任 班主任电话
六年一班 阿福 13131313131

(2)

学生姓名 学号 班级
小夫 1 六年一班
大熊 2 六年一班
静香 3 六年一班

为了方便说明,就不写30个学生信息了。可以发现,将数据都存放在一张表中,可以提高读表的可读性,但是开发者就会很麻烦,因为表中的前三列信息是一模一样的。如果有30条数据时,开发者就必须重复的填入相同的信息,麻烦又会出错。反观方法②,就对开发者十分友好,只有1列在重复。并且方法②的优势还在于,假设老师换手机号码了,只需要修改表(1)中的手机号,而不用像方法①中一个一个去修改。方法②如此便利,那么我们对这样的表进行查询呢?

(3)Question:如何使用关联查询?

现在我们在实际的数据库中设计两个表,为了SQL操作方便,我们将列的键都设置成英文字母。

(1)班级信息建表代码

CREATE TABLE `classinfo` (
  `class` varchar(255) DEFAULT NULL,
  `teacher` varchar(255) DEFAULT NULL,
  `mobile` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
class teacher mobile
六年一班 阿福 13131313131

(2)学生信息建表代码

CREATE TABLE `stuinfo` (
  `name` varchar(255) DEFAULT NULL,
  `id` varchar(255) DEFAULT NULL,
  `class` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
name id class
小夫 1 六年一班
大熊 2 六年一班
静香 3 六年一班

现在我们需要查看id为1的学生信息

SELECT classinfo.class, teacher, mobile, name, id 
FROM classinfo, stuinfo 
WHERE classinfo.class = stuinfo.class AND id = 1
ORDER BY id

执行结果如下

class teacher mobile name id
六年一班 阿福 13131313131 小夫 1

在这里插入图片描述

(4)Question:关联查询的实现过程是什么?

产生上面这样的结果,实际上在数据库运行中分为这三步:

(1)建立笛卡尔积

FROM classinfo, stuinfo 

该语句指定了classinfo, stuinfo 这两个表关联,系统会根据这两个表生成一个笛卡尔积。按照这个笛卡尔积生成的表我认为是这样的:

class teacher mobile name id
六年一班 阿福 13131313131 小夫 1
六年一班 阿福 13131313131 大熊 2
六年一班 阿福 13131313131 静香 3

为了更直观的表示笛卡尔积

classinfo现在改成

class teacher mobile
六年一班 阿福 13131313131
六年二班 特鲁 12121212121

此时再对classinfo与stuinfo求笛卡尔积,结果如下。

class teacher mobile name id
六年一班 阿福 13131313131 小夫 1
六年一班 阿福 13131313131 大熊 2
六年一班 阿福 13131313131 静香 3
六年二班 特鲁 12121212121 小夫 1
六年二班 特鲁 12121212121 大熊 2
六年二班 特鲁 12121212121 静香 3

可以看到,做笛卡尔其实是关联两表按行相乘,同名列保留一个。

(2)过滤

WHERE classinfo.class = stuinfo.class AND id = 1

通过这条过滤语句,系统挑出classinfo.class与stuinfo.class中键值相同的并且id列中键值为1的行,过滤完毕系统生成一个对用户不可见的中间表。

class teacher mobile name id
六年一班 阿福 13131313131 小夫 1

(3)挑选,并返回给用户

SELECT classinfo.class, teacher, mobile, name

此时,SELECT选择如上,返回的表如下。

class teacher mobile name
六年一班 阿福 13131313131 小夫

此时,就可以得到学号为1的学生所有信息。

(5)Question:假如我有多个表呢?

假设现在有第三个表,储存着班主任的年纪,性别的信息,我们期望得到的结果如下:

class teacher mobile age gender name id
六年一班 阿福 13131313131 31 小夫 1

那么我们如何使用SELECT去得到这样的结果呢?

在这里,要明白多表关联的工作机制。与两个表一样,多表查询实际上是将待查询表按顺序两两组合,将两表生成的笛卡尔积与第三个表再生成笛卡尔积,最后按照过滤、选择操作将结果返回用户。

建第三个表语句如下。

CREATE TABLE `tea` (
  `teacher` varchar(255) DEFAULT NULL,
  `age` varchar(255) DEFAULT NULL,
  `gender` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
teacher age gender
阿福 31
特鲁 35
白雪 25

同上,将会产生一个3X2X3的笛卡尔表,后再进行过滤,选择,返回用户。

操作语句如下。

SELECT classinfo.class, tea.teacher, mobile, age, gender, name, id 
FROM classinfo, stuinfo, tea
WHERE classinfo.class = stuinfo.class
AND classinfo.teacher = tea.teacher
AND id = 1
ORDER BY id

最终结果展示如下。

在这里插入图片描述

(6)总结

关联查询与建表的方式有关,使用数据分类的方式建表,就像打一本书,首先展示的是目录,一个目录下又包括多个章节,一个章节里又包含着许多知识点。这样将数据层层包装而不是做一个巨大的表的思想,是我们需要学习的。关联查询不仅仅包含本文中提到的查询,其中还有左外连接(左连接)查询,右外联结(右连接)查询,内联结查询等查询方式,应用于实际中不同的场景。

63094048813)]

(6)总结

关联查询与建表的方式有关,使用数据分类的方式建表,就像打一本书,首先展示的是目录,一个目录下又包括多个章节,一个章节里又包含着许多知识点。这样将数据层层包装而不是做一个巨大的表的思想,是我们需要学习的。关联查询不仅仅包含本文中提到的查询,其中还有左外连接(左连接)查询,右外联结(右连接)查询,内联结查询等查询方式,应用于实际中不同的场景。

你可能感兴趣的:(数据库学习,MySQL关联查询)