关于删除级联或加入删除:困境

时间:2013-06-08 15:05:52

标签: sql

当两个表由第三个表链接,其中包含一个用两个fk构建的约束时,在删除级联或连接删除时使用是否是一个好习惯?

create T1 (
id1 ...
...
CONSTRAINT pk_id1 PRIMARY KEY (id1) );

create T2 (
id2 ...
...
CONSTRAINT pk_id2 PRIMARY KEY (id2) );

create T3 (
id1 ...,
id2 ...,
CONSTRAINT pk_T3 PRIMARY KEY (id1, id2),
CONSTRAINT fk_T3_1 FOREIGN KEY (id2)
  REFERENCES T2 (id2) MATCH SIMPLE
  ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT fk_T3_2 FOREIGN KEY (id1)
  REFERENCES T1(id1) MATCH SIMPLE
  ON UPDATE CASCADE ON DELETE CASCADE )

有人说在删除级联上使用会很危险,那么连接删除会不那么危险吗?

修改:我没有找到要删除的正确查询:
如果我做

delete from T1 where id1=$id1

然后从T1中删除行$ id1,从T3中删除行$ id1,$ id2但不从T2中删除$ id2。
如果我做

delete from T3 where id1=$id1 and id2=$id2  

然后在T1中没有删除行$ id1,在T2中没有删除行$ id2,在T3中删除了这对($ id1,$ id2)。
如何在一个查询中删除?
编辑:我想通过移动T2表中的一个约束来找到一个技巧,如下所示:

 create T1 (
id1 ...
...
CONSTRAINT pk_id1 PRIMARY KEY (id1) );

create T2 (
id2 ...
...
CONSTRAINT pk_id2 PRIMARY KEY (id2) ),
CONSTRAINT fk_T2 FOREIGN KEY (id2)
  REFERENCES T3 (id2) MATCH SIMPLE
  ON UPDATE CASCADE ON DELETE CASCADE);

create T3 (
id1 ...,
id2 ...,
CONSTRAINT pk_T3 PRIMARY KEY (id1, id2),

CONSTRAINT fk_T3_2 FOREIGN KEY (id1)
  REFERENCES T1(id1) MATCH SIMPLE
  ON UPDATE CASCADE ON DELETE CASCADE );  

但是我有一条消息"没有唯一约束...对于引用的T3表"

1 个答案:

答案 0 :(得分:3)

关于删除级联有时被称为“危险”,因为无意识的查询最终会删除比你想象的更多。我已经看到至少有一种情况,其中一个不正确的where子句(无意中删除了树中的根节点)最终通过级联删除删除了比预期更多的堆(即那些根节点的子树)。

在这种意义上,连接删除同样危险。

偶尔向学习SQL的用户建议的是根本不使用级联删除。这迫使他们记住他们删除的内容和顺序,因为当他们的where子句不正确时,他们会得到方便的错误消息。但是,如果你对SQL足够舒服以担心使用连接删除,那么你很可能会超越这一点。