0

あるサイトが、人気のある記事を、その記事がリリースされたメディア形式に従って分類しているとします。そのデータベースは、次のテーブルで構成されています。

ストーリーテーブル

リンクテーブル

メディアテーブル

記事がデータベースから削除された場合、そのメディアの関連付けも削除する必要があります。特定の種類のメディアに関連付けられた唯一のストーリーが削除された場合、そのメディアに関する情報は役に立たなくなり、削除する必要があります。

たとえば、スパイダーマン (story_id 2) が削除された場合、映画やコミック メディアへのリンクも削除する必要があります。他のストーリーはコミックの形でリリースされないため、メディアとしてのコミックに関する情報は削除する必要がありますが、メディアとしての映画に関する情報は他のストーリーに引き続き関連しており、そのままにしておく必要があります。

抽象的には、次の方法でこれを達成することを考えました。

//delete the story itself:
DELETE FROM stories WHERE stories.story_id = 2

//delete its links to media:
DELETE FROM links WHERE links.story_id = 2

//delete any  media that might subsequently no longer have any links to them:
DELETE FROM media WHERE media.medium_id does not occur in links.medium_id

またはこのように:

//delete the story itself:
DELETE FROM stories WHERE stories.story_id = 2

//fetch its associated media ids:
SELECT links.medium_id FROM links WHERE links.story_id = 2

//delete the story's links to any media:
DELETE FROM links WHERE links.story_id = 2

//consider deleting the types of media of which a story has just been deleted:
DELETE FROM media WHERE media.medium_id does not occur in links.medium_id and medium.medium_id = <previously fetched medium id(s)>

おそらくより良いアプローチの一部として、これらのクエリまたは他のクエリを実際にどのように書き出すのでしょうか?

4

3 に答える 3

3

テーブルが でセットアップされている場合はFOREIGN KEY、使用を検討することをお勧めします。ON DELETE CASCADE

その後、storyテーブルから削除すると、そのストーリーにリンクされているアイテムが削除されます。

MySQLドキュメントから:

CASCADE: 親テーブルから行を削除または更新し、子テーブルの一致する行を自動的に削除または更新します。ON DELETE CASCADE と ON UPDATE CASCADE の両方がサポートされています。2 つのテーブル間で、親テーブルまたは子テーブルの同じ列に作用する複数の ON UPDATE CASCADE 句を定義しないでください。

SOユーザー@Marc Bは、これを設定することについて優れた回答を書きました:

MySQL 外部キー制約、カスケード削除

編集#1、テーブルは次のように設定されます:

CREATE TABLE stories
    (`story_id` int not null, 
     `story_title` varchar(18), 
     `story_rating` varchar(9),
     primary key (story_id),
     key idx_story_id (story_id)
    ) ENGINE=InnoDB;

CREATE TABLE media
    (`medium_id` int not null, 
     `medium_name` varchar(9), 
     `medium_popularity` varchar(6),
     primary key (medium_id),
     key idx_medium_id (medium_id)
     ) ENGINE=InnoDB;


CREATE TABLE links
    (`link_id` int not null, 
     `story_id` int, 
     `medium_id` int,
     primary key (link_id),
     key ix_story_id (story_id), 
     key ix_medium_id (medium_id),
    FOREIGN KEY (story_id) REFERENCES stories(story_id)
       ON DELETE CASCADE,
    FOREIGN KEY (medium_id) REFERENCES media(medium_id)
       ON DELETE CASCADE
     ) ENGINE=InnoDB;

次に、mediaまたはstoriesテーブルから削除すると、テーブル内の対応するレコードlinksも削除されます。

デモで SQL Fiddle を参照してください

于 2013-01-19T13:05:20.790 に答える
2

InnoDB を使用すると、bluefeet の方法が正しい方法です。ただし、1回限りの操作の場合、構文は次のとおりです...

DELETE x FROM table1 x LEFT JOIN table2 y ON y.id = x.id WHERE y.id IS NULL;
于 2013-01-19T13:11:26.373 に答える
1

追加の選択クエリを作成する理由はありません。

//delete the story itself:
DELETE FROM stories WHERE stories.story_id = 2

//delete its links to media:
DELETE FROM links WHERE links.story_id = 2

//delete any  media that might subsequently no longer have any links to them:
DELETE FROM media WHERE media.medium_id NOT IN((SELECT medium_id FROM link))

しかし、@bluefeet が言ったように、私はON DELETE CASCADE.

于 2013-01-19T13:10:35.003 に答える