您的位置:首页 > 数据库

【数据库基础】Foreign Key的使用及其优缺点

2018-03-27 20:08 218 查看
Foreign Key(外键)是数据库的一个很重要的概念。当两张表存在关联字段的时候,利用外键可以保证主表和从表的一致性和完整性。但是由于外键是Constraint,肯定会对表的新增删除修改产生性能的影响,所以到底使不使用,什么时候使用,该怎么用需要慎重考虑。

使用外键的优缺点

如何建立外键

假设我们有张主表user表,表结构如下



我们希望以id这个字段作为别的表的外键关联一张子表balance。 balance表记录着user的账户余额以及币种。表结构如下



这里的uid就是user表的id字段。

我们可以通过

create table balance(
...
foreign key(uid) references user(id)
) ...


或者如果balance表已经建好了,通过alter语句来添加外键。

alter table balance add foreign key(uid) references user(id);


值得注意的是:

1. 外键字段在创建的时候就应该与主表的类型完全一致(长度啊等),否则创建外键会报错

2. 外键创建中关键字的references不是reference, 有一个字母s。

3. 主表子表必须都是InnoDB的表!

我们来看一下balance表是否创建好了外键

show create table balance;




看到
CONSTRAINT `balance_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `user` (`id`)
看来是创建好了。

等一下,注意到了没? 由于创建了外键,mysql自动的为uid字段设置了索引。。 这点也需要了解一下。。

接下来我们来看外键的作用。。。

如何利用外键约束

我们试着往balance表中添加几条数据



uid=1和2的情况对应了user表中’yf’和’huangxiang’ 所以数据插入是没问题的。

接下来我们插入主表不存在的uid试试



结果发现是不行的,外键阻止我们这种错误的操作。都没这个user你怎么往它的账户上打钱?

如果我们删除子表中已经关联上的主表数据呢

比如我们试着删除’yf’这个user。



哈哈,不行吧? 除非你把子表关联的数据全部删除,你才能删除该条主表的数据。

同样,update操作也会因为外键限制操作失败,这里就不展示了。

外键进阶

参考

https://my.oschina.net/sallency/blog/465079

我们刚才讨论的情况,都是建立在

删除:从表记录不存在时,主表才可以删除。删除从表,主表不变

更新:从表记录不存在时,主表才可以更新。更新从表,主表不变

然而我们可以自定义外键的规则,比如我们删除了主表的某条数据,子表相应的数据都会被删除等

NULL、RESTRICT、NO ACTION

删除:从表记录不存在时,主表才可以删除。

更新:从表记录不存在时,主表才可以更新。

CASCADE

删除:删除主表时自动删除从表。

更新:更新主表时自动更新从表。

SET NULL

删除:删除主表时自动更新从表值为NULL。

更新:更新主表时自动更新从表值为NULL。

如果子表试图创建一个在父表中不存在的外键值,InnoDB会拒绝任何INSERT或UPDATE操作。如果父表试图UPDATE或者DELETE任何子 表中存在或匹配的外键值,最终动作取决于外键约束定义中的
ON UPDATE
ON DELETE
选项。InnoDB支持5种不同的动作,如果没有指定
ON DELETE
或者
ON UPDATE
,默认的动作为RESTRICT也就是我们上面的例子

cascade关键字

为了测试cascade作用,我们再创建一个tongbu_balance表.



然后复制balance表已有的数据到tongbu_balance表

insert into tongbu_balance select * from balance;


然后我们试着删除主表中的’huangxiang’ …

删除前两表的状态如下



↓↓↓↓↓↓↓↓↓↓删除后↓↓↓↓↓↓↓↓↓↓



子表中’huangxiang’对应的uid=2的数据全部也跟着删除了…

同样当我们UPDATE主表的时候,子表也会跟着UPDATE.. 这里就不做演示了。。

当我们想自定义规则的时候,注意用
ON UPDATE/DELETE 规则
这样的语法限定外键就好了。。。

组合使用

外键约束使用最多的两种情况无外乎:

1)父表更新时子表也更新,父表删除时如果子表有匹配的项,删除失败;

2)父表更新时子表也更新,父表删除时子表匹配的项也删除。

前一种情况,在外键定义中,我们使用
ON UPDATE CASCADE ON DELETE RESTRICT;
后一种情况,可以使用
ON UPDATE CASCADE ON DELETE CASCADE;


但无论什么约束情况,主表不存在的主键子表也是不能插入相应的外键的,这是所有外键约束的基本原则。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: