2013-04-21 1 views
1

실패 :또 다른 외부 키 문제 - # 1451 - 삭제하거나 부모 행을 업데이트 할 수 없습니다 : 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에 대해 묻는 외래 키 질문을 읽었습니다 ... 아무 소용이 없습니다. 나는이 시점에서 외래 키를 완전히 이해하고 있다고 생각하지 않는다. 문제를 일으키는 것은 client_group이라는 테이블에 Database structure diagram showing foreign keys

외부 키 :

여기 내 DB 구조입니다. "행이 추가 될 때마다 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, '[email protected]', 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, '[email protected]', '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, '[email protected]', 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; 

이 모든 도움 /지도 /지도가 많이 감사를!

UPDATE

client_group이라는 테이블에서 therapist_id을하여 client_therapist 테이블에 therapist_id 아닌 사용자 테이블에 바인딩되어 있기 때문에 나는 데 문제가 있습니다. 그 therapist_id는 client_therapist 및 client_group 테이블에 여러 번 존재할 수 있지만 user 테이블에는 한 번만 존재할 수 있으므로 client_therapist 테이블의 해당 열을 업데이트 할 수는 있지만 여전히 해당 therapist_id를 참조하는 client_group 테이블의 단일 행이 있어야합니다.

필자가 수행해야 할 작업은 각 테이블의 기본 ID를 참조하는 외래 키를 유지하는 것이 더 좋기 때문에 therapist_id를 user 테이블에 바인딩하고 client_therapist 테이블에 바인딩하지 않습니다 (사실입니까?).

는 지금은

답변

2

: 당신은 ON UPDATE CASCADE 옵션으로 선언 된 외래 키가 필요합니다 ... 꼭 테이블에/편집/업데이트 외래 키를 제거하는 방법을 학습했습니다. 그런 다음

ALTER TABLE client_group drop FOREIGN KEY `client_group_therapist_id`, 
    ADD FOREIGN KEY `client_group_therapist_id` (`therapist_id`) 
    REFERENCES `client_therapist` (`therapist_id`) ON DELETE NO ACTION ON UPDATE CASCADE; 

당신이 client_therapist.therapist_id의 값을 변경하면 자동으로 client_group.therapist_id의 값을 업데이트합니다 :

여기에 제거하고 테이블에 외래 키를 추가하는 방법의 예입니다.

이 변경 사항은 동시 및 원 자성입니다. 즉, 동시에 실행중인 다른 쿼리는 한 테이블에서 변경된 데이터를 볼 수는 있지만 다른 테이블에서는 변경되지 않습니다.

+0

감사합니다. 당신은 내 논리의 실수를 깨닫게했습니다. 사실 client_therapist 테이블을 업데이트 할 때 client_group이 항상 업데이트되기를 원하지 않습니다. 그래서 나는 외래 키가 잘못된 곳으로 간다. 내 실수를 설명하는 위의 내 질문을 편집합니다. 도움에 다시 한번 감사드립니다. – Buck

+0

위의 예제 코드를 사용하여 외래 키를 제거하고 추가하는 방법을 안내 할 수 있습니다. –

+0

예, 매력처럼 작동했습니다. 감사! – Buck

0

외래 키가 다른 테이블의 고유하지 않은 열을 참조하고 있으므로 올바르지 않습니다.

각 테이블의 기본 ID를 참조하는 외래 키를 유지하는 것이 좋기 때문에 필자가 수행해야하는 작업은 클라이언트 테이블에있는 therapist_id와 클라이언트 테이블에 바인딩되어 있습니다.

ALTER TABLE client_group drop FOREIGN KEY `client_group_therapist_id`, 
ADD FOREIGN KEY `client_group_therapist_id` (`therapist_id`) 
REFERENCES `user` (`user_id`) ON DELETE NO ACTION ON UPDATE NO ACTION; 
관련 문제