外键的一些注意事项

  • 2019 年 11 月 6 日
  • 筆記

外键的一些注意事项

昨天的文章中,重温了一下外键的使用方式,今天再聊聊外键的一些其他注意事项。

首先需要了解的是,InnoDB是目前唯一支持外键的内置存储引擎。使用外键是有一定成本的。这里讨论一下外键的优劣势:

优势:

使用外键在某些场景下能够提升一些性能,比如我们想确保两个相关表始终具有一致的数据,那么使用外键的方法要比直接查询两张表数据是否一致性能高得多,除了这个之外,外键在相关数据的删除和更新上,也比在应用程序中维护更加高效。不过这里需要注意的是,外键的维护操作是逐行记录进行的,所以这种更新会比批量删除和更新的速度慢一些。

劣势:

外键通常都要求每次在修改数据时在另外一张表中执行一次查找操作,虽然在innodb中强制外键使用索引,但是还是会带来额外开销,在一些基数比较小的索引上创建外键,还有可能严重影响性能。除此之外,外键约束使得查询需要额外访问一些别的表,以为着会需要额外的锁开销,例如,我们在子表中插入一条记录,外键约束会让innodb检查父表对应的记录,也就需要对父表加锁从而确保这条记录不会在该事务完成之前被删除掉。这个操作会导致额外的所等待,还有可能出现死锁的现象。

基于这种劣势,所以我们在包含外键的表中,如果需要导入数据,则会通过暂时关闭外键的方法来保证导入数据的时候,不进行外键检查,从而提高插入的性能,如下:

第一步、set foreign_key_checks = 0;

第二步、load data …

第三步、set foreign_key_checks = 1;

在实际的生产环境中,一般还是建议让数据库去做它最擅长的事儿,就是单纯的数据存储和数据查询。外键约束、存储过程、触发器、函数这些包含处理逻辑的功能,还是尽量不要使用,一旦表里面的记录量级上来了,那么这些功能很容易成为关系型数据库的瓶颈。