如何使用ON DELETE CASCADE删除相应的行

时间:2012-09-27 03:08:48

标签: mysql sql

我有2个表,一个称为“图像”表,另一个称为“Image_Question”表。以下是2个表格的样子:

图像表:

ImageId   ImageFile
01        picture/cat.png
02        picture/cat_2.png
03        picture/dog.png

Image_Question表:

ImageId  SessionId  QuestionId
01            ADS            3
02            FTG            7
03            JJK            1

我的问题是在SQL中如何编写它以便将来自两个表的ImageId链接在一起,这样我就可以说从Image Table中删除了ImageId = 01的行,即ImageId = 01(对应的行)来自Image_Question表也被删除。

我尝试了下面的代码,但它不起作用:

ALTER TABLE Image_Question ADD CONSTRAINT FK_ImageId FOREIGN KEY (ImageId) REFERENCES Image (ImageId) ON DELETE CASCADE; 

更新:

显示图像表:

CREATE TABLE `Image` (
 `ImageId` int(10) NOT NULL AUTO_INCREMENT,
 `ImageFile` varchar(250) NOT NULL,
 PRIMARY KEY (`ImageId`)
) ENGINE=MyISAM AUTO_INCREMENT=399 DEFAULT CHARSET=utf8

显示IMAGE_QUESTION表:

CREATE TABLE `Image_Question` (
 `ImageQuestionId` int(10) NOT NULL AUTO_INCREMENT,
 `ImageId` int(10) NOT NULL,
 `SessionId` varchar(10) NOT NULL,
 `QuestionId` int(5) NOT NULL,
 PRIMARY KEY (`ImageQuestionId`),
 KEY `QuestionId` (`QuestionId`),
 KEY `SessionId` (`SessionId`),
 KEY `fk_imagequestionid` (`ImageId`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

1 个答案:

答案 0 :(得分:0)

对于外键的唯一要求是它是一个索引,据我所知。 Image_Questions中的密钥应该是QuestionId,看起来您已根据我的建议在评论中将其更改为。但这不是你的CASCADE DELETE不起作用的原因。

(旁注:就数据组织而言,99.9%的案例中两个表具有相同的主键是没有意义的(只有实际情况是隐藏敏感信息,如信用卡号)。表具有相同的主键,它们应该是同一个表。)

由于您发布了CREATE TABLE语句,问题现在非常明显 - 只有InnoDB支持MySQL中的外键约束。 MyISAM(尚未)。它们让您使用外键语法创建没有错误的MyISAM表并且不支持它是奇怪和误导性的。

设置它的方式,从表Image中删除一行将删除Image_Question中的相应行。这是有道理的。

外键设置父级 - >子级关系。如果你杀了父母,孩子就会死去。但如果你杀了一个孩子,那就不会杀死父母。父母将继续存在,并可能有许多其他孩子。

您的每张图片可能有50个问题。删除任何一个子问题时,您不希望删除父图像。但是如果你删除1张图片,那么它的所有子问题都会变得无关紧要,毫无用处。您可以级联删除,但如果您认为子数据在某些方面仍然有用,则可以SET NULLNO ACTION。 SET NULL将使所有orphan行相等,而NO ACTION将保持其所需的外键,因此即使父项已经消失,您仍然可以按父级对它们进行分组。

一旦您将表更改为InnoDB,此查询应导致级联:

DELETE FROM `Images` WHERE `id` = 2;

这将从Images中删除一行,其中id为2(因为id是主键,每个值只能存在一行),并且 Image_QuestionsImageId为2的所有行(可能存在数百万行)。

另请注意,将ImageId作为Image_Questions的第一列并且它不应该是主键是非常奇怪的。很少有理由让两个表具有完全相同的主键。 Image_Questions的主键应为QuestionId

有关MySQL中外键支持的信息,请参阅此处:

http://dev.mysql.com/doc/refman/5.5/en/ansi-diff-foreign-keys.html

以下是ON DELETE选项的链接:

http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html