2014-09-04 4 views
2

복합 기본 키의 일부만 참조하는 외래 키가있을 때 상위 테이블에서 삭제하는 방법 ?? 난의 MySQL 5.6.2mysql 복합 기본 키의 일부만 참조하는 외래 키

사용하고

저는 기본 키 itemsup가 기본 키 항목 (A, B) 및 상품 공급 업체가 하나 개의 항목 테이블 (A, X를, Y)있다. 난 = itemsup (A) 항목 (A)와 같은 참조를 제공해야
전 항목에서 삭제
(부모) 표는 오류 얻을 : 1451 - 삭제하거나 부모 행 업데이트 할 수 없습니다 : 외래 키 제약 조건이

실패를

내 테이블 구조는 다음과 같습니다.

CREATE TABLE IF NOT EXISTS ITEM (/* parent */ 
    ITEMID INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ITEM ID', 
    MCA ENUM('A','C','M','X') NOT NULL , 
    ITEMNAME VARCHAR(100) NOT NULL COMMENT 'NAME OF ITEM', 
    PRIMARY KEY (ITEMID, MCA) 
) 
ENGINE = InnoDB; 

CREATE TABLE IF NOT EXISTS ITEMSUP (/* child */ 
    ITEMID INT UNSIGNED NOT NULL, 
    SUPID INT UNSIGNED NOT NULL, 
    MCA ENUM('A','C','M','X') NOT NULL , 
    PRIMARY KEY (ITEMID, SUPID, MCA), 
    CONSTRAINT FK_ITEMSUP_ITEM1 
    FOREIGN KEY (ITEMID) 
    REFERENCES ITEM (ITEMID) 
    ON DELETE NO ACTION 
    ON UPDATE CASCADE 
) 
ENGINE = InnoDB; 

INSERT INTO ITEM (ITEMID, MCA, ITEMNAME) VALUES (1,'A', 'ONE A'); 
INSERT INTO ITEM (ITEMID, MCA, ITEMNAME) VALUES (1,'M', 'ONE M'); 
INSERT INTO ITEMSUP(ITEMID, SUPID, MCA) VALUES(1,1,'X'); 
/* below is not working */ 
DELETE FROM ITEM WHERE ITEMID = 1 AND MCA ='A'; 

http://sqlfiddle.com/#!9/fb961/1

내가 하나 개의 솔루션을 찾았지만 확실하지 않은 것이 옳고 그름.

SET FOREIGN_KEY_CHECKS = 0; 
DELETE FROM ITEM WHERE ITEMID =1 AND MCA ='A'; 
SET FOREIGN_KEY_CHECKS = 1; 
+0

(ITEMID, MCA) 대신 FK (ITEMID)가있는 이유는 무엇입니까? – philipxy

답변

0

왜 오류 메시지가?

표준 SQL에서 참조 된 열 집합은 UNIQUE NON NULL 또는 PRIMARY KEY로 선언되어야합니다.

불행히도 MySQL은 참조 집합이 고유 한 null이 아니도록 허용합니다. the MySQL manual re Using FOREIGN KEY Constraints에서 :

그러나, 시스템이 참조 열은 고유 또는 NOT NULL로 선언 요구 사항을 적용하지 않습니다. 외래 키 또는 NULL 값을 포함하는 키에 대한 참조는 UPDATE 또는 DELETE CASCADE와 같은 작업에 대해 잘 정의 된 이 아닙니다. 은 UNIQUE ( PRIMARY 포함) 및 NULL이 아닌 키만 참조하는 외래 키를 사용하도록 권장됩니다. 특히 from the MySQL manual re InnoDB and FOREIGN KEY Constraints에서

: 동일한 참조 키 값이 상위 테이블의 여러 행이 경우 이노 외부 키 확인 작용

경우와 동일한와 다른 부모 행 키 값이 존재하지 않습니다. 예를 들어, RESTRICT 유형 제약 조건을 정의한 경우 자식 행 에 부모 행이 여러 개있는 경우 InnoDB는 해당 부모 행 중 하나 인 의 삭제를 허용하지 않습니다.

이 때문에 오류가 발생합니다. ITEM에 같은 행이있는 여러 ITEMID 행이 있습니다. 항목 ID는 항목에 & null이 아닌 고유 한 경우

관계형 및 표준 SQL 개념의 관점에서 말하기 설계

을 적응, 하나는 ITEMSUP에 FOREIGN KEY (항목 ID) 참조 항목 (항목 ID)를 가질 수있다.ITEMID는 ITEM에서 고유하지 않기 때문에 외래 키를 원할 수 없습니다. (비공식적으로 ITEMID는 ITEM의 "키"가 아니므로 ITEMSUP에서 외국의 "키"가 될 수 없습니다.)

모든 ITEMSUP ITEMID를 ITEM ITEMID 값으로 설정하려면 다음 중 하나의 ITEMID PRIMARY KEY 새 테이블을 가져 와서 ITEMID 및 ITEMSUP (현재 ITEMSUP 외래 키 대신)에서 FOREIGN KEY를 가져옵니다.

어쩌면 'X'당신의 디자인 개선은 더 MCA 없음을 나타내는 "널 (null)"의 종류와 일치하는 MCS있을하지 않습니다. 그리고/또는 ITEMSUP ITEMID의 MCA는 그것이 'X'가 아니거나 'X'일 때 ITEM MCA와 일치해야합니다. 어쩌면 ITEM에 ITEMID 당 하나의 MCA 만 있으면됩니다.이 경우 ITEMID PRIMARY KEY 및 MCA NOT NULL UNIQUE를 갖도록 ITEM을 변경하십시오. 어쩌면 ITEM 여러 항목 ID-MCA 쌍을 가질 수 있지만 ITEMSUP는 다른 ITEMSUP 외래 키가있는 경우에 그 사람, 할 수 있습니다 :

FOREIGN KEY (ITEMID,MCA) REFERENCES ITEM (ITEMID,MCA) 

그러나 이것은 당신의 SQLFiddle에 의해 침해 될 것이다 :

INSERT INTO ITEMSUP(ITEMID, SUPID, MCA) VALUES(1,1,'X'); 

을 ITEM에 상응하는 서브 로우 (1, 'X')가 없기 때문입니다.

"maybe"가 true이면 테이블에 대한 제약 조건을 제대로 설명하지 않은 것입니다. 필요한 제약 조건이 무엇인지 정확히 확인하지 않으면 설계가 어떻게되어야하는지에 대해 적절한 조언을 드릴 수 없습니다.