问题起因:
这几天在建表的时候遇到的问题,想试一试插入一下外键,结果折腾了半天,找了不少资料,闹了不少笑话。如果文章写的有问题,请及时指正我的错误,谢谢了。
问题描述:
错误理解:原来我一直以为,两个表只要存在相同的列就可以把他设成外键,这个想法是错误的。
问题解决:
查了不少的资料,外键约束(FOREIGN KEY)用来在两个表的数据之间建立链接,它可以是一列或者多列。一个表可以有一个或多个外键。
外键对应的是参照完整性,一个表的外键可以为空值,若不为空值,则每一个外键的值必须等于另一个表中主键的某个值。
外键是表的一个字段,不是本表的主键,但对应另一个表的主键。定义外键后,不允许删除另一个表中具有关联关系的行。
外键的主要作用是保持数据的一致性、完整性。例如,部门表 tb_dept 的主键是 id,在员工表 tb_emp5 中有一个键 deptId 与这个 id 关联。
- 主表(父表):对于两个具有关联关系的表而言,相关联字段中主键所在的表就是主表。
- 从表(子表):对于两个具有关联关系的表而言,相关联字段中外键所在的表就是从表。
注解:
1.很多地方使用3个表来尝试说明外键,这很容易让人产生外键是3个表之间的关系(我昨天就陷入过这样的一个误区),实际上外键约束(FOREIGN KEY)用来在两个表的数据之间建立链接。
2.每一个外键的值必须等于另一个表中主键的某个值。外键是表的一个字段,不是本表的主键,但对应另一个表的主键。这个问题昨天的也犯了,设想一下,如果“表1”的的一个列既是主键又是外键,而这个外键约束又对应另一个表“表2”的主键,那么是不是“表1”的主键就是“表2”的主键呢?!,那么“表1”和“表2”就可以合并起来了。在我昨天的设计中,我想专门用一个表专门放用户的账号和密码,并且有一个“uid”的列作为主键,另一张表放用户的各种各样的信息,同样也是“uid作为主键”,很明显这两张表可以合并成一张表,而却我想用外键连接他们2333;
选取设置 MySQL 外键约束的字段
定义一个外键时,需要遵守下列规则:
- 父表必须已经存在于数据库中,或者是当前正在创建的表。如果是后一种情况,则父表与子表是同一个表,这样的表称为自参照表,这种结构称为自参照完整性。
- 必须为父表定义主键。
- 主键不能包含空值,但允许在外键中出现空值。也就是说,只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的。
- 在父表的表名后面指定列名或列名的组合。这个列或列的组合必须是父表的主键或候选键。
- 外键中列的数目必须和父表的主键中列的数目相同。
- 外键中列的数据类型必须和父表主键中对应列的数据类型相同。
问题延伸:
在navcat创建外键的时候,这里有个选项,就顺手查了一下他们的含义。
这里提供了几个参数值,他们分别是
1. CASCADE: 从父表中删除或更新对应的行,同时自动的删除或更新自表中匹配的行。ON DELETE CANSCADE和ON UPDATE CANSCADE都被InnoDB所支持。
2. SET NULL: 从父表中删除或更新对应的行,同时将子表中的外键列设为空。注意,这些在外键列没有被设为NOT NULL时才有效。ON DELETE SET NULL和ON UPDATE SET SET NULL都被InnoDB所支持。
3. NO ACTION: InnoDB拒绝删除或者更新父表。
4. RESTRICT: 拒绝删除或者更新父表。指定RESTRICT(或者NO ACTION)和忽略ON DELETE或者ON UPDATE选项的效果是一样的。
5. SET DEFAULT: InnoDB目前不支持。
外键约束使用最多的两种情况无外乎:
1)父表更新时子表也更新,父表删除时如果子表有匹配的项,删除失败;
2)父表更新时子表也更新,父表删除时子表匹配的项也删除。
前一种情况,在外键定义中,我们使用ON UPDATE CASCADE ON DELETE RESTRICT;后一种情况,可以使用ON UPDATE CASCADE ON DELETE CASCADE。
参考文章:这里有外键更详细的描述: http://c.biancheng.net/view/2441.html
这里有外键使用的条件和三个参数的详细使用 https://blog.csdn.net/sky_100/article/details/52781434
希望可以帮到你,兄弟!