2011-11-05 92 views
0

那么,我的朋友告诉我,我应该开始使用InnoDB作为我的数据库,所以我第一次尝试。我在删除记录/索引/字段/表格时遇到问题。每当我尝试删除一条记录时,我都必须去所有的相关记录,删除这些记录,然后回去删除我的原始记录。我无法删除索引!有没有更简单的方法来做到这一点(因为当我要在PHP中运行,它不会删除任何东西),还是应该跳回到MyISAM?您认为哪些更好?如何删除MySQL InnoDB中的所有相关记录?

回答

2

如果你喜欢删除很多东西,InnoDB可能不适合你。 InnoDB比MyISAM严格得多。查询时速度更快(SELECT,SHOW等),但更新速度较慢(UPDATEINSERT等)。

InnoDB的CASCADE是神奇的,但要非常小心。它也很慢(因为数据库引擎本身会检查所有约束条件)。如果您正在处理级联到其他删除级联的其他更新级联到其他删除级联等的记录,您将等待很长时间。

如果你在开发删除,并通过InnoDB的约束恼火,你可能会发现SET FOREIGN_KEY_CHECKS = 0;非常有帮助:

SET FOREIGN_KEY_CHECKS = 0; 
/* do all kinds of dangerous deletes, eg. delete everything in the db */ 
SET FOREIGN_KEY_CHECKS = 1; 

不要在应用程序本身使用,或绝对确保你不会破坏任何依赖关系。

+0

是的,数据库设计已基本完成,但我处于应用程序的早期开发阶段,使用密钥检查进行测试相当困难,但我认为我会采取不同的操作而不是删除操作,因为我想保留一些有外键的数据。 – ItsGreg

3

如果您希望从属记录在主表中删除记录时自动删除,则需要在外键上指定ON DELETE CASCADE

按照说明书,你的外键约束的选择是其中一个之中:

CASCADE:删除或更新从父表中的行,并 自动删除或更新匹配的行孩子桌子。 支持ON DELETE CASCADE和ON UPDATE CASCADE。在 两个表之间,不要定义在父表或子表中的同一列上执行 的几个ON UPDATE CASCADE子句。

注意级联外键操作不激活触发器。

SET NULL:从父表中删除或更新该行,并将子表中的 外键列设置为NULL。 ON DELETE SET NULL和ON UPDATE SET支持NULL子句。

如果您指定SET NULL操作,请确保您没有将子表中的列作为NOT NULL声明为 。

限制:拒绝父表的删除或更新操作。 指定RESTRICT(或NO ACTION)与删除ON或DELETE子句的ON 相同。

无动作:来自标准SQL的关键字。在MySQL中,相当于 RESTRICT。如果引用表中存在相关外键值,InnoDB将拒绝父表 表的删除或更新操作。 某些数据库系统具有延期检查,NO ACTION是延期检查。在MySQL中,外键约束立即被检查 ,所以NO ACTION与RESTRICT相同。

默认的,如果你不指定任何东西,是NO ACTION - 这就是为什么你删除没有做任何事情现在。

+0

'没有行动'和'RESTRICT'是完全一样的东西,功能上,我想。我认为MySQL同意。 “没有行动”意味着约束失败,所以更新是不可能的。 'RESTRICT'也会这样做。 – Rudie

+0

@Rudie:当然是,“NO ACTION”描述的第一句话是这样说的。 – Jon

+0

我的不好。没有看到。至少我从回头想起它。 – Rudie

0

这正是它应该如何工作。

它保留了所谓的数据完整性。如果你有一个用户和一个与之关联的地址,你应该不能删除用户,除非你首先删除一个地址 - 否则你会在数据库中留下流氓数据。

如果没有使用ON DELETE CASCADE来强制执行,您的应用程序应负责确保删除所有相关数据。

一般innoDB是多的保护您的数据的完整性更好地与它所以坚持不回去myISAM(还有什么每台发动机是最好的前一个问题,但除非你给我们更多的细节存在没有意义住在那)。