mysql-error 1823:未能将外键约束添加到系统表

mefy6pfw  于 2021-06-18  发布在  Mysql
关注(0)|答案(1)|浏览(584)

我正在更新一个数据库,以更正更新和删除时的外键行为。然而,特别是在一张table上,这出乎意料地困难。
在大多数表格中,我一直在毫无问题地执行以下操作:
删除外键约束
删除相应的索引
添加新的、更新的外键
然而,有一张table给我带来了一些我不太明白的麻烦。尝试执行上述过程会返回以下错误(我已将db名称修改为 db_name ):

SQLSTATE[HY000]: General error: 1025 Error on rename of 
'./<db_name>/#sql-5e1_1c5' to './<db_name>/doctors' 
(errno: 150 - Foreign key constraint is incorrectly formed)
(SQL: alter table `doctors` drop index `doctors_id_unique`)

表格的相关部分如下:

UNIQUE KEY `doctors_id_unique` (`id`),
  UNIQUE KEY `doctors_code_unique` (`code`),
  KEY `doctors_updated_by_foreign` (`updated_by`),
  CONSTRAINT `doctors_id_foreign` FOREIGN KEY (`id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
  CONSTRAINT `doctors_updated_by_foreign` FOREIGN KEY (`updated_by`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

我想改变 id 到主键和外键,因此我执行以下操作:

ALTER TABLE doctors DROP FOREIGN KEY doctors_id_foreign;
ALTER TABLE doctors DROP INDEX doctors_code_unique;
ALTER TABLE doctors DROP INDEX doctors_id_unique;

但是,在第3条语句中,我得到以下错误:

Error on rename of './<db_name>/#sql-5e1_2' to './<db_name>/doctors' 
(errno: 150 - Foreign key constraint is incorrectly formed)

我想不出怎么解决这个问题。我试着放下枪 updated_by 约束和键以及 code 首先是唯一键,但它不会改变任何东西。我尝试禁用外键检查,但没有雪茄。
我尝试更改用于测试的sql转储。将其更改为以下内容使其按我的预期工作,至少很明显:

PRIMARY KEY (`id`),
  UNIQUE KEY `doctors_code_unique` (`code`),
  KEY `doctors_updated_by_foreign` (`updated_by`),
  CONSTRAINT `doctors_id_foreign` FOREIGN KEY (`id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `doctors_updated_by_foreign` FOREIGN KEY (`updated_by`) REFERENCES `users` (`id`) ON UPDATE CASCADE ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

但是,我更希望通过编程来更新表,这样可以使迁移更容易、更可靠。所以我尝试了另一种方法,只需重命名表,将它复制到一个新表,然后在那里添加键:

SET FOREIGN_KEY_CHECKS=0;
RENAME TABLE `doctors` TO `old_doctors`;
CREATE TABLE `doctors` SELECT * FROM `old_doctors`;
ALTER TABLE `doctors` ADD PRIMARY KEY (`id`);
ALTER TABLE `doctors` ADD UNIQUE INDEX `doctors_code_unique` (`code`);
ALTER TABLE `doctors` ADD CONSTRAINT `doctors_id_foreign` FOREIGN KEY `doctors_id_foreign` (`id`) REFERENCES `users` (`id`) ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE `doctors` ADD CONSTRAINT `doctors_updated_by_foreign` FOREIGN KEY `doctors_updated_by_foreign` (`updated_by`) REFERENCES `users` (`id`) ON UPDATE CASCADE ON DELETE SET NULL;
SET FOREIGN_KEY_CHECKS=1;

现在我得到以下错误:

SQLSTATE[HY000]: General error: 1823 Failed to add the foreign key constraint
'<db_name>/doctors_id_foreign' to system tables (SQL: ALTER TABLE `doctors`
ADD CONSTRAINT `doctors_id_foreign` FOREIGN KEY `doctors_id_foreign` (`id`) 
REFERENCES `users` (`id`) ON UPDATE CASCADE ON DELETE CASCADE)

所以我无法让它工作,而且两个错误似乎都不常见:我找不到任何关于如何处理它们的好信息。
这是如此耗时,我可能会放下服务器,转储数据库,手动修复转储,然后将修复后的转储导入回去;然而,我真的很想知道这是一些错误,或者我只是错过了一些东西。这很有可能,因为我几乎不是一个有经验的程序员。
对于context:这都是在一个laravel(5.7.13)项目中,但是错误发生在使用laravel迁移(使用schema和blueprint)和直接通过sql控制台。mysql版本5.7.22。
热释光;dr:我就是不能在更新/删除时更改表的外键行为,尽管在同一个db上的其他表上这样做是成功的。我尝试了两种截然不同的方法来修复它,两种方法都返回了(明显的)错误,我在任何地方都找不到解决方法。是虫子还是我遗漏了什么?

k4emjkb1

k4emjkb11#

确保没有其他表引用 doctors.id 列的外键。
如果是,请在删除这些外键之前删除它们 doctors_id_unique 索引。
然后,在您创建了外键之后恢复外键 doctors.id 主键。

相关问题