MySQL

MySQL 知识量:16 - 40 - 165

6.2 联结表><

关系表- 6.2.1 -

MySQL是关系型数据库管理系统,关系表是重要的概念。

在子查询的示例中,介绍了一个学生表(student)和课程表(course),它们之间通过student.id和course.id_student进行了关联,也就是有了“关系”。其中,student.id是学生表的主键,course.id_student是课程表的外键,这两个键关联后,学生表和课程表就成为了关系表。

关系表的设计就是要保证把信息分解成多个表,一类数据一个表,这样可以排除重复数据,也便于数据修改,增加了表的灵活性。这种设计可以很好的适应不断增加的数据量,具有很好的可伸缩性。

联结的目的- 6.2.2 -

因为关系表的设计将信息分解到了多个表中,因此,要一次查询出包含在多个表中的数据就需要使用联结。

联结就像是把分散的表组合到了一起而进行的查询,这种组合是通过主键与外键的关联关系完成的,联结的表不是物理上真的连接到了一起,只是逻辑上连接在了一起。

创建联结- 6.2.3 -

要创建联结只需要同时列出联结的表名和它们之间的关联关系即可。

例子:假设有一个学生表(student)、一个课程表(course)和一个课程目录表(lesson),学生表通过student.id与课程表course.id_student关联,课程目录表通过lesson.id与课程表course.id_lesson关联。

学生表:(student)

+----+-------+-----+--------+
| id | name  | age | sex    |
+----+-------+-----+--------+
|  1 | Susan |  11 | female |
|  2 | Jame  |  12 | male   |
|  3 | Bob   |  11 | male   |
|  4 | Robot |  10 | male   |
|  5 | Jen   |  11 | female |
|  6 | Toney |  10 | male   |
+----+-------+-----+--------+

课程表(course):

+----+------------+-----------+
| id | id_student | id_lesson |
+----+------------+-----------+
|  1 |          1 |         1 |
|  2 |          5 |         3 |
|  3 |          2 |         1 |
|  4 |          4 |         1 |
|  5 |          6 |         1 |
|  6 |          1 |         2 |
|  7 |          3 |         2 |
|  8 |          4 |         2 |
|  9 |          5 |         2 |
| 10 |          2 |         3 |
| 11 |          4 |         3 |
| 12 |          6 |         3 |
+----+------------+-----------+

课程目录表(lesson):

+----+---------+
| id | name    |
+----+---------+
|  1 | Maths   |
|  2 | English |
|  3 | Natural |
+----+---------+

如果要查询所有学生的姓名和选择的课程名称,并按学生姓名排列,SQL语句如下:

select s.name,l.name
from student as s,course as c,lesson as l
where s.id=c.id_student and l.id=c.id_lesson
order by s.name;

返回结果:

+-------+---------+
| name  | name    |
+-------+---------+
| Bob   | English |
| Jame  | Maths   |
| Jame  | Natural |
| Jen   | Natural |
| Jen   | English |
| Robot | Maths   |
| Robot | English |
| Robot | Natural |
| Susan | Maths   |
| Susan | English |
| Toney | Maths   |
| Toney | Natural |
+-------+---------+

重要的where子句- 6.2.4 -

联结的具体细节是:将第一个表的每一行与第二个表的每一行进行配对,如果满足where子句规定的条件就保留,否则舍弃。因此,如果没有设置where子句,那么每一次配对都将保留,结果会是一个笛卡尔积,查询出的行数将是所有表行数的积。

因为以上原因,where子句在联结中是非常重要的,应该保证所有的联结都有where子句。

理论上可以联结无数个表,但是因为性能原因,表还是能少就少。如果联结n个表,那么where子句至少应该有n-1个联结条件(联结条件之间用and连接)。

内部联结- 6.2.5 -

基于两个表之间的相等测试的联结称为等值联结,创建联结中的例子就是等值联结。这种联结也称为内部联结,它还可以用另一种语法来写。

创建联结中的例子可以改写为:

select s.name,l.name
from student as s
inner join course as c
on s.id=c.id_student
inner join lesson as l
on l.id=c.id_lesson
order by s.name;

返回的结果是一样的,但这种内部联结的写法能够更明确的表明表联结的方式。联结的表之间通过inner join来表明联结关系,紧跟在表名后面的on则规定了联结的条件。where子句此时已经没有用了,因此舍去。