5

UserPostの間に 1..* 関係があります。(1 人のユーザーが複数の投稿を持っている)

Postには「UserId」と呼ばれる FK があり、これはUserテーブルの「UserId」フィールドにマップされます。

この FK を Cascade UPDATE/DELETE として設定しようとしましたが、次のエラーが発生します。

「ユーザー」テーブルは正常に保存されました 「投稿」テーブル - リレーションシップ「FK_Posts_Users」を作成できません。
テーブル 'Posts' に FOREIGN KEY 制約 'FK_Posts_Users' を導入すると、サイクルまたは複数のカスケード パスが発生する可能性があります。ON DELETE NO ACTION または ON UPDATE NO ACTION を指定するか、他の FOREIGN KEY 制約を変更します。制約を作成できませんでした。以前のエラーを参照してください。

PostHelpfulというテーブルがあります。1 つの投稿には多くの役立つ投稿があります。

Helpful には User へのカスケード FK があります (そのため、User が削除されると、その Helpful も削除されます)。

しかし、これが「複数のカスケードパス」に対する不満の原因だと思います。

ユーザーを削除すると(現在)、そのユーザーの役立つ情報が削除されるためです。しかし、ポストにもカスケードを追加しようとしていますが、ポストを削除してから、そのポストのヘルプフルを削除しようとします(ヘルプフルにはポストへのカスケード FK もあるため)。そのシナリオでは、SQL はどのカスケード FK を選択しますか?

問題の 3 つのテーブルのデータベース ダイアグラムを次に示します。

ここに画像の説明を入力

ご覧のとおり、「PostHelpful」は「Post」と「User」の両方の子です (両方に FK があります)。

では、両方のキーをカスケードすることはできませんか? 役立つもの(およびユーザーを参照する他のテーブル)を手動で削除するには、「ユーザー」(削除後)にトリガーが必要ですか。

4

1 に答える 1

3

SQL Serverがどちらのパスを選択するかは問題ではなく、妥協する位置にたどり着かないようにパスを許可しません。このような状況に遭遇したとき、私たちは引き金に頼らなければなりませんでした。

1)エラーメッセージに記載されているように、 Users_PostHelpfulsFKONDELETENOACTIONに変更します。

2)INSTEADOFDELETEトリガーをユーザーに追加します。

CREATE TRIGGER dbo.Users_IO_Delete 
ON dbo.Users
INSTEAD OF DELETE
AS
BEGIN;
    DELETE FROM dbo.PostHelpfuls WHERE UserId IN (SELECT UserId FROM deleted);

    DELETE FROM dbo.Users WHERE UserId IN (SELECT UserId FROM deleted);
END;

これで、FKは引き続きDRIを適用しますが、トリガーはFK制約ではなく削除をカスケードします。

上記の手順で、 PostHelpfulsPostsに置き換えることができます。ただし、これを行うときは、トリガーを使用して、独立性の低いエンティティのレコードを削除することをお勧めします。つまり、PostHelpfulsがUsersPostsの横のテーブルに関連付けられているよりも、PostsがUsersPostHelpfulsの横のテーブルに関連付けられている可能性が高くなります。

于 2011-03-02T08:43:50.043 に答える