MySQL Foreign key 설정 시 오류가 납니다.


두 개의 테이블이 있는데요.

부모 테이블의 pk가 두 개일 경우에는 자식테이블 생성에 실패합니다.

방법이 있을까요?

부모 테이블의 no 의 경우 형식적인 시퀀스 값 입니다. 시퀀스 값을 포기해야하나요.

CREATE TABLE parent
(
  no INT AUTO_INCREMENT NOT NULL ,
  id INT NOT NULL,
  PRIMARY KEY(no, id)
) ENGINE = InnoDB;
CREATE TABLE child
(
  id INT NOT NULL,
  parent_id INT NOT NULL,
  PRIMARY KEY(id),
  FOREIGN KEY(parent_id) REFERENCES parent(id)
) ENGINE = InnoDB;
  • 2016년 08월 27일에 작성됨
    Software Engineer

조회수 189


1 답변


좋아요
2
싫어요
채택취소하기

복합키(복수개의 컬럼으로 구성된 키)를 주키로 사용한 테이블을 외래키로 참조할 경우, 해당 복합키 모두 참조해야만 합니다.

다음과 같이 고치면 됩니다.

CREATE TABLE child
(
  id INT NOT NULL,
  parent_no INT NOT NULL,
  parent_id INT NOT NULL,
  PRIMARY KEY(id),
  FOREIGN KEY(parent_no,parent_id) REFERENCES parent(no,id)
) ENGINE = InnoDB;

parent_no INT NOT NULL을 추가하고, 참조 Constraint 에도 FOREIGN KEY(parent_no,parent_id) REFERENCES parent(no,id)와 같이 변경해주세요.

수정답변

만약 child record가 parent 레코드 1개에 대해 참조하는 것이 아니라, 특정 부분키(복합키의 일부)만 참조하려고 한다면, 부분키에 대한 키(혹은 인덱스)를 생성해줘야만 합니다.

CREATE TABLE parent
(
  no INT AUTO_INCREMENT NOT NULL ,
  id INT NOT NULL,
  PRIMARY KEY(no, id),
  INDEX idx_parent_id(id)
) ENGINE = InnoDB;

혹은

CREATE TABLE parent
(
  no INT AUTO_INCREMENT NOT NULL ,
  id INT NOT NULL,
  PRIMARY KEY(no, id)
) ENGINE = InnoDB;
CREATE INDEX idx_parent_id ON parent(id);

위와 같이 parent 테이블의 id에 대한 단독 인덱스(키)를 생성해준 후, 질문해주신 다음의 child 테이블과 같이 생성하면 됩니다.

CREATE TABLE child
(
  id INT NOT NULL,
  parent_id INT NOT NULL,
  PRIMARY KEY(id),
  FOREIGN KEY(parent_id) REFERENCES parent(id)
) ENGINE = InnoDB;
  • 2016년 08월 28일에 작성됨
    리눅스(유닉스) 기반의 시스템에서 웹 서비스를 개발하고 있습니다.

  • 답변감사합니다. parent_no 는 child 테이블에서 필요 없는 데이터입니다만.. 어쩔 수 없이 복합키를 모두 참조해서 쌓는 방법밖에 없는 걸까요?     김선우   2016.8.28 10:47     
  • 연관(Relation)의 형태에 따라 다를 것 같습니다. parent 테이블의 정확하게 한개의 record를 child에서 참조하고자 한다면. 복합키를 모두 참조해야 합니다. 그렇지 않은 경우는 다르게 해결해야 합니다.(수정답변 참고)    허대영(Daeyoung Heo)   2016.8.28 11:08     
  • 감사합니다!     김선우   2016.8.29 08:59     

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close