데이터베이스 외래 키
더 많은 작업
외래 키(Foreign Key, FK)는 한 릴레이션의 속성(또는 속성 집합) 값이 다른 릴레이션, 또는 같은 릴레이션의 기본 키 값으로 반드시 존재하도록 묶어 두는 속성으로, 두 릴레이션 사이의 참조 관계를 나타낸다.
외래 키를 가진 쪽을 참조하는 릴레이션(referencing relation, 자식), 외래 키가 가리키는 쪽을 참조되는 릴레이션(referenced relation, 부모)이라 한다. Silberschatz 는 속성 집합 A 가 릴레이션 S 의 기본 키이고, R 에 나타나는 A 의 값이 모두 S 에도 나타날 때 A 를 R 의 외래 키라고 정의한다.[1] 외래 키가 지키게 하는 규칙이 참조 무결성이고, 부모 쪽 행이 지워지거나 키가 바뀔 때 자식을 어떻게 할지는 참조 동작(CASCADE, SET NULL, SET DEFAULT, RESTRICT)으로 정한다.
외래 키는 후보 키나 기본 키처럼 튜플을 식별하는 키가 아니다. 같은 값이 여러 튜플에 되풀이될 수 있고(일대다 관계), 값이 비어 있을 수도 있다. 이름에 '키'가 붙은 것은 다른 릴레이션의 키를 가져다 쓰기 때문이다.
- 여러 개를 둘 수 있다. 한 릴레이션에 외래 키 개수의 제한은 없다. 주문 항목 릴레이션이 주문과 상품을 각각 참조하는 것처럼, 다대다 관계를 풀어 놓은 릴레이션은 외래 키를 둘 이상 갖는다.[2]
- 자기 자신을 참조할 수 있다. 직원(사번, 이름, 상사사번)의 상사사번이 같은 릴레이션의 사번을 가리키는 것처럼, 참조되는 릴레이션이 자기 자신일 수도 있다(자기 참조 외래 키). 트리·계층 구조를 표현할 때 쓴다.[2] 이런 릴레이션을 조회할 때는 셀프 조인을 쓴다.
- NULL 을 허용할 수도, 막을 수도 있다. 기본적으로 외래 키 열 가운데 하나라도 NULL 이면 그 행은 참조 검사를 받지 않는다. 관계가 반드시 있어야 하면(필수 관계) 외래 키 열을 NOT NULL 로 선언한다.[2] 그래서 "외래 키는 NULL 을 가질 수 없다"도, "외래 키는 반드시 NULL 을 허용한다"도 틀린 말이고, 설계에 따라 NULL 을 갖지 않게 할 수 있다가 맞다.
- 참조되는 쪽은 기본 키(또는 UNIQUE 로 선언된 후보 키)여야 한다. SQL 에서 외래 키는 기본값으로 참조 릴레이션의 기본 키를 가리키고, 열 목록을 따로 적을 수도 있다.[1] PostgreSQL 은 참조되는 열이 기본 키이거나 UNIQUE 제약(또는 부분이 아닌 유일 인덱스)을 가진 열이어야 한다고 정한다.[2]
참조 무결성을 넓게 정의하면 "R 의 어떤 속성 값이 S 의 어떤 속성 값으로 존재해야 한다"는 조건이고, 이때 S 쪽 속성이 키일 필요는 없다. 그러나 DBMS 가 실제로 선언·검사해 주는 것은 참조되는 속성이 기본 키(또는 유일성이 보장된 후보 키)인 경우, 곧 외래 키 제약뿐이다. 참조 대상이 키가 아닌 일반 속성인 참조 조건은 외래 키로 선언할 수 없고, 트리거나 응용 프로그램으로 검사해야 한다. 데이터베이스 시스템이 참조된 속성이 기본 키일 때 참조 무결성 제약을 지원한다는 설명은 이 사정을 말한 것이다.
CREATE TABLE DEPT (
DNO INT PRIMARY KEY,
DNAME VARCHAR(20),
MGR_ENO INT);
CREATE TABLE EMP (
ENO INT PRIMARY KEY,
NAME VARCHAR(20) NOT NULL,
SUPER_ENO INT, -- NULL 허용: 상사가 없을 수 있다
DNO INT NOT NULL DEFAULT 1, -- NOT NULL: 반드시 부서에 속한다
FOREIGN KEY (SUPER_ENO) REFERENCES EMP(ENO) -- 자기 참조
ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY (DNO) REFERENCES DEPT(DNO) -- 두 번째 외래 키
ON DELETE SET DEFAULT ON UPDATE CASCADE);
EMP 에는 외래 키가 둘 있고, 그중 하나는 자기 자신을 참조한다. SUPER_ENO 는 NULL 을 허용하고 DNO 는 허용하지 않는다. SET DEFAULT 로 바뀐 값 1 도 DEPT 에 있는 부서번호여야 하며, 없으면 삭제가 실패한다.[2]
- ↑ 1.0 1.1 Silberschatz, Korth, Sudarshan, 「Database System Concepts 7th Edition - Chapter 4: Intermediate SQL」 강의 슬라이드, https://www.db-book.com/slides-dir/PDF-dir/ch4.pdf, 확인일: 2026-11-05.
- ↑ 2.0 2.1 2.2 2.3 2.4 「5.5. Constraints - Foreign Keys」, PostgreSQL Documentation, https://www.postgresql.org/docs/current/ddl-constraints.html, 확인일: 2026-11-05.