[英]MySQL: Cannot delete or update a parent row: a foreign key constraint fails
[英]Cannot delete or update a parent row: a foreign key constraint fails - MYSQL
我在尝试从数据库中删除用户时遇到此错误,我知道这样做是因为我要删除的用户是约会表中的外键,但我不知道如何更正它或我哪里出错了。 不确定它是否有任何改变,只是以防万一我使用 laravel 创建了表
用户表
CREATE TABLE `users` (
`id` int(10) UNSIGNED NOT NULL,
`firstname` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`surname` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`address` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`postcode` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`dateofbirth` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`role` tinyint(4) NOT NULL,
`remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
约会表
CREATE TABLE `appointments` (
`id` int(10) UNSIGNED NOT NULL,
`time` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`date` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`doctor_id` int(10) UNSIGNED NOT NULL,
`user_id` int(10) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
ALTER TABLE `appointments`
ADD PRIMARY KEY (`id`),
ADD KEY `appointments_doctor_id_foreign` (`doctor_id`),
ADD KEY `appointments_user_id_foreign` (`user_id`);
ALTER TABLE `appointments`
ADD CONSTRAINT `appointments_doctor_id_foreign` FOREIGN KEY (`doctor_id`) REFERENCES `doctors` (`id`),
ADD CONSTRAINT `appointments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`);
您收到此错误是因为您要删除的用户在appointments
表中具有关联的记录。 您有 2 个选择:
首先使用单独的delete
语句从约会表中删除关联的记录。
将删除级联选项添加到appointments_user_id_foreign
_用户appointments_user_id_foreign
外键。 当您删除用户的记录时,此选项将自动从appointments
表中删除所有关联记录,以便删除用户。
修改后的 fk 语句如下所示:
... ADD CONSTRAINT `appointments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE;
@Nebster 提出的解决方案在技术上删除了错误消息,但也允许在appointments
表中拥有孤立记录 - 与已删除用户相关的appointments
。 因此,在我看来,删除外键不是一个明智的选择。
SET FOREIGN_KEY_CHECKS=0;
– 禁用它们
SET FOREIGN_KEY_CHECKS=1;
– 重新启用它们
似乎您在约会表中的外键具有删除时:限制选项。 将约束约会_user_id_foreign 更改为On delete: Cascade ,您应该能够在保留外键的同时删除用户。
ALTER TABLE "appointments" DROP FOREIGN KEY "appointments_user_id_foreign";
ALTER TABLE "appointments" ADD CONSTRAINT "appointments_user_id_foreign" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE;
您不能简单地从表 users 中删除用户。 它被约会表引用为外键索引。 我认为当一个用户被删除时,他的所有引用都应该从其他表中删除是很公平的。
对于您的场景,您可以改进您的数据库设计。 您可以将约会表中的外键列设为可选。 所以如果用户被删除,相应记录的user_id 可以设置为NULL。 但是为那些不再存在于系统中的用户存储约会是没有意义的。 另一种方法是在删除该用户之前,从约会表中删除所有对应的引用,然后从用户表中删除引用
如果您想要临时解决方案,请尝试以下操作
SET FOREIGN_KEY_CHECKS=OFF; -- to disable foreign key checks
//drop the table and then
SET FOREIGN_KEY_CHECKS=ON; -- to re-enable foreign key checks
有几个选项,但最终只有两个主要选项:
on delete cascade
意味着当用户被删除时,与该用户相关的约会也应该按照Shadow 的建议删除(第二点)on delete set null
意味着当用户被删除时,与该用户相关的约会 user_id 应设置为 null(尽管您必须将user_id int(10) UNSIGNED NOT NULL
更改为user_id int(10) UNSIGNED DEFAULT NULL
应该选择哪种解决方案?
假设这是一个诊所,诊所收到用户的请求,要求将他从数据库中删除。 那很好,一直发生。 但是诊所仍然希望保留数据库中所有约会的历史记录。 在这种情况下,您将使用解决方案编号 2。这样,当用户被删除时,您仍将在数据库中拥有约会,但 user_id 将为空,因为该用户不再存在。 如果诊所不关心约会的历史,那么您可以使用第一解决方案。 虽然也可以将用户字段设置为 null 而不是完全删除行,在这种情况下,您将使用第一号解决方案,因为实际上永远不需要完全删除用户记录。
我有同样的例外。 我可以通过在我的父类中更改为CascadeType.DETACH
来解决这个问题。
所以在你的情况下它会是
public class AppointmentsEntity {
@JoinColumn(name = "USER_ID", referencedColumnName = "ID")
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.DETACH)
private User user;
}
顺便说一句:您最好对数据库表名使用单数名称。
实际上,这取决于您的数据模型,您应该问您子实体是否应该/可以在没有父实体的情况下存在的问题。 这回答了您如何对待子实体。
我通过 Typeorm MysQL 找到了该问题的解决方案:您可以将“createForeignKeyConstraints”设置为 FALSE。
@OneToOne(type => Task, {
cascade: true, onDelete: 'CASCADE', createForeignKeyConstraints: false
})
@JoinColumn()
taskDetails: Task
SET FOREIGN_KEY_CHECKS=OFF; -- to disable foreign key checks
//drop the table and then
SET FOREIGN_KEY_CHECKS=ON; -- to re-enable foreign key checks
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.