[mysql] MySQL 오류 1452-자식 행을 추가하거나 업데이트 할 수 없음 : 외래 키 제약 조건이 실패 함

이상한 문제가 있습니다. 다른 테이블을 참조하는 테이블에 외래 키를 추가하려고하는데 어떤 이유로 실패합니다. MySQL에 대한 나의 제한된 지식으로, 아마도 의심의 여지가있는 유일한 것은 내가 참조하려고하는 것을 참조하는 다른 테이블에 외래 키가 있다는 것입니다.

SHOW CREATE TABLE두 테이블 모두 에서 쿼리를 수행 sourcecodes_tags했으며 외래 키 sourcecodes가있는 테이블이며 참조 테이블입니다.

CREATE TABLE `sourcecodes` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `user_id` int(11) unsigned NOT NULL,
 `language_id` int(11) unsigned NOT NULL,
 `category_id` int(11) unsigned NOT NULL,
 `title` varchar(40) CHARACTER SET utf8 NOT NULL,
 `description` text CHARACTER SET utf8 NOT NULL,
 `views` int(11) unsigned NOT NULL,
 `downloads` int(11) unsigned NOT NULL,
 `time_posted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`),
 KEY `user_id` (`user_id`),
 KEY `language_id` (`language_id`),
 KEY `category_id` (`category_id`),
 CONSTRAINT `sourcecodes_ibfk_3` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `sourcecodes_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `sourcecodes_ibfk_2` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

CREATE TABLE `sourcecodes_tags` (
 `sourcecode_id` int(11) unsigned NOT NULL,
 `tag_id` int(11) unsigned NOT NULL,
 KEY `sourcecode_id` (`sourcecode_id`),
 KEY `tag_id` (`tag_id`),
 CONSTRAINT `sourcecodes_tags_ibfk_1` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1

이것은 오류를 생성하는 코드입니다.

ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE



답변

sourcecodes_tags테이블에 sourcecode_id더 이상 존재하지 않는 값이 테이블에 포함되어 있을 가능성이 큽니다 sourcecodes. 먼저 제거해야합니다.

해당 ID를 찾을 수있는 쿼리는 다음과 같습니다.

SELECT DISTINCT sourcecode_id FROM
   sourcecodes_tags tags LEFT JOIN sourcecodes sc ON tags.sourcecode_id=sc.id
WHERE sc.id IS NULL;


답변

내 MySQL 데이터베이스와 동일한 문제가 있었지만 마침내 나를 위해 일한 솔루션을 얻었습니다.
내 테이블에서는 mysql 관점에서 모든 것이 좋았습니다 (두 테이블 모두 InnoDB 엔진을 사용해야하고 각 열의 데이터 유형은 외래 키 제약 조건에 참여하는 동일한 유형이어야합니다).
내가 한 유일한 방법은 외래 키 검사를 비활성화하고 나중에 외래 키 작업을 수행 한 후 활성화했습니다.
내가 취한 단계 :

SET foreign_key_checks = 0;
alter table tblUsedDestination add constraint f_operatorId foreign key(iOperatorId) references tblOperators (iOperatorId); Query
OK, 8 rows affected (0.23 sec) Records: 8  Duplicates: 0  Warnings: 0
SET foreign_key_checks = 1;


답변

NOT IN구속 조건이 구속 되는 위치를 찾는 데 사용하십시오 .

SELECT column FROM table WHERE column NOT IN
(SELECT intended_foreign_key FROM another_table)

보다 구체적으로 :

SELECT sourcecode_id FROM sourcecodes_tags WHERE sourcecode_id NOT IN
(SELECT id FROM sourcecodes)

편집 : INNOT IN연산자는 훨씬 빠르게보다 알려져있다 JOIN뿐만 아니라 훨씬 더 쉽게 구조, 반복에, 운영자.


답변

테이블을 자른 다음 FK 제약 조건을 추가해보십시오 .

이 솔루션이 약간 어색하지만 100 % 작동한다는 것을 알고 있습니다. 그러나 이것이 문제를 해결하기위한 이상적인 솔루션은 아니지만 동의하는 데 동의합니다.


답변

나 에게이 문제는 조금 다르고 확인하고 해결하기가 매우 쉽습니다.

테이블의 BOTH가 모두 InnoDB인지 확인해야합니다. 테이블 중 하나, 즉 참조 테이블이 MyISAM이면 제약 조건이 실패합니다.

    SHOW TABLE STATUS WHERE Name =  't1';

    ALTER TABLE t1 ENGINE=InnoDB;


답변

child.column의 값이 이미 0이고 parent.id 값이 0이 아닌 경우 외래 키를 parent.id에서 child.column으로 설정할 때 발생합니다.

각 child.column이 NULL이거나 parent.id에 존재하는 값을 가지고 있는지 확인해야합니다.

그리고 지금 내가 쓴 진술을 읽었으므로, 그것이 그가 확인하고있는 것입니다.


답변

나는 오늘 같은 문제가 있었다. 나는 네 가지를 테스트했는데 그중 일부는 이미 여기에 언급되어 있습니다.

  1. 자식 열에 부모 열에 존재하지 않는 값이 있습니까 (자식 열이 Null을 허용하는 경우 NULL 제외)

  2. 자식 및 부모 열의 데이터 형식이 동일합니까?

  3. 참조하는 상위 열에 색인이 있습니까? MySQL은 성능상의 이유로 이것을 필요로하는 것 같습니다 ( http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html )

  4. 그리고 이것은 나를 위해 그것을 해결했습니다. 두 테이블이 동일한 데이터 정렬을 가지고 있습니까?

UTF-8로 된 테이블 하나와 등거리에있는 다른 테이블이있었습니다. 작동하지 않았습니다. iso-table을 UTF-8 데이터 정렬로 변경 한 후 문제없이 제약 조건을 추가 할 수 있습니다. 필자의 경우 phpMyAdmin은 외래 키 제약 조건을 만들기위한 드롭 다운에서 아이 테이블을 아이 인코딩으로 표시하지 않았습니다.