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;

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

ᕕ( ᐛ )ᕗ
로그인이 필요합니다

작성한 답변에 다른 개발자들이 댓글을 작성하거나 댓글에 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.