如何测试与外键链接的表?

时间:2013-04-16 23:46:36

标签: php mysql

我使用redbean ORM使用mysql和codeigniter。在为多对多的assosciation实现外键后,我运行时遇到以下错误:

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状态输入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

1 个答案:

答案 0 :(得分:2)

如评论中所述,您必须将具有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关系(more on data normalization),其中一个用户行可以引用一个地址行,并且因为地址行取决于用户行的存在,如果您尝试删除用户行,您将看到您提到的错误。

但是如果你先删除Address表,一切都按预期工作,因为User表不是任何其他表的FK。

确保架构中的referential integrity可确保您不会遇到孤立的行,这些行将渗透到整个数据驱动的应用程序中。

您还可以发出以下命令:

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

但我强烈建议不要这样做,因为你可能会破坏数据的参照完整性,并最终陷入混乱。我见过有人在企业环境中这样做,并花了几周的时间来清理它。但是,如果您正在执行 STRICTLY 以进行测试;比如写单元测试,或者只是学习,而且你不想每次都放弃表,你可以这样做:

# 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 workbench对这些模式进行内省,并查看它们的Entity-Relationship Diagrams(ERD),它们可以直观地展示表之间的链接。