1. 개요

관계형 데이터베이스의 테이블에는 비슷해 보이는 행이 여러 개 들어갈 수 있다. 이때 키(Key) 는 특정 행을 구별하거나, 다른 테이블의 행과 연결하는 데 쓰는 열 또는 열의 조합이다.

회원과 주문을 예로 키가 왜 필요한지 살펴보고, 후보키·기본키·대체키·외래키의 차이를 정리한다.


2. 행을 구별하려면 무엇이 필요할까?

다음 회원 테이블에서 이름만으로는 두 민수 중 누구를 가리키는지 알 수 없다. 반면 member_id는 각 회원에게 서로 다른 값을 부여한다.

member_id email name
1 minsu@example.com 민수
2 minsu2@example.com 민수
3 jiyun@example.com 지윤

행을 구별하는 열은 유일성과 최소성을 생각해야 한다.

  • 유일성: 키 값이 같은 두 행이 없어야 한다.
  • 최소성: 키를 이루는 열 중 하나라도 빼면 더 이상 모든 행을 구별할 수 없어야 한다.

예를 들어 member_id만으로 회원을 구별할 수 있으므로 (member_id, name)은 불필요한 열이 포함된 조합이다. email도 모든 회원에게 필수이고 중복되지 않는다는 업무 규칙이 있다면 회원을 구별하는 키가 될 수 있다.


3. 후보키, 기본키, 대체키

후보키(Candidate Key) 는 유일성과 최소성을 모두 만족하는 키다. 위 테이블에서 member_id와 email에 각각 고유한 값이 반드시 들어온다면 둘 다 후보키가 된다.

후보키 중 테이블의 대표 식별자로 선택한 것이 기본키(Primary Key, PK) 다. member_id를 기본키로 정하면 나머지 후보키인 email은 대체키(Alternate Key) 다. 기본키는 중복되거나 NULL일 수 없다.

종류 뜻 회원 테이블의 예
후보키 각 행을 최소한의 열로 구별할 수 있는 키 member_id, email
기본키 후보키 중 대표로 선택한 키 member_id
대체키 기본키로 선택되지 않은 후보키 email

email을 대체키로 다루려면 실제 스키마에서도 고유성과 필수 입력을 강제해야 한다. 이메일 변경이 가능하다면, 변하지 않는 member_id를 기본키로 두는 편이 다른 테이블에서 참조하기 쉽다.


4. 외래키로 테이블 연결하기

주문은 어느 회원의 것인지 알아야 한다. 주문 테이블의 member_id가 회원 테이블의 member_id를 가리키면, 주문 쪽의 member_id를 외래키(Foreign Key, FK) 라고 한다.

order_id member_id amount
101 1 12000
102 1 8000
103 3 15000

주문 101과 102는 모두 회원 1의 주문이다. 외래키 값은 여러 주문에서 반복될 수 있으므로 외래키 자체가 주문 행을 구별하는 키일 필요는 없다. 주문을 구별하는 기본키는 order_id다.

외래키 제약 조건을 설정하면 존재하지 않는 회원의 ID로 주문을 저장하는 일을 막을 수 있다. 회원을 삭제하거나 ID를 바꿀 때 주문을 어떻게 처리할지는 외래키의 삭제·갱신 규칙에 따라 달라진다.


5. SQL로 키 정의하기

다음은 앞의 두 테이블에 기본키, 이메일의 고유성, 외래키를 지정하는 예제다. SQL 문법과 제약 조건의 세부 동작은 사용하는 데이터베이스 제품에 따라 조금씩 다를 수 있다.

CREATE TABLE members (
    member_id BIGINT PRIMARY KEY,
    email VARCHAR(255) NOT NULL UNIQUE,
    name VARCHAR(100) NOT NULL
);

CREATE TABLE orders (
    order_id BIGINT PRIMARY KEY,
    member_id BIGINT NOT NULL,
    amount INTEGER NOT NULL,
    CONSTRAINT fk_orders_member
        FOREIGN KEY (member_id) REFERENCES members(member_id)
);

PRIMARY KEY는 행의 대표 식별자를 정한다. email의 NOT NULL UNIQUE는 값이 반드시 있고 중복되지 않도록 한다. FOREIGN KEY는 주문의 member_id가 회원 테이블에 있는 값을 참조하도록 강제한다. 이 스키마에는 ID 자동 생성 설정이 없으므로 데이터를 넣을 때 member_id와 order_id 값을 직접 지정해야 한다.


6. 여러 열을 묶는 복합키

키는 열 하나로만 구성되는 것은 아니다. 한 회원이 한 강의에 한 번만 수강 신청할 수 있다면, 수강 신청 테이블에서는 (member_id, course_id)를 복합키(Composite Key) 로 사용할 수 있다.

member_id course_id enrolled_at
1 10 2026-10-01
1 20 2026-10-02
2 10 2026-10-03

member_id와 course_id는 각각 반복되지만 두 값을 묶은 조합은 중복되지 않는다. 이 조합을 기본키로 선택한다면 다음처럼 선언한다.

CREATE TABLE enrollments (
    member_id BIGINT NOT NULL,
    course_id BIGINT NOT NULL,
    enrolled_at DATE NOT NULL,
    PRIMARY KEY (member_id, course_id)
);

이 예제는 복합 기본키만 보여 준다. 실제로 회원과 강의 테이블이 있다면 각 열에 외래키도 선언해 참조 관계를 보장한다.


7. 정리

후보키는 행을 구별할 수 있는 최소한의 열 조합이고, 그중 대표로 선택한 것이 기본키다. 선택되지 않은 후보키는 대체키가 된다. 외래키는 다른 테이블의 행을 참조해 테이블 사이의 관계를 표현한다.

키를 설계할 때는 현재 데이터에서 우연히 값이 다르다는 사실만 보지 말고, 앞으로도 지켜야 할 업무 규칙을 먼저 정해야 한다. 그 규칙을 기본키·고유성·외래키 제약 조건으로 데이터베이스에 명시하면 잘못된 데이터가 들어오는 것을 막을 수 있다.