親の行を削除または更新できません: 外部キー制約に失敗しました - 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つのオプションがあります:

1.別のdeleteステートメントで、まずappointmentsテーブルから関連レコードを削除する。

2.appointments_user_id_foreignの外部キーに [on delete cascade][1] オプションを追加します。このオプションは、削除するユーザーのレコードを削除すると、そのユーザーのappointments`テーブルから関連するレコードが自動的に削除されます。

修正したfk文は次のようになります:

... ADD CONSTRAINT `appointments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE;

Nebsterが提案した解決策は、技術的にはエラーメッセージを取り除きますが、appointmentsテーブルの中に、削除されたユーザーに関連する予定という孤児レコードを持つことも可能になります。したがって、外部キーを削除することは賢明な選択肢とは言えないと私は思います。

解説 (0)

SET FOREIGN_KEY_CHECKS = 0;& ndash;それらを無効にします。

SET FOREIGN_KEY_CHECKS = 1;& ndash;それらを再有効にします。

解説 (1)

Appointmentsテーブルの外部キーにOn delete:Restrict オプションを使用しているようです。制約の appointments_user_id_foreignOn delete:Cascade に変更すると、Foreign keyを保持したままUsersを削除できるはずです。

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;
解説 (1)

usersテーブルからユーザーを単純に削除することはできません。それは、apointmentsテーブルから外部キーインデックスとして参照されています。ユーザーを削除した場合、他のテーブルからその参照先をすべて削除するのが妥当だと思います。

あなたのシナリオでは、データベースの設計を改善することができます。予約テーブルの外部キーカラムをオプションにすることができます。もしユーザーが削除された場合、対応するレコードのuser_idはNULLに設定することができます。しかし、これでは、もう存在しないユーザーの予定を保存する意味がありません。別の方法としては、そのユーザーを削除する前に、そのユーザーに対応するすべての参照をappointmentsテーブルから削除し、その後、usersテーブルから参照を削除することもできます。

解説 (0)

一時的な解決策が必要な場合は、以下を試してください。

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
解説 (0)