外键约束:何时使用 ON UPDATE 和 ON DELETE
我正在使用 MySQL Workbench 设计我的数据库模式,这非常酷,因为您可以绘制图表并转换它们:P
不管怎样,我决定使用 InnoDB,因为它支持外键。我注意到的一件事是,它允许您设置外键的“更新”和“删除”选项。有人可以在一个简单的例子中解释一下“Restrict”、“Cascade”和 set null 可以在哪里使用吗?
例如,假设我有一个 user
表,其中包含 userID
。假设我有一个消息表message
,它是一个多对多,有 2 个外键(引用相同的主键,userID
) 表)。在这种情况下,设置“更新时”和“删除时”选项有用吗?如果是这样,我该选择哪一个?如果这不是一个很好的例子,您能否想出一个很好的例子来说明这些如何有用?
谢谢
I'm designing my database schema using MySQL Workbench, which is pretty cool because you can do diagrams and it converts them :P
Anyways, I've decided to use InnoDB because of it's Foreign Key support. One thing I noticed though is that it allows you to set On Update and on Delete options for foreign keys. Can someone explain where "Restrict", "Cascade" and set null could be used in a simple example?
For example, say I have a user
table which includes a userID
. And say I have a message table message
which is a many-to-many which has 2 foreign keys (which reference the same primary key, userID
in the user
table). Is setting the On Update and On Delete options any useful in this case? If so, which one do I choose? If this isn't a good example, could you please come up with a good example to illustrate how these could be useful?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
除了 @MarkR 答案之外 - 需要注意的一件事是,许多具有 ORM 的 PHP 框架无法识别或使用高级数据库设置(外键、级联删除、唯一约束),这可能会导致意外的行为。
例如,如果您使用 ORM 删除一条记录,并且您的
DELETE CASCADE
将删除相关表中的记录,则 ORM 尝试删除这些相关记录(通常是自动的)将导致错误。Addition to @MarkR answer - one thing to note would be that many PHP frameworks with ORMs would not recognize or use advanced DB setup (foreign keys, cascading delete, unique constraints), and this may result in unexpected behaviour.
For example if you delete a record using ORM, and your
DELETE CASCADE
will delete records in related tables, ORM's attempt to delete these related records (often automatic) will result in error.您需要在应用程序的上下文中考虑这一点。一般来说,您应该设计一个应用程序,而不是一个数据库(数据库只是应用程序的一部分)。
考虑您的应用程序应如何响应各种情况。
默认操作是限制(即不允许)操作,这通常是您想要的,因为它可以防止愚蠢的编程错误。然而,DELETE CASCADE 也很有用。这实际上取决于您的应用程序以及您打算如何删除特定对象。
就我个人而言,我会使用 InnoDB,因为它不会破坏你的数据(参见 MyISAM,它会破坏数据),而不是因为它有 FK 约束。
You'll need to consider this in context of the application. In general, you should design an application, not a database (the database simply being part of the application).
Consider how your application should respond to various cases.
The default action is to restrict (i.e. not permit) the operation, which is normally what you want as it prevents stupid programming errors. However, on DELETE CASCADE can also be useful. It really depends on your application and how you intend to delete particular objects.
Personally, I'd use InnoDB because it doesn't trash your data (c.f. MyISAM, which does), rather than because it has FK constraints.
请毫不犹豫地对数据库施加约束。您一定会拥有一个一致的数据库,这是使用数据库的好理由之一。特别是如果您有多个应用程序请求它(或者只有一个应用程序,但具有使用不同源的直接模式和批处理模式)。
对于 MySQL,你没有像 postgreSQL 那样的高级约束,但至少外键约束是相当高级的。
我们将举一个例子,一个公司表和一个包含来自这些公司的人员的用户表
让我们看一下 ON UPDATE 子句:
现在在ON DELETE一侧:
通常我的默认设置是:ON DELETE RESTRICT ON UPDATE CASCADE。当主表是“简单属性”时,使用一些
ON DELETE CASCADE
用于跟踪表(日志——不是所有日志——,类似的东西)和ON DELETE SET NULL
' 对于包含外键的表,例如 USER 表的 JOB 表。编辑
自从我写这篇文章以来已经很长时间了。现在我想我应该添加一个重要警告。 MySQL 在级联方面有一个大的记录限制。 级联不会触发触发器。因此,如果您对该引擎有足够的信心来使用触发器,则应该避免级联约束。
==>请参阅下面的最后一次编辑,该域上的事情正在发生变化
我认为这个问题不会有一天得到解决。外键约束由 InnoDb 存储管理,触发器由 MySQL SQL 引擎管理。两者都分开了。 Innodb是唯一具有约束管理的存储,也许有一天他们会直接在存储引擎中添加触发器,也许不会。
但对于应该在糟糕的触发器实现和非常有用的外键约束支持之间选择哪个元素,我有自己的看法。一旦您习惯了数据库一致性,您就会喜欢 PostgreSQL。
12/2017-更新有关 MySQL 的编辑:
正如 @IstiaqueAhmed 在评论中所述,这个主题的情况已经发生了变化。因此,请点击链接并检查真实的最新情况(将来可能会再次发生变化)。
Do not hesitate to put constraints on the database. You'll be sure to have a consistent database, and that's one of the good reasons to use a database. Especially if you have several applications requesting it (or just one application but with a direct mode and a batch mode using different sources).
With MySQL you do not have advanced constraints like you would have in postgreSQL but at least the foreign key constraints are quite advanced.
We'll take an example, a company table with a user table containing people from theses company
Let's look at the ON UPDATE clause:
And now on the ON DELETE side:
usually my default is: ON DELETE RESTRICT ON UPDATE CASCADE. with some
ON DELETE CASCADE
for track tables (logs--not all logs--, things like that) andON DELETE SET NULL
when the master table is a 'simple attribute' for the table containing the foreign key, like a JOB table for the USER table.Edit
It's been a long time since I wrote that. Now I think I should add one important warning. MySQL has one big documented limitation with cascades. Cascades are not firing triggers. So if you were over confident enough in that engine to use triggers you should avoid cascades constraints.
==> See below the last edit, things are moving on this domain
And I do not think this will get fixed one day. Foreign key constraints are managed by the InnoDb storage and Triggers are managed by the MySQL SQL engine. Both are separated. Innodb is the only storage with constraint management, maybe they'll add triggers directly in the storage engine one day, maybe not.
But I have my own opinion on which element you should choose between the poor trigger implementation and the very useful foreign keys constraints support. And once you'll get used to database consistency you'll love PostgreSQL.
12/2017-Updating this Edit about MySQL:
as stated by @IstiaqueAhmed in the comments, the situation has changed on this subject. So follow the link and check the real up-to-date situation (which may change again in the future).