2011-06-28 9 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

まずその作成スクリプトを試してみてください。その後

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で確実に動作します。この外部キー参照が機能するには、テーブルFoo(Id, BarId)にインデックスまたは一意の制約(暗黙的にインデックスを作成する)が必要です。

BarIdにある階層的な複数の関係が、FooIdであるため、個々の外部キーを列ごとに使用する必要はありません。 Fooで特定のBarIdを更新する場合は、テーブル全体の一部であるFooIdにリンクされているTableXのBarIdのみを更新する必要があります。 (つまり、私があなたを正しく理解しているならば)。

また、Idという名前の列を取り出して頭で撮影することはできません。間もなく、少なくともクリエイターのための頑丈な鞭打ちが続きます。 :)代わりにFooテーブルFooIdのPKに名前を付けます。データベースが大きくなり、クエリがますます複雑になるにつれて、常に列のエイリアシングが厄介であるだけでなく(誤って間違いを犯す可能性が増します) T.IdここではP.Idを意味し、その列は両方の表にあるため、問合せでエラーは発生しません。

私の理解では、データベース専門家の一般的な合意は、使用されているすべての列(ソース表を含む)の名前を同じにする必要があるということです。

TableXとTableYが他の場所で参照されていない場合、その中の人工的なId列が、ビジネス上の意味を持つ別の列を優先して出現する可能性があります。私は本当に言うべきテーブルについては十分に分かっていませんが、必要でないときには何回も余分な人工Idが生成されます(多対多中間結合テーブルなど)。

+0

ErikEありがとうございます。あなたはあなたの最後のことを精緻化できますか? – FrankF

+0

@Frankが更新されました。 – ErikE

0

[更新時カスケード時]を指定すると、参照値が更新されます。 TableXTableYにあなたが持っているすべての外部キー制約をドロップし、

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;