14

単一テーブル継承に関するBillKarwinの回答のいくつかを読みましたが、このアプローチは、検討しているセットアップに適していると思います。

Playlist
--------
id AUTO_INCREMENT
title

TeamPlaylist
------------
id REFERENCES Playlist.id
teamId REFERENCES Team.id

UserPlaylist
------------
id REFERENCES Playlist.id
userId REFERENCES User.id

PlaylistVideo
-------------
id
playlistId REFERENCES Playlist.id
videoId REFERENCES Video.id

すべてのCASCADEオプションは、aが削除されDELETEたときに正しく機能するように設定されていますが、またはが削除された場合はどうなりますか?PlaylistUserTeam

すなわち。aUserが削除されると、の行は削除さUserPlaylistれますが、の参照された行PlaylistPlaylistVideo残ります。これを強制することを考えましたが、が削除されたために削除要求が発生したのか、それとも削除されたのかTRIGGER AFTER DELETEを知る方法がありません。PlaylistUser

この状況で整合性を強制するための最良の方法は何ですか?

編集(提供されたERD)

ここに画像の説明を入力してください

4

4 に答える 4

11

実行できることは、次のいずれかから行が削除されるたびに実行されるトリガーをUsersテーブルTeamに実装することです。

ユーザーテーブル:

DELIMITER $$
CREATE TRIGGER user_playlist_delete 
BEFORE DELETE ON User FOR EACH ROW
BEGIN
    DELETE a FROM Playlist a
    INNER JOIN UserPlaylist b ON a.id = b.id AND b.userId = OLD.id;
END$$
DELIMITER ;

チームテーブル:

DELIMITER $$
CREATE TRIGGER team_playlist_delete 
BEFORE DELETE ON Team FOR EACH ROW
BEGIN
    DELETE a FROM Playlist a
    INNER JOIN TeamPlaylist b ON a.id = b.id AND b.teamId = OLD.id;
END$$
DELIMITER ;

これらのトリガーが行うことは、これらのテーブルの1つからレコードが削除されるたびに、削除されようとしているテーブルを使用して(内部結合を介して)DELETE操作がテーブルに対して自動的に実行されることです。Playlistsid

私はこれをテストしました、そしてそれは素晴らしい働きをします。

于 2012-07-19T01:51:29.503 に答える
4

OK私はあなたがここで何をしたいのかわかります...あなたがしたいのは次のようなクエリを実行することです

DELETE FROM playlist
WHERE       id 
NOT IN      (
    SELECT  id
    FROM    UserPlayList
    UNION
    SELECT  id
    FROM    TeamPlayList
)

ユーザーまたはチームのいずれかから行が削除された後

于 2012-07-18T05:17:18.420 に答える
3

私の見解では、問題は、プレイリストテーブルではなくUserTeamテーブルがスーパータイプテーブル(などParty)を持つべきものであるということです。

ご指摘のとおり、プレイリストで「テーブルの継承」を行うと、何を削除するかを考えたときにペナルティが発生します。継承をユーザー/チームレベルに上げると、これらの問題はすべて解消されます。

スーパータイピング/サブタイピングの詳細については、この回答を参照してください。

MySQLの構文がよくわからないため、コードを提供しないことをお詫びします。

基本的な概念は、スーパータイプテーブルを使用すると、データベースのようなポリモーフィズムを実装できるということです。作業しているテーブルがサブタイプのグループのいずれかにリンクする必要がある場合は、代わりにFKがスーパータイプを指すようにするだけで、目的の「一度に1つだけ」のビジネス制約が自動的に取得されます。 。スーパータイプは、各サブタイプテーブルと「1対0または1」の関係にあり、各サブタイプテーブルは、そのPKでスーパータイプテーブルのPKと同じ値を使用します。

データベースではPlaylist、FKを使用するテーブルを1つだけ持つParty (PartyID)ことで、トリガーなしでデータベースレベルでビジネスルールを簡単に適用できます。

于 2012-07-24T23:47:55.773 に答える
1

Zane Bienの答えは非常に明白で素晴らしいですが、トリガーには多くの問題があるため、トリガーを使用せずにこれを行うことを考えています。

プログラミング言語を使用していますか?はいの場合、

シングルtransactionを使用してデータベースを作成しますauto commit false

プレイリストとプレイリストビデオで参照されている行の削除クエリを記述します。手動では、最初にその参照ID(where条件付き)を使用してこのクエリを記述し、実行する必要があります。

次に、メインタスク用に別のクエリを準備します。つまり、ユーザーを削除すると、UserPlaylistの行が自動的に削除されます(CASCADE DELETEオプションにより)。次に、2番目のクエリを実行しますcommit

最後に取引を行いますauto commit true

正常に動作しています。お役に立てば幸いです。

于 2012-07-23T09:51:09.367 に答える