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。在两个表之间,不要定义多个作用于父表或子表中的同一列的 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;

然后,当您从mediastories表中删除时,表中的相应记录links也将被删除。

请参阅带有演示的 SQL Fiddle

于 2013-01-19T13:05:20.790 回答
2

使用 InnoDB,bluefeet 的方法是正确的。但是,如果它只是一次性操作,那么语法如下......

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 回答