2011-06-28 67 views
0

我有这样的:级联问题

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,或只有手动定义的触发器?

+0

请详细说明什么是引用这组表中的内容。 –

+0

你使用什么数据库引擎?许多数据库(一个是Oracle)在外键上没有级联更新。 –

+1

为什么TableX和TableY中有FooID?由于表Foo,BarID是否已经完全暗示了FooID?或者一个BarID可以在多个Foos中?我希望你会使用明智的示例对象而不是无意义的对象。 – ErikE

回答

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中与该特定FooId链接的那些BarId,而不是整个表中的全部。 (也就是说,如果我正确理解你的话)。

我也忍不住要提出名为Id的栏目应该被拿出来拍在脑袋里。不久之后,他们的创作者至少会有一个坚实的鞭子。 :)相反,请命名FooFooId的PK。随着数据库的增长和查询变得越来越复杂,涉及越来越多的表格,不仅恼人的是不断地出现别名列(F.Id FooId),而且它变得越来越可能会犯错误,比如说意外地把T.Id你的意思是P.Id并且该查询将不会出现错误,因为该列在两个表中。

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

我还会提供,如果TableX和TableY没有引用任何其他地方那么人造Id列可能会出来赞成另一列具有商业意义。我不太了解表格的真实含义,但是当不需要它们时(例如在多对多的中间连接表中,几乎从不具有单独的ID),会生成多次额外的虚假Ids。

+0

谢谢ErikE。你能详细说明你的最后一边吗? – FrankF

+0

@Frank更新。 – ErikE

0

如果您指定了“更新级联”,则会更新引用的值。 尝试是创建脚本

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;