为什么不推荐使用外键与级联?

  • 不是不能用外键,而是在高并发、分布式、读写分离架构下,数据库层面的强约束会成为系统扩展性的“隐形枷锁”。很多互联网公司选择在应用层维护关系,而不是依赖数据库外键和级联。

  • 外键(Foreign Key)本质是数据库级别的引用完整性约束。比如:

    • child 表的 user_id 必须存在于 parent 表
    • 删除 parent 时,child 要么禁止删除,要么级联删除
    • 数据库会在每次 INSERT / UPDATE / DELETE 时做一致性检查。

为什么不推荐使用外键与级联?

  1. 影响性能

外键会让数据库在修改数据时做额外检查。高并发写场景下:

  • 每次写都要查父表
  • 可能加锁
  • 级联删除会触发大量额外操作

当数据量上亿时,这不是“小开销”。

  1. 降低扩展性(分库分表 nightmare)

一旦做分库分表,问题就来了。假设 user 表和 order 表被拆到不同数据库实例。数据库层面已经无法做跨库外键。

于是:

  • 要么放弃外键
  • 要么永远不能拆库

而大规模系统最终几乎都会拆库。

外键 = 强耦合 = 垂直扩展障碍。

  1. 级联删除风险极高

假设:

  • 删除一个 user
  • 触发删除 10 万条 order
  • 再触发删除 order_item
  • 再触发日志表删除

结果可能是:

  • 误删灾难
  • 长事务
  • 大面积锁表
  1. 业务逻辑不应该埋在数据库

现代架构更推崇:

  • 数据库负责存储
  • 业务逻辑在应用层

级联删除本质是业务规则。

而规则往往会变化:

今天允许级联
明天改成逻辑删除
后天改成归档

数据库约束一旦上线,修改成本很高。

结论

  • 使用外键和级联的问题:
    • 影响性能
    • 影响扩展性(分库分表)
    • 级联删除风险极高
    • 业务逻辑不应该埋在数据库