我有这个:
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
然后它级联到TableX
和TableY
。这是否可以在更新级联上使用FK,或者仅使用手动定义的触发器?
答案 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)
首先,删除TableX
和TableY
中的所有外键约束。
然后:
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
上具有索引或唯一约束(隐式创建索引)。
您不希望为每列使用单独的外键,因为这会破坏BarId
与FooId
的分层多重关系。如果您更新Foo中的特定BarId
,您希望它仅更新TableX中与该特定BarId
链接的那些FooId
,而不是更新整个表中的所有Id
。 (也就是说,如果我正确理解你的话)。
我也无法抗拒提供名为Foo
的列应该被取出并射中头部。不久之后,至少为他们的创作者提供了坚实的鞭打。 :)而是命名FooId
表F.Id FooId
的PK。随着数据库的增长和查询变得越来越复杂涉及越来越多的表,不仅令人烦恼的是不断对列进行别名(T.Id
),但它变得越来越有可能你会犯错误,比如说,意外地将P.Id
放在了Id
的位置,而且由于该列在两个表中,查询都不会给您带来任何错误。
根据我的理解,数据库专业人员普遍认为,列的名称应该在使用的任何地方都相同,包括在源表中。
我还要提出,如果TableX和TableY没有在其他任何地方引用,那么那些中的人工{{1}}列可能会有利于另一个具有商业含义的列。我不太了解这些表格,但很多时候,当不需要它们时会产生额外的人工ID(例如在多对多的中间连接表中,这几乎不应该有单独的ID)。 / p>