MySQL 中的外键是指一个表中的一列(或一组列),该列引用另一个表中的主键。包含外键的表称为子表,而包含所引用的主键的表称为父表.
父子表
让我们用一个简单的例子来说明父表和子表的概念。请考虑以下两个表格,其中包含有关学生及其各自老师的一些信息:
pupil
表:
ID |
名字 |
---|---|
1 |
axel |
2 |
bobby |
3 |
cathy |
请参阅此处生成 pupil
表的代码。
teacher
表:
teacher_id |
teacher_name |
pupil_id |
部门 |
---|---|---|---|
1 |
emily |
1 |
physics |
2 |
fiona |
2 |
physics |
3 |
gilbert |
3 |
chemistry |
请参阅此处生成 teacher
表的代码。
-
检查每个表的代码,您将看到
teacher
表的pupil_id
字段引用pupil
表的id
字段。 -
因此在这个例子中
pupil
表是家长表和teacher
表是孩子表格。
外键的重要性
每当一个表引用另一个表时,使用外键几乎总是一个好主意。让我们用一个简单的例子来理解为什么。
让我们再次使用相同的表:
pupil
(父表)
ID |
名字 |
---|---|
1 |
axel |
2 |
bobby |
3 |
cathy |
teacher
(子表)
teacher_id |
teacher_name |
pupil_id |
部门 |
---|---|---|---|
1 |
emily |
1 |
physics |
2 |
fiona |
2 |
physics |
3 |
gilbert |
3 |
chemistry |
假设我们添加一位新老师来监督一名新学生pupil_id=4
:
teacher
(子表)
teacher_id |
teacher_name |
pupil_id |
部门 |
---|---|---|---|
1 |
emily |
1 |
physics |
2 |
fiona |
2 |
physics |
3 |
gilbert |
3 |
chemistry |
4 |
helen |
4 |
physics |
您能看到我们目前的数据不一致吗?我们有一位老师所监管的学生不存在于我们的 pupil
表中(即 pupil
表中没有 id=4
的学生)。
注意
外键是防止我们的数据出现这些不一致的约束。换句话说,有了外键,我们将无法添加Helen
记录,因为MySQL知道pupil_id=4
在pupil
的id
字段中没有相应的匹配项。表格。
为了证明这一点,让我们尝试将老师 Helen
插入到我们的 teacher
表中,他将用 pupil_id = 4
来监督新学生:
INSERT INTO teacher(teacher_name, pupil_id)
VALUES ('helen', 4);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails.
太好了,外键对于防止数据库中的不一致很有用!
从父表中删除
可能发生不一致的另一种情况是删除父表中的记录。例如,假设我们尝试从 pupil
表中删除 id=2
的学生:
DELETE FROM pupil
WHERE id = 2;
这将导致错误,因为子表包含带有 pupil_id=2
的记录,如果删除 bobby
(即 id=2
),则父表中将不再有匹配的记录。
瞳孔(父表)
ID |
名字 |
---|---|
1 |
axel |
2 |
bobby |
3 |
cathy |
老师 (子表)
teacher_id |
teacher_name |
pupil_id |
部门 |
---|---|---|---|
1 |
emily |
1 |
physics |
2 |
fiona |
2 |
physics |
3 |
gilbert |
3 |
chemistry |
此外,当我们也更新父表时,可能会出现同样的不一致:
UPDATE pupil
SET id = 3
WHERE id = 2;
当我们使用外键时,所有这些不一致的情况都可以避免。因此,建议使用它!
默认情况下,外键没有任何限制,它可以采用 NULL
以及重复值。
相关用法
- MySQL FROM_BASE64()用法及代码示例
- MySQL FROM_UNIXTIME方法用法及代码示例
- MySQL FIELD方法用法及代码示例
- MySQL FROM_BASE64方法用法及代码示例
- MySQL FROM_UNIXTIME()用法及代码示例
- MySQL FORMAT()用法及代码示例
- MySQL FORMAT方法用法及代码示例
- MySQL FROM_DAYS()用法及代码示例
- MySQL FLOOR()用法及代码示例
- MySQL FROM_DAYS方法用法及代码示例
- MySQL FIND_IN_SET()用法及代码示例
- MySQL FLOOR方法用法及代码示例
- MySQL FIELD()用法及代码示例
- MySQL FIND_IN_SET方法用法及代码示例
- MySQL FLOAT and DOUBLE用法及代码示例
- MySQL FLOOR() AND CEIL()用法及代码示例
- MySQL From_days()用法及代码示例
- MySQL ROUND()用法及代码示例
- MySQL REPEAT()用法及代码示例
- MySQL POWER()用法及代码示例
- MySQL LEAD() and LAG()用法及代码示例
- MySQL IS_IPV4()用法及代码示例
- MySQL RADIANS方法用法及代码示例
- MySQL VARIANCE方法用法及代码示例
- MySQL WEEK()用法及代码示例
注:本文由纯净天空筛选整理自Arthur Yanagisawa大神的英文原创作品 MySQL | Foreign keys。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。