5

我正在使用 redbean ORM 使用 mysql 和 codeigniter。在为多对多关联实现外键后,运行时出现以下错误:

drop TABLE IF EXISTS `temp`

Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails thrown

然后我将 SHOW ENGINE INNODB STATUS 输入到 phpmyadmin。输出包括:

LATEST FOREIGN KEY ERROR------------------------:  Cannot drop table `db1`.`temp`because it is referenced by `db1`.`temp_workers`.

换句话说,另一个表引用了 FK。出于测试目的,我认为最好的做法是删除所有关联的表并使用我正在测试的控制器重新创建它们。这是最好的方法吗?我试过了:

drop TABLE IF EXISTS `temp` `temp_workers`

,但我仍然收到上述错误,并且 drop 命令不起作用。还:

truncate TABLE `temp`, `temp_workers`

给出:

You have an error in your SQL syntax
4

1 回答 1

3

如评论中所述,您必须首先将具有 FK 约束的任何表删除到其他表,然后您可以删除链接到的表。

例子:

User
  id: 1
  name: Mike

Address 
  id: 1
  user_id: 1 (FK constraint to User.id table.column)
  address_1: 555 Main Street

此设置是 1:1 关系(更多关于数据规范化),其中一个用户行可以引用一个地址行,并且由于地址行取决于用户行的存在,如果您尝试删除用户行,您会看到你提到的错误。

但是,如果您首先删除 Address 表,那么一切都会按预期进行,因为 User 表不是任何其他表的 FK。

确保架构中的引用完整性可确保您不会以孤立行结束,这将渗透到整个数据驱动的应用程序中。

您还可以发出以下命令:

SET foreign_key_checks = 0;
# Do Stuff
SET foreign_key_checks = 1;

但我强烈建议不要这样做,因为您可能会破坏数据的引用完整性,并最终陷入混乱。我见过有人在企业环境中这样做,他们花了数周时间来清理它。但是,如果您出于测试目的而严格执行此操作;就像编写单元测试,或者只是学习,你不想每次都丢表,你可以这样做:

# Because we remove the foreign key check, we can truncate in any order
SET foreign_key_checks = 0;
TRUNCATE TABLE user;
TRUNCATE TABLE address;
SET foreign_key_checks = 1;

使用外键约束的正确模式设计有助于为任何数据驱动的应用程序构建良好的基础。了解何时使用以及如何构建外键约束需要时间,但随着时间的推移,您将开始理解。开始的一个好方法是下载一个开源项目,如magentowordpressvbulletin,并查看它们的模式。您甚至可以使用MySQL 工作台内省这些模式并查看它们的实体关系图(ERD),这将直观地展示表之间的链接。

于 2013-04-17T00:51:47.973 回答