바이브 코딩 시대의 데이터베이스3-4 기본키 (PK)
테크타니 LEARN — 섹션 03 · 테이블에 대한 이해

기본키(PK),
한 행을 정확히 찾는 기준

지난 강의에서 값에 맞는 그릇을 골랐습니다. 이번에는 그 값들이 모여 만든 한 행을 정확히 가리키는 방법입니다. 이름이 김철수인 회원이 두 명이라면 이름만으로는 둘을 구별할 수 없으니까요.

난이도아주 쉬움소요6분준비물3-3 완료오늘PRIMARY KEY 한 줄만

이번 섹션의 여정

3-2 컬럼의 약속

완료 ✓

3-3 데이터 타입

완료 ✓

3-4 기본키(PK)

지금 여기

3-5 ~ 3-8

외래키 · 테이블 만들기

이름이 같은 회원이 둘이라면

회원 한 명의 나이를 고치려고 합니다. 그런데 이름이 김철수인 회원이 두 명이라면 어떻게 될까요?

❌ 가상 상황 — 이름이 같은 회원이 둘
member_namegenderagejoined_at
김철수M352025-01-15
김철수M412025-06-30
둘 중 한 명을 고치려면 — 어느 행인지부터 정할 수 있어야 합니다

값을 찾는 것도, 고치는 것도, 지우는 것도 전부 어느 행인지 먼저 정해야 시작됩니다. 이름으로는 그게 안 되죠.

그래서 테이블에는 각 행을 하나씩 구별하는 값이 필요합니다. 이 값을 기본키, 또는 PK라고 부릅니다.

가상 상황입니다

실제 shop 의 회원 20명에는 동명이인이 없습니다. 위 표는 “이름으로는 구별할 수 없다” 는 걸 보여주기 위한 가상의 상황이에요.

기본키 — 한 행을 정확히 찾는 대표 값

우리 members 테이블에서는 member_id가 기본키입니다.

shop DB — members (member_id 가 기본키)
🔑 member_idmember_namegenderagejoined_at
1김철수M352025-01-15
2이영희F282025-02-03
3박민수M422025-02-10
20백서윤F212026-04-02
김철수는 1번, 이영희는 2번, 박민수는 3번 — 서로 겹치지 않습니다
회원 20명 — member_id 는 1번부터 20번까지 모두 다릅니다

이름이나 전화번호는 다른 회원과 같을 수도 있고, 나중에 바뀔 수도 있습니다. 하지만 각 행에 서로 다른 PK 값을 지정해두면 — 이름이 같은 회원이 있어도 PK 값으로 원하는 행 하나를 정확히 찾을 수 있어요.

기본키 한 줄 정의기본키는 테이블의 각 행을 중복 없이 구별하기 위해, 테이블이 정한 대표 값입니다.

기본키의 두 가지 규칙 — 중복 불가 · NULL 불가

기본키에는 데이터베이스가 직접 지키게 하는 두 가지 규칙이 있습니다.

PRIMARY KEY 로 지정하면 DB 가 검사하는 두 가지
① 중복 불가 — 같은 값이 두 행에 들어갈 수 없다
② NULL 불가 — 값을 비운 채로 저장할 수 없다

members에 새 회원을 저장한다고 해봅시다. 이미 1번부터 20번까지 저장돼 있고, member_id 는 자동 번호 매기기를 잠시 꺼둔 채 직접 지정한다고 가정할게요.

세 번의 저장 시도
member_id 에 넣은 값결과이유
21저장 성공 ✓아직 아무도 쓰지 않은 번호입니다
1저장 실패 ❌이미 김철수가 쓰고 있습니다 — 중복 불가
(비움 · NULL)저장 실패 ❌기본키는 비울 수 없습니다 — NULL 불가
개발자가 확인하기 전에 — 데이터베이스가 먼저 막아줍니다

두 번째 규칙은 3-2에서 배운 NULL과 이어집니다. NULL현재 기록된 값이 없다는 뜻이었죠. 기본키 값이 없다면 그 행을 정확히 찾을 방법 자체가 사라집니다. 그래서 저장을 아예 허용하지 않아요.

NOT NULL 과의 관계

PRIMARY KEY 로 지정한 컬럼은 자동으로 NULL 을 허용하지 않습니다. 우리 shop 스키마가 member_id INT NOT NULL 처럼 NOT NULL 을 함께 적어둔 건 — 읽는 사람이 규칙을 한눈에 보게 하려는 것이지, 그걸 적어야만 규칙이 생기는 건 아닙니다.

기본키는 하나, 구성 컬럼은 1개일 수도 N개일 수도

여기서 꼭 구분해야 할 것이 있습니다. 아마 이 강의에서 가장 자주 헷갈리는 지점일 거예요.

한 테이블에는 기본키를 하나만 지정할 수 있습니다. 하지만 그 기본키를 구성하는 컬럼이 꼭 하나여야 하는 건 아닙니다.

기본키를 만드는 방법은 두 가지 — 둘 다 기본키는 하나입니다.

컬럼 1개로 구성한 PK ✓
  • 예시members 의 member_id

  • 행을 정하는 법번호 하나만 알면 행이 정해진다

  • 기본키 개수1개

컬럼 N개로 구성한 PK ✓
  • 예시order_items 의 order_id + product_id

  • 행을 정하는 법두 값을 한 쌍으로 묶어야 행이 정해진다

  • 기본키 개수1개 — 구성 컬럼만 2개

달라지는 건 기본키의 개수가 아니라 — 그 하나를 만드는 컬럼의 개수입니다.

테이블 정의에 적히는 줄을 보면 더 분명합니다. 어느 쪽이든 PRIMARY KEY한 줄, 괄호도 하나예요.

테이블 정의에서 기본키를 적는 한 줄
PRIMARY KEY (member_id)
members — 컬럼 1개가 기본키 하나를 구성
 
PRIMARY KEY (order_id, product_id)
order_items — 컬럼 2개가 기본키 하나를 구성
절대 헷갈리면 안 되는 것

기본키가 N개라는 뜻이 아닙니다. 기본키는 하나이고, 그 하나를 구성하는 컬럼이 N개일 수 있다는 뜻입니다.

이렇게 여러 컬럼이 함께 하나의 기본키를 만들면, 그걸 복합키라고 부릅니다.

복합키 읽기 — order_items 의 (order_id, product_id)

order_items, 즉 주문상세 테이블의 한 행에는 어떤 주문에 어떤 상품이 몇 개 들어 있는지를 기록합니다.

shop DB — order_items 앞부분
order_idproduct_idquantity
111
1162
2221
391
3111
order_id 는 1 이 두 번, 3 이 두 번 — 값이 반복됩니다
전체 64줄 중 앞의 5줄

여기서 어떤 컬럼이 기본키가 될 수 있을지 하나씩 대입해 보겠습니다. 판단 기준은 방금 배운 중복 불가 하나면 충분해요.

무엇으로 행을 구별할 수 있을까?
이 기준으로 보면실제 데이터에서는
order_id 만 본다한 주문에 여러 상품 → 1 이 두 행에 중복된다 ❌
product_id 만 본다같은 상품이 여러 주문에 → 9 가 3·6·12번 주문에 모두 있다 ❌
두 컬럼을 한 쌍으로 묶는다(1,1) · (1,16) · (2,22) · (3,9) · (3,11) — 모두 다르다 ✓
PRIMARY KEY (order_id, product_id)

order_id만 보면 한 주문에 상품이 여러 개 들어가니 값이 중복됩니다. product_id만 봐도 같은 상품이 여러 주문에 들어가니 역시 중복돼요. 하지만 둘을 한 쌍으로 묶으면 각 행을 구별할 수 있습니다.

그래서 order_items의 기본키는 (order_id, product_id)입니다. 다시 한 번 — 기본키가 두 개인 게 아니라, 하나의 기본키를 두 컬럼이 함께 구성하는 겁니다.

같은 주문에 같은 상품은 한 줄만

복합키를 정하는 순간 규칙이 하나 따라옵니다. 같은 주문과 같은 상품의 조합은 두 번 저장할 수 없다는 것.

1번 주문에 이미 라운드 티셔츠(product_id 1)가 들어 있다면, 같은 주문에 라운드 티셔츠 행을 하나 더 만들 수 없습니다. 그럼 세 개를 산 경우는 어떻게 기록할까요?

라운드 티셔츠를 3개 샀다면
이렇게 저장하려 하면결과
(1, 1) 행을 세 줄 만든다저장 실패 ❌ — 같은 조합이 이미 있습니다
(1, 1) 행 하나에 quantity = 3저장 성공 ✓
행을 늘리는 대신 — 수량 컬럼의 숫자를 올립니다

실제 shop 데이터에도 이런 행이 있습니다. 10번 주문의 (10, 16)quantity3이에요. 프리미엄 그래놀라를 세 개 산 주문이지만 행은 하나입니다.

복합키가 하는 두 가지 일기본키는 행을 찾는 기준이면서 — 동시에 같은 데이터가 두 번 저장되지 않게 막는 규칙입니다.

이름으로 추측하지 말고 설정을 확인하세요

마지막으로 흔한 함정 하나. 컬럼 이름이 id로 끝난다고 무조건 기본키인 것은 아닙니다.

orders 테이블에는 order_idmember_id가 둘 다 있습니다. 하지만 기본키는 order_id 하나뿐이에요.

shop DB — 김철수(member_id 1)의 주문 6건
🔑 order_idmember_idordered_at
112025-02-01
612025-04-10
1412025-08-01
2012025-10-12
2712025-12-10
3412026-02-15
member_id 는 1 이 여섯 번 반복됩니다 — 중복되므로 기본키가 될 수 없어요
주문 40건 중 김철수의 주문만 뽑은 모습

한 회원이 여러 번 주문하니까 member_id는 당연히 반복됩니다. 이름이 id로 끝난다는 건 아무 근거가 되지 못해요.

처음 보는 테이블에서 기본키를 찾는 법
테이블 정의에서 PRIMARY KEY 항목이 어느 컬럼을 가리키는지 본다
DBeaver 컬럼 목록의 열쇠 표시를 확인한다
이름이 id 로 끝나는지로 추측하지 않는다

한눈에 정리

개념한 줄 정의shop 에서는
기본키 (PK)각 행을 중복 없이 구별하는 대표 값members.member_id
중복 불가같은 PK 값을 두 행에 저장할 수 없다member_id 1번은 김철수 한 명
NULL 불가PK 값을 비운 채로는 저장할 수 없다비우면 그 행을 찾을 수 없으니까
기본키는 하나한 테이블에 PK 는 하나만 지정한다예외 없음
구성 컬럼은 1 ~ N개그 하나를 만드는 컬럼은 여러 개일 수 있다(order_id, product_id)
복합키여러 컬럼이 함께 만든 하나의 PKorder_items
이름 ≠ 기본키id 로 끝나도 PK 가 아닐 수 있다orders.member_id

오늘의 핵심은 간단합니다 — 기본키는 테이블의 한 행을 정확히 찾는 값이며, 중복과 NULL을 허용하지 않습니다.

그런데 방금 본 orders.member_id는 그럼 뭘까요? 기본키도 아닌데 왜 거기 있을까요? 그건 다른 테이블의 기본키를 가리키는 값입니다. 그 이야기가 다음 강의예요.

NEXT LESSON3-4 연습 문제

PK 후보를 직접 고르고, 저장이 성공할지 실패할지 판정한 뒤 — 복합키에 대한 흔한 오해를 바로잡습니다.

GO ▸ 연습 문제 풀기