简介
在上一篇文章MySQL操作汇总(单表创建查询)中,我们介绍了在MySQL中如何创建单张表,并进行相关的查询、更新、删除等操作。但实际上一个数据库中往往包含多张表,因此往往需要对多张表进行联结(join)查询。联结是利用SQL的SELECT能执行的最重要的操作,很好地理解联结及其语法是学习SQL的一个极为重要的组成部分。
多张表
在上一篇文章MySQL操作汇总(单表创建查询)中,我们引入了一张名为products的表,记录了产品信息。如下:
products表
产品一般都包含对应的供应商。如果每个产品只有一个供应商,每个供应商又只提供一种商品(即一对一的关系)。我们可以单独添加一些供应商的信息(名称、地址、电话号码)到prodcuts表中。
假设每个产品只有一个供应商,但是一个供应商可以提供0个或者多个商品(即一对多关系)。那么此时把供应商的信息添加到products表中,就会导致数据重复。这是因为一个供应商可能提供多件商品,因此,同一个供应商的信息可能会出现在products表中的多行。这不仅会导致空间的浪费,还很容易导致不一致。如果一个产品包含多个供应商,并且每个供应商同时提供多种商品,那么情况还会变得更加复杂,即多对多的关系。
一对多关系
假设每个产品只有一个供应商,并且每个供应商提供一种或多种商品。那么我们可以创建一张名为suppliers的表来存储供应商的信息(比如,名称、地址、电话等)。我们创建名为supplierID的一列来区别每一个供应商,这一列的数据是唯一的。另外,我们设置supplierID作为表suppliers的主键来保证唯一性和加快查询速度。
为了将表suppliers与表products关联起来,我们在products表中添加一个新列,名为supplierID。然后设置表products的supplierID列为外键,它引用了表suppliers中的主键列supplierID,由此来定义两个表之间的关系。
表suppliers
表products 我们首先需要创建suppliers表,因为表products需要引用表suppliers。使用以下命令来创建:
mysql> USE southwind;
Database changed
mysql> DROP TABLE IF EXISTS suppliers;
Query OK, 0 rows affected, 1 warning (0.04 sec)
mysql> CREATE TABLE suppliers (
-> supplierID INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> name VARCHAR(30) NOT NULL DEFAULT '',
-> phone CHAR(8) NOT NULL DEFAULT '',
-> PRIMARY KEY (supplierID)
-> );
Query OK, 0 rows affected (0.10 sec)
mysql> DESC suppliers;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| supplierID | int unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(30) | NO | | | |
| phone | char(8) | NO | | | |
+------------+--------------+------+-----+---------+----------------+
3 rows in set (0.02 sec)
mysql> INSERT INTO suppliers VALUE
-> (501, 'ABC Traders', '88881111'),
-> (502, 'XYZ Company', '88882222'),
-> (503, 'QQ Corp', '88883333');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM suppliers;
+------------+-------------+----------+
| supplierID | name | phone |
+------------+-------------+----------+
| 501 | ABC Traders | 88881111 |
| 502 | XYZ Company | 88882222 |
| 503 | QQ Corp | 88883333 |
+------------+-------------+----------+
3 rows in set (0.00 sec)
然后我们使用ALE