MySQL:级联与限制

MySQL: Cascade vs. Restrict

我正在处理一个数据库并使用许多外键来连接我的 table。默认情况下,MySQL 将所有 ON UPDATEON DELETE 设置为 RESTRICT。这似乎工作正常。

然后有一次,我想更改 table 中几行的 id。这个 table 涉及很多关系,所以我将关系更改为 CASCADE 以便将更改级联到使用 id 作为外键的 tables .

现在我想,有什么理由将关系保留为 RESTRICT,因为 CASCADE 似乎让我的生活更轻松?

有时您确实希望在代码中实现所有关系逻辑。你使用 RESTRICT 只是为了控制自己 - 当你忘记某些情况时查看错误。

还要记住 CASCADE 操作有时非常出乎意料,对于庞大的代码库,您应该始终牢记这一点。因此,根本不使用它们可能是一个很好的解决方案 - 有助于组织应用程序的设计,顺便说一句。

另一种方法 - 有时您确实有循环关系(例如反规范化)并且 CASCADE 无法使用。

更改 ID 应该是一件非常罕见的事情。如果这是您的动机,请抵制消除差距或保留您的 ID "tidy," 的诱惑。如果是,那么答案很简单。不,不要。 :) 通常很重要,尤其是在更复杂的系统中,给定域中的 ID 绝不会代表 "thing," 个以上的不同,即使按时间分隔也是如此。请注意,如果您将一行插入自动增量 table,然后回滚插入,即使没有其他竞争操作,id 也不会被重用。

如果 id 是自动递增或任何其他类型的代理键,则很少有正当理由对其进行更改,并且级联更新更有可能仅在响应以下错误时触发您或代码...不是为了有意更改。

级联更新通常只应考虑用于自然键,其中父 table 的主键可能实际上需要更新。

自然键是来自现实世界的 ID,例如车辆的 VIN 或税务机关分配的一块房地产的地块编号,在理论上比在实际操作中更常被视为主键...而代理键在数据库之外具有零意义(因此不应向用户公开),例如自动递增和内部生成的 GUID。

级联删除被合法地用于在正常事件过程中删除父行并且所有子行突然消失也是可取的情况。

不过,一般来说,如果有疑问,RESTRICT 始终是最安全的做法。