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。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。
