级联问题

时间:2011-06-28 18:55:26

标签: sql cascade

我有这个:

Foo
Id|BarId

Bar
Id

TableX
Id|FooId|BarId

TableY
Id|FooId|BarId

如果像

这样的查询,我需要它
update Foo
set BarId = some bar id
where BarId = some other bar id

然后它级联到TableXTableY。这是否可以在更新级联上使用FK,或者仅使用手动定义的触发器?

2 个答案:

答案 0 :(得分:0)

如果指定On Update Cascade,则会更新引用的值。 尝试创建脚本

CREATE TABLE TableX(
  id INT, 
  FooId INT,
  BarId INT,
  INDEX foo_idx (FooId),
  INDEX bar_idx (BarId),
  FOREIGN KEY (FooId) 
    REFERENCES Foo(Id) 
    ON UPDATE CASCADE
  FOREIGN KEY (BarId) 
    REFERENCES Bar(Id) 
    ON UPDATE CASCADE
) ENGINE=INNODB;

答案 1 :(得分:0)

首先,删除TableXTableY中的所有外键约束。

然后:

ALTER TABLE TableX
   ADD CONSTRAINT FK_TableX_FooId_BarID FOREIGN KEY (FooId, BarId)
   REFERENCES Foo (Id, BarId) ON UPDATE CASCADE;

-- Do the same for TableY

你没有说你正在使用什么DBMS(请做)但这在SQL Server和MySql中肯定会有用。在此外键引用起作用之前,您必须在表(Id, BarId)中的Foo上具有索引或唯一约束(隐式创建索引)。

您不希望为每列使用单独的外键,因为这会破坏BarIdFooId的分层多重关系。如果您更新Foo中的特定BarId,您希望它仅更新TableX中与该特定BarId链接的那些FooId,而不是更新整个表中的所有Id。 (也就是说,如果我正确理解你的话)。

我也无法抗拒提供名为Foo的列应该被取出并射中头部。不久之后,至少为他们的创作者提供了坚实的鞭打。 :)而是命名FooIdF.Id FooId的PK。随着数据库的增长和查询变得越来越复杂涉及越来越多的表,不仅令人烦恼的是不断对列进行别名(T.Id),但它变得越来越有可能你会犯错误,比如说,意外地将P.Id放在了Id的位置,而且由于该列在两个表中,查询都不会给您带来任何错误。

根据我的理解,数据库专业人员普遍认为,列的名称应该在使用的任何地方都相同,包括在源表中。

我还要提出,如果TableX和TableY没有在其他任何地方引用,那么那些中的人工{{1}}列可能会有利于另一个具有商业含义的列。我不太了解这些表格,但很多时候,当不需要它们时会产生额外的人工ID(例如在多对多的中间连接表中,这几乎不应该有单独的ID)。 / p>