C

기본키(PK)와 외래키(FK) 차이 완벽 정리

2026-06-05 · Database · 기본키 · 외래키 · 설계

기본키(PK)와 외래키(FK) 차이란

기본키(PK)와 외래키(FK) 차이를 한마디로 정리하면 이렇습니다. 기본키는 한 테이블 안에서 각 행을 유일하게 구분하는 식별자이고, 외래키는 다른 테이블의 기본키를 가리켜 두 테이블을 연결하는 연결 고리입니다. 둘 다 "키"라는 이름이 붙지만 역할이 전혀 다릅니다. 이 글에서는 회원(users)과 주문(orders) 테이블로 두 개념의 차이를 정리합니다.

CREATE TABLE users (
  id    INT PRIMARY KEY,        -- 기본키(PK)
  name  VARCHAR(50) NOT NULL
);

CREATE TABLE orders (
  id       INT PRIMARY KEY,     -- orders의 기본키
  user_id  INT,                 -- users.id를 가리키는 외래키(FK)
  amount   INT,
  FOREIGN KEY (user_id) REFERENCES users(id)
);

기본키(Primary Key)의 특징

기본키는 행을 식별하는 대표 키입니다. 다음 세 가지 성질을 반드시 만족합니다.

  • 유일성(UNIQUE): 같은 값이 두 번 나올 수 없습니다.
  • NOT NULL: 비어 있을 수 없습니다.
  • 불변성 권장: 한번 정한 값은 잘 바꾸지 않습니다.

한 테이블에는 기본키가 하나뿐이며, 여러 컬럼을 묶어 복합키로 만들 수도 있습니다.

-- 복합 기본키 예시: (학번, 과목코드) 조합이 유일
CREATE TABLE enrollment (
  student_id INT,
  course_id  INT,
  PRIMARY KEY (student_id, course_id)
);

외래키(Foreign Key)의 특징

외래키는 다른 테이블(또는 같은 테이블)의 기본키를 참조합니다. 외래키의 핵심은 참조 무결성(referential integrity)으로, 존재하지 않는 값을 참조할 수 없게 막아 줍니다.

-- users에 없는 user_id로 주문을 넣으려 하면 거부됨
INSERT INTO orders (id, user_id, amount)
VALUES (1, 999, 5000);
-- 오류: user_id 999가 users.id에 없음 (외래키 위반)

외래키 덕분에 "회원이 없는 주문" 같은 고아 데이터가 생기지 않습니다. 외래키 값은 NULL일 수 있고(관계가 아직 없음을 의미), 기본키와 달리 같은 값이 여러 행에 중복될 수 있습니다(한 회원이 여러 주문을 가질 수 있으므로).

PK와 FK 비교표

구분기본키(PK)외래키(FK)
역할행을 유일하게 식별다른 테이블 참조(관계)
중복불가(유일)가능
NULL불가가능
개수테이블당 1개여러 개 가능

ON DELETE / ON UPDATE 옵션

참조 대상(부모 행)이 삭제되거나 변경될 때 외래키가 어떻게 반응할지 지정할 수 있습니다.

FOREIGN KEY (user_id) REFERENCES users(id)
  ON DELETE CASCADE   -- 회원 삭제 시 그 회원의 주문도 함께 삭제
  ON UPDATE CASCADE;  -- 회원 id 변경 시 주문의 user_id도 자동 변경

주요 옵션은 CASCADE(연쇄 적용), SET NULL(참조를 NULL로), RESTRICT/NO ACTION(참조가 있으면 삭제 거부)입니다. 데이터 성격에 맞게 신중히 선택해야 합니다.

실전 팁

기본키로는 의미 없는 자동 증가 정수(AUTO_INCREMENT 또는 시퀀스)나 UUID를 쓰는 것이 일반적입니다. 이메일·주민번호처럼 바뀔 수 있거나 민감한 값을 기본키로 쓰면 나중에 곤란해집니다. 또한 외래키 컬럼에는 인덱스를 두는 것이 좋습니다. 조인과 참조 검사 성능에 직접 영향을 주기 때문입니다(MySQL InnoDB는 외래키에 인덱스를 자동 생성합니다).

흔한 실수

1. 외래키 제약을 걸지 않고 운영하기. 제약이 없으면 애플리케이션 버그로 고아 데이터가 쌓여도 DB가 막아 주지 못합니다. 데이터 정합성이 중요하면 외래키를 명시하세요.

2. 부모 행을 지우려다 막히는 상황. 자식 행이 참조 중인 부모 행은 기본적으로 삭제되지 않습니다. 이때 무작정 제약을 빼지 말고, 자식 데이터를 먼저 처리하거나 ON DELETE 정책을 의도에 맞게 설정해야 합니다.

자주 묻는 질문

Q1. 기본키와 UNIQUE 제약은 같은 건가요?

비슷하지만 다릅니다. 둘 다 중복을 막지만, 기본키는 NULL을 허용하지 않고 테이블당 하나뿐입니다. UNIQUE 제약은 NULL을 허용하며 여러 개 둘 수 있습니다.

Q2. 외래키 없이 조인할 수 있나요?

가능합니다. 외래키 제약은 데이터 정합성을 강제하는 장치일 뿐, 조인 자체는 어떤 컬럼끼리든 ON 조건만 맞으면 됩니다. 다만 외래키가 있으면 관계가 명확해지고 무결성이 보장됩니다.

Q3. 복합키와 단일키 중 무엇을 써야 하나요?

가능하면 단순한 단일 대리키(surrogate key)를 권장합니다. 복합키는 조인·참조가 번거로워질 수 있어, 연결 테이블처럼 자연스러운 경우에 한정해 사용하는 편이 좋습니다.

기본키(PK)와 외래키(FK) 차이 완벽 정리 | CodeMaster 블로그 | CodeMaster