MySQL でこれを行う場合:
UPDATE `client_therapist` SET `therapist_id` = 3 LIMIT 1 ;
次のエラーが表示されます。
#1451 - Cannot delete or update a parent row: a foreign key constraint fails (`test_structure`.`client_group`, CONSTRAINT `client_group_therapist_id` FOREIGN KEY (`therapist_id`) REFERENCES `client_therapist` (`therapist_id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
私はいたるところを検索し、StackOverflowでここで尋ねられた外部キーの質問のいくつかを読みました...役に立ちませんでした。この時点では、外部キーを完全に理解しているとは思いません。
これが私のDB構造です:
問題の原因となっている外部キーは client_group テーブルにあります。私が理解しているのは、「行が追加されるたびに、therapist_id は client_therapist テーブルの therapist_id と一致する必要がある」ということです。
これを入力しただけで、client_group が追加されると、client_therapist テーブルの特定の行にバインドされる可能性があるという問題の一部に気付きました。したがって、その client_therapist 行を更新しようとすると、びっくりします。だから私は私の質問だと思います - どうすればこれを回避できますか? client_therapist テーブルの特定の行で therapist_id を更新する必要がありますが、client_group テーブルに行がある限り更新できないようです。
ここにいくつかのダミー情報を含む私のテーブルがあります:
CREATE SCHEMA IF NOT EXISTS `test_structure` DEFAULT CHARACTER SET utf8 ;
USE `test_structure` ;
-- -----------------------------------------------------
-- Table `test_structure`.`user`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `test_structure`.`user` (
`user_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
`email` VARCHAR(80) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT NULL ,
`password` VARCHAR(40) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT NULL,
`display_name` VARCHAR(60) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NULL DEFAULT NULL ,
`first_name` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT NULL ,
`last_name` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT NULL ,
`street_address` VARCHAR(120) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NULL DEFAULT NULL ,
`city` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NULL DEFAULT NULL ,
`state` CHAR(2) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NULL DEFAULT NULL ,
`zip` VARCHAR(10) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NULL DEFAULT NULL ,
`work_phone` VARCHAR(20) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NULL DEFAULT NULL ,
`cell_phone` VARCHAR(20) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NULL DEFAULT NULL ,
`home_phone` VARCHAR(20) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NULL DEFAULT NULL ,
`date_created` TIMESTAMP NULL DEFAULT NULL ,
`expired` TINYINT(1) NOT NULL DEFAULT '0' ,
`date_last_login` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ,
`login_count` INT(10) UNSIGNED NULL DEFAULT '0' ,
PRIMARY KEY (`user_id`) ,
UNIQUE INDEX `email` (`email` ASC) )
ENGINE = InnoDB
AUTO_INCREMENT = 0
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci,
COMMENT = 'Users table. All Therapists, Clients, Admins and others wil' ;
-- -----------------------------------------------------
-- Table `test_structure`.`client_therapist`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `test_structure`.`client_therapist` (
`client_therapist_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
`client_id` INT(10) UNSIGNED NOT NULL ,
`therapist_id` INT(10) UNSIGNED NOT NULL ,
`start_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`end_date` TIMESTAMP NULL DEFAULT NULL ,
`therapist_approval` TINYINT(1) NOT NULL DEFAULT '0' ,
`date_client_agreed_to_terms` TIMESTAMP NULL DEFAULT NULL ,
PRIMARY KEY (`client_therapist_id`) ,
INDEX `client_therapist_client_id` (`client_id` ASC) ,
INDEX `client_therapist_therapist_id` (`therapist_id` ASC) ,
CONSTRAINT `client_therapist_client_id`
FOREIGN KEY (`client_id` )
REFERENCES `test_structure`.`user` (`user_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `client_therapist_therapist_id`
FOREIGN KEY (`therapist_id` )
REFERENCES `test_structure`.`user` (`user_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
AUTO_INCREMENT = 0
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci,
COMMENT = 'This defines the relationship between a client and therapist' ;
-- -----------------------------------------------------
-- Table `test_structure`.`client_group`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `test_structure`.`client_group` (
`client_group_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
`therapist_id` INT(10) UNSIGNED NOT NULL ,
`title` VARCHAR(128) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT NULL ,
`description` VARCHAR(255) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NULL DEFAULT NULL ,
`date_added` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ,
PRIMARY KEY (`client_group_id`) ,
INDEX `client_group_therapist_id` (`therapist_id` ASC) ,
CONSTRAINT `client_group_therapist_id`
FOREIGN KEY (`therapist_id` )
REFERENCES `test_structure`.`client_therapist` (`therapist_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
AUTO_INCREMENT = 0
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;
-- -----------------------------------------------------
-- Table `test_structure`.`client_group_member`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `test_structure`.`client_group_member` (
`client_group_member_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
`client_group_id` INT(10) UNSIGNED NOT NULL ,
`client_id` INT(10) UNSIGNED NOT NULL ,
PRIMARY KEY (`client_group_member_id`) ,
INDEX `client_group_id` (`client_group_id` ASC) ,
INDEX `client_group_member_id` (`client_id` ASC) ,
CONSTRAINT `client_group_id`
FOREIGN KEY (`client_group_id` )
REFERENCES `test_structure`.`client_group` (`client_group_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `client_group_member_id`
FOREIGN KEY (`client_id` )
REFERENCES `test_structure`.`client_therapist` (`client_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
AUTO_INCREMENT = 0
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;
-- -----------------------------------------------------
-- INSERT TEST DATA
-- -----------------------------------------------------
INSERT INTO `test_structure`.`user` (`user_id`, `email`, `password`, `display_name`, `first_name`, `last_name`, `street_address`, `city`, `state`, `zip`, `work_phone`, `cell_phone`, `home_phone`, `date_created`, `expired`, `date_last_login`, `login_count`) VALUES (NULL, 'dr@dr.com', SHA1('12345'), 'Dr. Test', 'Dr.', 'Test', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NOW(), '0', CURRENT_TIMESTAMP, '0');
SET @therapist_id = LAST_INSERT_ID();
INSERT INTO `test_structure`.`user` (`user_id`, `email`, `password`, `display_name`, `first_name`, `last_name`, `street_address`, `city`, `state`, `zip`, `work_phone`, `cell_phone`, `home_phone`, `date_created`, `expired`, `date_last_login`, `login_count`) VALUES (NULL, 'client@client.com', '12345', 'Client', 'Client', 'Client', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NOW(), '0', CURRENT_TIMESTAMP, '0');
SET @client_id = LAST_INSERT_ID();
INSERT INTO `test_structure`.`client_therapist` (`client_therapist_id`, `client_id`, `therapist_id`, `start_date`, `end_date`, `therapist_approval`, `date_client_agreed_to_terms`) VALUES (NULL, @client_id, @therapist_id, CURRENT_TIMESTAMP, NOW(), '0', NOW());
INSERT INTO `test_structure`.`client_group` (`client_group_id`, `therapist_id`, `title`, `description`, `date_added`) VALUES (NULL, @therapist_id, 'Test', NULL, CURRENT_TIMESTAMP);
SET @group_id = LAST_INSERT_ID();
INSERT INTO `test_structure`.`client_group_member` (`client_group_member_id`, `client_group_id`, `client_id`) VALUES (NULL, @group_id, @client_id);
次に、次のコードを実行して、foreign_key の問題を確認します。
INSERT INTO `test_structure`.`user` (`user_id`, `email`, `password`, `display_name`, `first_name`, `last_name`, `street_address`, `city`, `state`, `zip`, `work_phone`, `cell_phone`, `home_phone`, `date_created`, `expired`, `date_last_login`, `login_count`) VALUES (NULL, 'newdr@newdr.com', SHA1('12345'), 'New Dr', 'Dr.', 'New', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NOW(), '0', CURRENT_TIMESTAMP, '0');
SET @new_therapist_id = LAST_INSERT_ID();
UPDATE `test_structure`.`client_therapist` SET `therapist_id` = @new_therapist_id LIMIT 1;
すべてのヘルプ/指示/ガイダンスは大歓迎です!
アップデート
私が抱えている問題は、client_group テーブルの therapist_id が user テーブルではなく client_therapist テーブルの therapist_id にバインドされているためです。その therapist_id は client_therapist および client_group テーブルに複数回存在できますが、user テーブルには 1 回しか存在できません。したがって、client_group テーブルにまだその therapist_id を参照している行が 1 つある限り、client_therapist テーブルのその列を更新することはできません。
各テーブルのプライマリ ID を参照する外部キーを保持する方がよいため、client_therapist テーブルではなく、user テーブルに therapist_id をバインドする必要がありました (本当ですか?)。
今、テーブルの外部キーを削除/編集/更新する方法を学ばなければなりません... :)