【数据库】外键

参考:https://draveness.me/whys-the-design-database-foreign-key/  为什么数据库不应该使用外键

 

在关系型数据库中,外键也被称为关系键,它是关系型数据库中提供关系表之间连接的多个列,这一组数据列是当前关系表中的外键,也必须是另一个关系表中的候选键(Candidate Key),我们可以通过候选键在当前表中找到唯一的元素。、

在通常情况下,我们都会使用关系表中的主键作为其他表中的外键,这样才可以满足关系型数据库对外键的约束。

ALTER TABLE posts
ADD CONSTRAINT FOREIGN KEY (author_id)
REFERENCES authors(id);

 

外键的类型,最常见的也就是 RESTRICT 和 CASCADE 两种,其中 RESTRICT 为外键的默认类型,不同类型的外键会带来不同的额外开销,而这些额外开销就是我们不使用外键的理由:

  • 使用 RESTRICT 会在更新或者删除记录时对外键对应的记录是否存在进行一致性检查;
  • 使用 CASCADE 会在更新或者删除记录时触发级联更新或者删除操作;

一致性检查

在执行如下所示的操作时都会触发数据库对外键的检查: 通过额外开销,保证数据库数据完整性

  • 向 posts 表中插入数据时,检查 author_id 是否在 authors 表中存在;
  • 修改 posts 表中的数据时,检查 author_id 是否在 authors 表中存在;
  • 删除 authors 表中的数据时,检查 posts 中是否存在引用当前记录的外键;

模拟外键一致性检查效果:

  • 向表中插入数据或者修改表中的数据时,都应该执行额外的 SELECT 语句确保它引用的数据在数据库中存在;
  • 在删除数据之前需要执行额外的 SELECT 语句检查是否存在当前记录的引用;

级联操作

配置级联类型外键

ALTER TABLE posts
ADD CONSTRAINT FOREIGN KEY (author_id)
REFERENCES authors(id)
ON UPDATE CASCADE
ON DELETE CASCADE;
  • 当客户端更新 authors 表中记录的主键时,数据库会同时更新 posts 表中所有引用该记录的外键;
  • 当客户端删除 authors 表中的记录时,数据库会删除所有与 authors 表关联的记录;

复杂的级联操作:

当客户端想要在数据库中删除 authos 表中的数据时,如果我们同时在 authors 和 posts 中指定了级联删除的行为,那么数据库会同时删除所有关联的 posts 记录以及与 posts 表关联的 comments 数据。

数据量大时可能造成系统问题;建议手工SQL完成业务关联表的删除

 

不使用外键的理由

MySQL、PostgreSQL 等关系型数据库很难水平扩容,但是无状态的服务往往都可以很容易地扩容。

由于外键等特性需要数据库执行额外的工作,而这些操作会占用数据库的计算资源,所以我们可以将大部分的需求都迁移到无状态的服务中完成以降低数据库的工作负载。

 

posted @ 2022-03-03 21:33  飞翔在天  阅读(767)  评论(0编辑  收藏  举报