외래 키(Foriegn Key)

솔트커피·2022년 9월 19일
0

두 테이블을 서로 연결하는데 사용되는 키

외래 키가 포함된 테이블을 자식 테이블이라고 하고 외래키 값을 제공하는 테이블을 부모 테이블이라 한다

CREATE TABLE `tb_user`
(
    id INT(11), 
    name VARCHAR(100),
    primary key(id)
);

CREATE TABLE `tb_post`
(
    id INT(11),
    title VARCHAR(100),
    content VARCHAR(255),
    writer_id INT(11),
    primary key(id)
);
  • 여기서 tb_postwriter_id 컬럼이 tb_user의 id를 가리키는 외래키 컬럼
    • tb_user는 자식 테이블, tb_post 부모 테이블
  • 따로 외래키 설정을 하지 않고 그냥 그때마다 조인해서 써도 사용에는 문제 없음
    • 다만 이럴 경우 tb_user의 값이 갑자기 삭제되거나 변경되어도 직관적으로 파악하고 대응할 수 없다는 단점이 있음
    • 게다가 외래 키 값으로 존재하지 않는 이상한 키 값을 삽입하는 것도 막을 수 없음

사용시 주의 사항

  • 참조 무결성 제약 조건 - 외래 키 값은 NULL이거나 부모 테이블의 기본 키 값과 동일해야 함
  • 부모 테이블의 기본 키, 고유 키를 외래 키로 지정할 수 있음
    • 부모 테이블의 기본 키 고유 키가 여러 개의 컬럼으로 이루어져 있다면, 그 컬럼들을 원하는 개수만큼 묶어서 외래키로 지정할 수 있음
CREATE TABLE `parent` (
	`id1` INT(11) NOT NULL,
	`id2` INT(11) NOT NULL,
	`id3` INT(11) NOT NULL,
	`uk1` INT(11) NOT NULL,
	`uk2` INT(11) NOT NULL,
	`uk3` INT(11) NOT NULL,
	PRIMARY KEY (`id1`, `id2`, `id3`),
	UNIQUE KEY (`uk1`, `uk2`, `uk3`)
);

CREATE TABLE `child` (
	`id` INT(11) NOT NULL,
	`id1` INT(11) NOT NULL,
	`id2` INT(11) NOT NULL,
	`uk1` INT(11) NOT NULL,
	`uk2` INT(11) NOT NULL,
	PRIMARY KEY (`id`),
	FOREIGN KEY (`id1`, `id2`) REFERENCES `parent` (`id1`, `id2`), 
	-- 부모 테이블의 PK는 3개의 키로 이루어져 있으나, 자식 테이블에서는 그 중 2개만 외래 키로 사용
	FOREIGN KEY (`uk1`, `uk2`) REFERENCES `parent` (`uk1`, `uk2`)
	-- 부모 테이블의 UK는 3개의 키로 이루어져 있으나, 자식 테이블에서는 그 중 2개만 외래 키로 사용
)

ON DELETE 속성

외래 키로 삭제에 대한 제약이나 트리거를 걸어주는 기능
예를 들어, tb_user 값을 delete할 때, 해당 값을 참조하는 tb_post가 있을 경우 어떻게 반응할 지 결정하는 것

속성설명
CASCADEtb_user의 데이터가 삭제되면 해당 값을 참조하는 tb_post의 데이터도 함께 삭제
SET NULLwriter_id를 null로 설정
SET DEFAULTwriter_id를 디폴트 값으로 설정
RESTRICTtb_user의 삭제를 막음
NO ACTION아무런 조치도 취하지 않음 (기본값)

ON UPDATE 속성

외래 키로 업데이트에 대한 제약이나 트리거를 걸어주는 기능
tb_user의 id 값이 바뀔 경우에 rb_post의 writer_id 값을 어떻게 할지 지정해주는 기능

속성설명
CASCADEtb_user의 데이터가 변경되면 tb_post의 데이터도 함께 같은 값으로 변경
SET NULLwriter_id를 null로 설정
SET DEFAULTwriter_id를 디폴트 값으로 설정
RESTRICTtb_user의 업데이트를 막음
NO ACTION아무런 조치도 취하지 않음 (기본값)

0개의 댓글