Joh*_*ron 135 mysql foreign-key
我不是每天都设计模式,但是当我这样做时,我会尝试正确设置级联更新/删除以使管理更容易。我了解级联的工作原理,但我永远记不起哪个表是哪个。
例如,如果我有两个表 -Parent并且Child- 在Child该引用上有一个外键Parent并且 has ON DELETE CASCADE,哪些记录触发级联,哪些记录被级联删除?我的第一个猜测是Child记录被删除时Parent记录被删除,因为Child记录依赖于Parent记录,但这ON DELETE是不明确的;这可能意味着在删除Parent记录时删除记录Child,也可能意味着在删除Child记录时删除记录Parent。那么它是哪个?
我希望语法是ON PARENT DELETE, CASCADE,ON FOREIGN DELETE, CASCADE或者类似的东西来消除歧义。有没有人有记住这一点的助记符?
ype*_*eᵀᴹ 188
如果您喜欢Parent和Child术语,并且觉得它们很容易记住,您可能会喜欢ON DELETE CASCADEto的翻译Leave No Orphans!
这意味着当Parent一行被删除(终止)时,Child表中不应存在孤立行。父行的所有孩子也被杀死(删除)。如果这些孩子中的任何一个有孙子(通过另一个外键在另一个表中)并且有ON DELETE CASCADE定义,那么它们也应该被杀死(以及所有后代,只要定义了级联效应。)
该FOREIGN KEY约束本身也可以被描述为Allow No Orphans!(首先)。不Child应该永远被允许(写入)子表,如果它不是一个Parent(父表中的行)。
为了一致性,ON DELETE RESTRICT可以将 转换为(不那么激进)You Can't Kill Parents!只能杀死(删除)无子行的行。
Mik*_*ll' 40
例如,如果我有两个表 - Parent 和 Child - 其中 Child 记录归 Parent 记录所有,哪个表需要 ON DELETE CASCADE?
ON DELETE CASCADE 是外键声明中的可选子句。所以它与外键声明一致。(意思是,在“子”表中。)
...这可能意味着在删除子记录时删除父记录,或者在删除父记录时删除子记录。那么它是哪个?
解释外键声明的一种方法是,“此列的所有有效值都来自 'that_table' 中的 'that_column'。” 当您删除“子”表中的一行时,没有人关心。它不会影响数据完整性。
当您从“父”表(从“that_table”)中删除一行时,您将从“子”表的可能值中删除一个有效值。为了保持数据完整性,您必须对“子”表做一些事情。级联删除是您可以做的一件事。
章节和诗句,来自PostgreSQL 文档。
限制和级联删除是两个最常见的选项。RESTRICT 防止删除引用的行。NO ACTION 意味着如果检查约束时仍然存在任何引用行,则会引发错误;如果您未指定任何内容,则这是默认行为。(这两个选择之间的本质区别是 NO ACTION 允许将检查推迟到事务的后期,而 RESTRICT 不允许。) CASCADE 指定当删除引用的行时,应自动删除引用它的行以及。还有另外两个选项:SET NULL 和 SET DEFAULT。当删除引用的行时,这些会导致引用行中的引用列分别设置为空值或它们的默认值。请注意,这些并不能免除您遵守任何约束条件。例如,如果操作指定了 SET DEFAULT 但默认值不满足外键约束,则操作将失败。
Eva*_*oll 12
有五个选项ON DELETE,并ON UPDATE可以应用到FOREIGN KEY。这些被调用<referential actions>,直接来自 SQL:2011 规范
ON DELETE CASCADE: 如果引用表的一行被删除,则引用表中所有匹配的行都被删除。ON DELETE SET NULL: 如果引用表的一行被删除,则引用表的所有匹配行中的所有引用列都将设置为空。ON DELETE SET DEFAULT: 如果引用表的一行被删除,则引用表的所有匹配行中的所有引用列都将设置为该列的默认值。ON DELETE RESTRICT: 如果该行在引用表中有任何匹配的行,则禁止删除该行。ON DELETE NO ACTION(默认):没有引用删除操作;引用约束仅指定约束检查。
外键建立依赖关系。在<referential action>确定何时关系溶解会发生什么。
对于这个例子,我们将接受社会和经济的共同模型:其中每business一家都是一家bourgeoisie通过fatcat_owner.
CREATE TABLE bourgeoisie(
fatcat_owner varchar(100) PRIMARY KEY
);
INSERT INTO bourgeoisie(fatcat_owner) VALUES
( 'Koch Brothers' );
CREATE TABLE business (
name varchar(100),
fatcat_owner varchar(100) REFERENCES bourgeoisie
);
INSERT INTO business(name, fatcat_owner)
VALUES ('Georgia-Pacific', 'Koch Brothers');
Run Code Online (Sandbox Code Playgroud)
如果所有的businesses 都直接受到bourgeoisie他们的影响,fatcat_owner那么在工人革命之后,当你清洗fatcat_owners 并拥有一个无阶级的社会时,你会做什么?
-- Viva la revolución
BEGIN;
DELETE FROM bourgeoisie;
END;
Run Code Online (Sandbox Code Playgroud)
你有几个选择,
停止革命。在 SQL 中,RESTRICT. 有些人认为这是较小的邪恶,但他们通常是错误的。
让它继续。如果是这样,当革命发生时 SQL 给了你四个选项,
SET NULL——留空。谁知道呢,也许资本主义恢复bourgeoisie了,寡头们出现了fatcat_owners。重要说明,该列必须是NULLABLE(not NOT NULL) 否则这永远不会发生。
SET DEFAULT- 也许你有一个DEFAULT处理这个的?A
DEFAULT可以调用一个函数。也许你的模式已经准备好革命了。
CASCADE- 没有损坏控制。如果bourgeoisie是这样,那么business. 如果一个业务必须有一个fatcat_owner,那么有时丢失数据比在business表中包含一个非业务更有意义。
NO ACTION-- 这本质上是一种延迟检查的方法,在 MySQL 中它与 没有什么不同RESTRICT,但是在 PostgreSQL 中,您可以这样做
-- Not a real revolution.
-- requires constraint be DEFERRABLE INITIALLY DEFERRED
BEGIN;
SET CONSTRAINTS ALL DEFERRED;
DELETE FROM bourgeoisie;
INSERT INTO bourgeoisie VALUES ( 'Putin' );
UPDATE business SET fatcat_owner = 'Putin';
END;
Run Code Online (Sandbox Code Playgroud)
在这样的系统中,仅在事务提交之前验证约束。这可能会导致停止革命,但您可以在交易中恢复——某种程度的“恢复”。
小智 6
一个简单的助记符是
ON DELETE 父 CASCADE [通过删除]此处
它告诉您哪些删除(父级的删除)被级联、ON DELETE CASCADE语句的去向(子级)以及删除的内容(子级)。