关系表

什么是关系表,假设有一个学生表,其中包含了学生姓名,出生年月,主键id, 班级id(外键)。

同时还有另外一个表,是一个班级表,其中包含主键id,班级名称。
这样的两个表就形成了关系表,学生表可以通过外键(班级id)查询到该学员的班级名称。这样的关系表也可称为一对多关系表。

外键

外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系。

这样做的好处:

  • 班级信息不重复,从而不浪费查询的时间和空间。
  • 如果班级信息有变动,直接更新班级表即可,学生表的数据不用改动
  • 因为数据无重复,处理起来也会更加方便

为什么要使用联结

分解数据为多个表能更有效的存储,更方便的处理,并且具有更大的可伸缩性。
但是由于数据存储在多个表中,又不想使用多重子查询这种不易阅读的写法,那可以用联结。

简单来说:
联结的概念相当于是变量的赋值

创建联结

SELECT first_name, last_name FROM employees, dept_manager WHERE employees.emp_no = dept_manager.emp_no;

输出:

+-------------+--------------+
| first_name  | last_name    |
+-------------+--------------+
| Margareta   | Markovitch   |
| Vishwani    | Minakawa     |
| Ebru        | Alpin        |
| Isamu       | Legleitner   |
| Shirish     | Ossenbruggen |
| Karsten     | Sigstam      |
| Krassimir   | Wegerle      |
| Rosine      | Cools        |
| Shem        | Kieras       |
| Oscar       | Ghazalie     |
| DeForest    | Hagimont     |
| Leon        | DasSarma     |
| Peternela   | Onuegbe      |
| Rutger      | Hofmeyr      |
| Sanjoy      | Quadeer      |
| Dung        | Pesch        |
| Przemyslawa | Kaelbling    |
| Hauke       | Zhang        |
| Arie        | Staelin      |
| Hilary      | Kambil       |
| Tonny       | Butterworth  |
| Marjo       | Giarratana   |
| Xiaobin     | Spinelli     |
| Yuchang     | Weedman      |
+-------------+--------------+
24 rows in set (0.00 sec)

分析:
上面这个语句指的是从employees,dept_manager两张表中找出所有管理层的全名。
语句的关键点是从FROM语句,因为涉及到了2张表,两张表中都有emp_no字段的情况,所以为了能让MySQL区分emp_no是属于那张表,在后面的WHERE语句中添加过滤employees.emp_no = dept_manager.emp_no

WHERE子句的重要性

首先WHERE子句本身的作用就是过滤数据,由于两个表的匹配逻辑是从第一个表的第一行去匹配第二个表的每一行,如果没有WHERE语句对两个表联结后的过滤,最终会形成笛卡尔积。在这个例子中,第二个表有24行所以最终会有24*第一个表的行数的数据。

内部联结

与上面相同效果的不同写法:

SELECT first_name, last_name FROM employees INNER JOIN dept_manager ON employees.emp_no = dept_manager.emp_no;

联结多个表

查询管理层的全名以及所在部门的名称

SELECT first_name, last_name, dept_name FROM employees, dept_manager, departments  WHERE employees.emp_no = dept_manager.emp_no AND dept_manager.dept_no = departments.dept_no;

输出:

+-------------+--------------+--------------------+
| first_name  | last_name    | dept_name          |
+-------------+--------------+--------------------+
| Tonny       | Butterworth  | Customer Service   |
| Marjo       | Giarratana   | Customer Service   |
| Xiaobin     | Spinelli     | Customer Service   |
| Yuchang     | Weedman      | Customer Service   |
| DeForest    | Hagimont     | Development        |
| Leon        | DasSarma     | Development        |
| Ebru        | Alpin        | Finance            |
| Isamu       | Legleitner   | Finance            |
| Shirish     | Ossenbruggen | Human Resources    |
| Karsten     | Sigstam      | Human Resources    |
| Margareta   | Markovitch   | Marketing          |
| Vishwani    | Minakawa     | Marketing          |
| Krassimir   | Wegerle      | Production         |
| Rosine      | Cools        | Production         |
| Shem        | Kieras       | Production         |
| Oscar       | Ghazalie     | Production         |
| Peternela   | Onuegbe      | Quality Management |
| Rutger      | Hofmeyr      | Quality Management |
| Sanjoy      | Quadeer      | Quality Management |
| Dung        | Pesch        | Quality Management |
| Arie        | Staelin      | Research           |
| Hilary      | Kambil       | Research           |
| Przemyslawa | Kaelbling    | Sales              |
| Hauke       | Zhang        | Sales              |
+-------------+--------------+--------------------+
24 rows in set (0.00 sec)