MySQL报错Failed to open the referenced table XXX问题

 更新时间:2024年11月06日 10:46:11   作者:A_bad_horse  
在数据库操作中,尝试删除外键约束表'master_role'时遇到错误码3730,因其被'user_role'表中的外键'fk_user_role'引用,解决方法包括关闭外键检查和删除外键,阿里巴巴开发手册和知乎回答指出,外键虽能维护数据一致性

问题复现

CREATE TABLE `master_role` (
  `id` INTEGER NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `role` VARCHAR(50) CHARACTER SET latin1 NOT NULL COMMENT 'Role',
  `active` TINYINT NOT NULL COMMENT 'Active',
  PRIMARY KEY (`id`)
)
ENGINE = InnoDB
DEFAULT CHARSET=utf8mb4
COMMENT = 'Master Role';
CREATE TABLE `user_role` (
  `id` INTEGER NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `email` VARCHAR(150) NOT NULL COMMENT 'Email',
  `role_id` INTEGER NOT NULL COMMENT 'Role ID',
  PRIMARY KEY (`id`),
  KEY `fk_user_role_idx` (`role_id`),
  CONSTRAINT `fk_user_role` FOREIGN KEY (`role_id`) REFERENCES `master_role` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
)
ENGINE = InnoDB
DEFAULT CHARSET=utf8mb4
COMMENT = 'User Role';

step1: create table master_role

step2: create table user_role

step3: DROP TABLE IF EXISTS master_role;

Error Code: 3730. Cannot drop table 'master_role' referenced by a foreign key constraint 'fk_user_role' on table 'user_role'.

解决方案

方案一:关闭外键检查

SET foreign_key_checks=0;  # 关闭外键检查
DROP TABLE Course;
SET foreign_key_checks=1;  # 开启外键检查

关闭检查之后,如果下次还要使用外键就要再次打开检查,较为繁琐。

方案二:删除外键

#user_role表删除外键
ALTER TABLE user_role DROP FOREIGN KEY fk_user_role;
#删表
DROP TABLE IF EXISTS master_role;

外键

阿里规范

源自《阿里巴巴开发手册》

实例:

假设删除微博某V,其粉丝关系表中的百万条数据如果有外键约束,就会影响性能。

来自知乎的回答

  • 外键约束是物理上的“硬绑定”,而表的关联只是一种逻辑概念,即数据间存在一定的联系。数据库通过外键建立的“硬绑定”会带来额外的资源消耗来进行一致性和完整性校验,尽管有时候无需这些校验。
  • 因此,一般不建议使用外键约束来保证数据的一致性和完整性。--- 源自知乎

外键作用:维护数据一致性和完整性,避免借助外部资源(例如:启用事务)。

何时使用:高并发大流量事务场景使用外键容易造成死锁,数据库资源会更容易出现瓶颈。一般互联网很少使用外键。--- 源自知乎

总结

实际建表时,不建外键。

表之间的关联可以通过建立索引(咨询同事得到的答案,后续会就此问题写博客解答)。

更新user_role表的创建语句,删除外键。

CREATE TABLE `user_role` (
  `id` INTEGER NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `email` VARCHAR(150) NOT NULL COMMENT 'Email',
  `role_id` INTEGER NOT NULL COMMENT 'Role ID',
  PRIMARY KEY (`id`)
)
ENGINE = InnoDB
DEFAULT CHARSET=utf8mb4
COMMENT = 'User Role';

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • MySQL中使用case when 语句实现多条件查询的方法

    MySQL中使用case when 语句实现多条件查询的方法

    今天在一个应用中使用到了一个比较特殊的数据查询要求。需要的朋友可以参考下。
    2010-12-12
  • MySQL联表查询的简单示例

    MySQL联表查询的简单示例

    这篇文章主要给大家介绍了关于MySQL联表查询的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用MySQL具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • MySQL查看和修改时区的实现方法

    MySQL查看和修改时区的实现方法

    本文主要介绍了MySQL查看和修改时区,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • MySQL 配置主从复制实践分享

    MySQL 配置主从复制实践分享

    这篇文章主要介绍了MySQL 配置主从复制实践分享,通过检测通信展开详情,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-07-07
  • mysql5.6批量设置表ROW_FORMAT =DYNAMIC问题

    mysql5.6批量设置表ROW_FORMAT =DYNAMIC问题

    这篇文章主要介绍了mysql5.6批量设置表ROW_FORMAT =DYNAMIC问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • MySQL创建内部临时表的所有场景盘点

    MySQL创建内部临时表的所有场景盘点

    这篇文章主要为大家介绍了MySQL创建内部临时表的所有场景盘点,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • 使用navicat将csv文件导入mysql

    使用navicat将csv文件导入mysql

    这篇文章主要为大家详细介绍了使用navicat将csv文件导入mysql,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • Express连接MySQL及数据库连接池技术实例

    Express连接MySQL及数据库连接池技术实例

    数据库连接池是程序启动时建立足够数量的数据库连接对象,并将这些连接对象组成一个池,由程序动态地对池中的连接对象进行申请、使用和释放,本文重点给大家介绍Express连接MySQL及数据库连接池技术,感兴趣的朋友一起看看吧
    2022-02-02
  • MySQL备份与恢复之热备(3)

    MySQL备份与恢复之热备(3)

    热备使用mysqldump命令进行备份,此工具是MySQL内置的备份和恢复工具,功能强大,它可以对整个库进行备份,可以对多个库进行备份,可以对单张表或者某几张表进行备份,需要了解的朋友可以参考下
    2015-08-08
  • MySQL数据操作-DML语句的使用

    MySQL数据操作-DML语句的使用

    这篇文章主要介绍了MySQL数据操作-DML语句的使用,帮助大家更好的理解和使用MySQL数据库,感兴趣的朋友可以了解下
    2020-11-11

最新评论