•
슈퍼키 · 후보키 · 기본키 · 대체키 · 외래키의 포함 관계를 그림으로 설명할 수 있다.
•
주식별자의 4가지 특징(유일성·최소성·불변성·존재성) 으로 후보를 판정할 수 있다.
•
식별자를 4가지 기준으로 분류할 수 있다. (특히 본질 vs 인조)
•
식별관계와 비식별관계를 구분하고, 각각을 언제 써야 하는지 판단할 수 있다.
1. 키(Key)의 종류
1) 다섯 가지 키와 그 포함 관계
키 | 정의 | 한 줄 요약 |
슈퍼키 (Super Key) | 유일성만 만족하는 속성(들의 조합) | "구분은 되는데 군더더기가 있어도 됨" |
후보키 (Candidate Key) | 유일성 + 최소성을 만족 | "기본키가 될 자격을 갖춘 후보들" |
기본키 (Primary Key) | 후보키 중에서 대표로 선정된 것 | "실제로 뽑힌 대표" |
대체키 (Alternate Key) | 후보키 중에서 뽑히지 못한 나머지 | "낙선한 후보" = 보조식별자 |
외래키 (Foreign Key) | 다른 엔터티의 기본키를 참조하는 속성 | "관계를 만드는 열쇠" |
암기 문장"슈퍼키 중에 군더더기를 뺀 것이 후보키, 후보키 중에 뽑힌 것이 기본키, 떨어진 것이 대체키"2) 슈퍼키와 후보키의 차이 
PLAYER 테이블(480건)의 여러 조합을 판정해 봅시다.
후보 조합 | 서로 다른 값의 개수 | 유일성 | 최소성 | 판정 |
PLAYER_ID | 480 | ![]() | 더 뺄 것 없음 | 후보키 (그리고 기본키) |
(PLAYER_ID, PLAYER_NAME) | 480 | ![]() | 이름을 빼도 유일 | 슈퍼키일 뿐 |
(PLAYER_ID, HEIGHT, WEIGHT) | 480 | ![]() | 군더더기 2개 | 슈퍼키일 뿐 |
PLAYER_NAME | 476 | 동명이인 | — | 키가 될 수 없음 |
핵심: 유일하기만 하면 슈퍼키, 유일하면서 더 뺄 것이 없어야 후보키입니다.3) (TEAM_ID, BACK_NO) 는 후보키가 될 수 있는가? ★
상식: "같은 팀 안에서 등번호는 중복될 수 없다" — 진짜인지 데이터로 확인합니다.
STEP | 검증 항목 | 결과 | 판정 |
1 | 같은 (팀ID, 등번호) 조합이 2건 이상 있는가? | 0건 | 유일성 만족 |
2 | 팀ID만으로 유일한가? | 15종류 (≠480) | 부족 |
2 | 등번호만으로 유일한가? | 47종류 (≠480) | 부족 |
2 | → 둘 다 필요한가? | 그렇다 | 최소성 만족 |
3 | BACK_NO 에 NULL이 있는가? | 12건 존재 ![]() | 존재성 위반 |
최종 판정(TEAM_ID, BACK_NO) 는 유일성·최소성은 만족하지만 NULL이 있어 기본키로 쓸 수 없습니다.
그래서 이 모델은 인위적으로 만든 PLAYER_ID 를 기본키로 선택했습니다.
시험에서 "후보키인가?"를 물을 때 NULL 여부를 반드시 함께 확인해야 합니다.2. 주식별자의 특징 4가지 


1) 4가지 특징
# | 특징 | 뜻 | 위반하면? |
1 | 유일성 (Unique) | 모든 인스턴스를 유일하게 구분한다 | 어느 행인지 특정 불가 |
2 | 최소성 (Minimality) | 유일성을 만족하는 최소 개수의 속성만 사용 | 불필요한 컬럼이 인덱스를 키움 |
3 | 불변성 (Not Changeable) | 한 번 정해지면 값이 바뀌지 않는다 | 자식 테이블의 FK까지 전부 수정해야 함 |
4 | 존재성 (Not Null) | 값이 반드시 존재해야 한다 (NULL 불가) | 식별 자체가 불가능 |
실제 후보들을 4특징으로 판정해 보면
후보 속성 | 유일성 | 최소성 | 불변성 | 존재성 | 결론 |
PLAYER_ID | ![]() | ![]() | ![]() | ![]() | 주식별자 O |
선수명 | ![]() | — | 개명 가능 | ![]() | ![]() |
휴대폰번호 | ![]() | ![]() | 바뀜 | 없을 수 있음 | ![]() |
이메일 | ![]() | ![]() | 바뀜 | ![]() | ![]() |
주민등록번호 | ![]() | ![]() | ![]() | ![]() | 개인정보 이슈로 사용 불가 |
가장 많이 틀리는 지점 — '불변성'
휴대폰번호·이메일은 유일해 보여도 바뀝니다 → 불변성 위반 → 주식별자 부적합.2) DB가 자동으로 지켜주는 것 vs 설계자가 지켜야 하는 것 
PRIMARY KEY 제약을 걸면 Oracle이 두 가지를 자동으로 강제합니다.
CONSTRAINT PLAYER_PK PRIMARY KEY (PLAYER_ID)
-- → (1) UNIQUE 자동 적용 = '유일성' 보장
-- → (2) NOT NULL 자동 적용 = '존재성' 보장
SQL
복사
시도한 일 | Oracle의 반응 | 어떤 특징이 지켜진 것인가 |
같은 PLAYER_ID 를 또 입력 | ORA-00001: unique constraint violated | 유일성 ![]() |
PLAYER_ID 에 NULL 입력 | ORA-01400: cannot insert NULL | 존재성 ![]() |
PK에 군더더기 컬럼을 넣음 | 아무 오류 없음 ![]() | 최소성 — DB가 안 막아줌 |
PK 값을 나중에 변경 | 아무 오류 없음 ![]() | 불변성 — DB가 안 막아줌 |
시험 포인트유일성·존재성은 DB가 자동으로 보장하지만, 최소성·불변성은 설계자의 책임입니다.3) '최소성' 위반 — 군더더기가 낀 복합키의 대가 ★
SCHEDULE 의 기본키를 두 가지로 설계했다고 비교해 봅시다.
나쁜 설계 | 좋은 설계 (실제 a1.sql) | |
기본키 구성 | (경기장ID, 경기일자, 홈팀ID, 원정팀ID) | (경기장ID, 경기일자) |
PK 컬럼 수 | 4개 | 2개 |
PK 인덱스 크기 | 약 17바이트 | 약 11바이트 |
자식 테이블의 FK | 4개 컬럼을 전부 끌고 다녀야 함 | 2개면 충분 |
자식과의 조인 조건 | 4개 | 2개 |
"한 경기장에서 같은 날 두 경기는 열리지 않는다" → (경기장ID, 경기일자)면 충분합니다.
홈팀·원정팀은 PK가 아닌 일반 속성으로 두는 것이 맞습니다.
3. 식별자의 4가지 분류 

기준 | 종류 | 판별 요령 |
① 대표성 | 주식별자 / 보조식별자 | 다른 테이블이 참조하면 주식별자 |
② 생성 여부 | 내부식별자 / 외부식별자 | FK면 외부식별자 |
③ 속성 개수 | 단일식별자 / 복합식별자 | 컬럼이 2개 이상이면 복합 |
④ 대체 여부 | 본질식별자 / 인조식별자 | 업무에 원래 있던 값이면 본질, 없던 걸 만들었으면 인조 |
1) 실습 스키마 전수 분류
각 엔터티의 기본키 구성
엔터티 | 기본키 컬럼 | 컬럼 수 |
STADIUM | STADIUM_ID | 1 |
TEAM | TEAM_ID | 1 |
PLAYER | PLAYER_ID | 1 |
SCHEDULE | STADIUM_ID + SCHE_DATE | 2 |
4가지 기준으로 분류하면
엔터티 | 주식별자 | ① 대표성 | ② 생성 여부 | ③ 속성 개수 | ④ 대체 여부 |
STADIUM | STADIUM_ID | 주식별자 | 내부식별자 | 단일식별자 | 인조식별자 |
TEAM | TEAM_ID | 주식별자 | 내부식별자 | 단일식별자 | 인조식별자 |
PLAYER | PLAYER_ID | 주식별자 | 내부식별자 | 단일식별자 | 인조식별자 |
SCHEDULE | STADIUM_ID + SCHE_DATE | 주식별자 | 외부식별자 포함(STADIUM_ID가 FK) | 복합식별자 | 본질에 가까움 |
SCHEDULE 만 성격이 다릅니다. 교차 엔터티라서 부모(경기장)의 키를 물려받았기 때문입니다.
이것이 식별관계입니다.2) 본질식별자 vs 인조식별자 
본질식별자 | 인조식별자 | |
정의 | 업무에 원래 존재하는 값 | 마땅한 게 없어 인위적으로 만든 값 |
예 | 사업자등록번호, 주문번호, 차량번호 | PLAYER_ID, 시퀀스, 자동증가 ID |
장점 | 값 자체가 의미를 가짐 | 짧고 단순, 값이 안 바뀜 |
단점 | 길거나 바뀔 수 있음 | 본질적 중복을 걸러내지 못함 |
3) 인조식별자를 쓸 때 반드시 따라오는 부작용 ★★
문제: 인조 PK만 믿으면 '같은 사람'이 두 번 등록되어도 DB는 막지 못합니다.
인조식별자만 PK로 둔 경우회원ID(PK) | 이름 | 생년월일 | 전화번호 | DB의 판정 |
1 | 김철수 | 19900101 | 010-1111-1111 | 입력 성공 |
2 | 김철수 | 19900101 | 010-1111-1111 | 입력 성공 ![]() |
회원ID만 다르면 DB는 아무 문제 없다고 판단합니다.
하지만 실제로는 완전히 같은 사람이 두 번 등록된 것 = 데이터 품질 붕괴
해결 — 본질식별자를 보조식별자로 남겨 UNIQUE 를 건다CONSTRAINT MEMBER_PK PRIMARY KEY (MEMBER_ID), -- 인조식별자 = 주식별자
CONSTRAINT MEMBER_UK UNIQUE (NAME, BIRTH_DT, PHONE) -- 본질식별자 = 보조식별자 ✅
SQL
복사
회원ID(PK) | 이름 | 생년월일 | 전화번호 | DB의 판정 |
1 | 김철수 | 19900101 | 010-1111-1111 | 입력 성공 |
2 | 김철수 | 19900101 | 010-1111-1111 | ORA-00001 차단됨 ![]() |
시험 포인트"인조식별자를 주식별자로 쓰면, 본질식별자는 보조식별자(대체키)로 남겨 UNIQUE 를 걸어야 한다."
이 조치를 안 하면 중복 데이터가 쌓이는 것이 인조식별자의 대표적 단점입니다.4. 식별관계 vs 비식별관계 


1과목에서 가장 많이 틀리는 부분입니다. 여기만큼은 확실히 잡고 갑시다.1) 딱 하나의 질문으로 구분된다
"부모의 기본키가, 자식의 기본키 안에 들어가는가?"
•
들어간다 → 식별관계 (Identifying) — ERD에서 실선
•
안 들어가고 일반 속성(FK)으로만 남는다 → 비식별관계 (Non-Identifying) — ERD에서 점선
구분 | 식별관계 | 비식별관계 |
부모 PK의 위치 | 자식의 PK에 포함 | 자식의 일반 속성(FK) |
ERD 표기 | 실선 | 점선 |
자식의 존재 | 부모 없이는 존재 불가 | 부모 없이도 존재 가능 |
FK의 NULL | 불가 (PK이므로) | 가능 (선택적 관계) |
관계 선택사양 | 필수 | 필수 또는 선택 |
장점 | 부모 키만으로 자식을 바로 조회 가능 | PK가 단순, 구조 변경에 유연 |
단점 | PK 컬럼이 계속 늘어남 ![]() | 조인을 한 단계 더 타야 함 |
헷갈리지 마세요"FK가 있으면 식별관계"가 아닙니다. FK는 둘 다 있습니다.
차이는 오직 그 FK가 자식의 PK 안에 들어가느냐입니다.2) 실습 스키마 판별표 
판별 공식: 그 컬럼이 PK이면서 동시에 FK이면 → 식별관계
테이블 | 컬럼 | PK인가 | FK인가 | 판정 |
PLAYER | PLAYER_ID | ![]() | — | (자기 키) |
PLAYER | TEAM_ID | — | ![]() | 비식별관계 |
TEAM | TEAM_ID | ![]() | — | (자기 키) |
TEAM | STADIUM_ID | — | ![]() | 비식별관계 |
SCHEDULE | SCHE_DATE | ![]() | — | (자기 키) |
SCHEDULE | STADIUM_ID | ![]() | ![]() | 식별관계 ![]() |
3) HR 스키마의 교과서적 식별관계 — JOB_HISTORY
"한 사원의 경력은, 그 사원이 없으면 존재할 수 없다"
테이블 | 기본키 | 설명 |
EMPLOYEES | EMPLOYEE_ID | 부모 |
JOB_HISTORY | EMPLOYEE_ID + START_DATE | 자식 — 부모 PK가 PK 안에 포함 ![]() |
데이터를 보면 왜 START_DATE 가 필요한지 알 수 있습니다
사원명 | 시작일 | 종료일 | 담당직무 |
Neena Kochhar | 1989-09-21 | 1993-10-27 | AD_ASST |
Neena Kochhar | 1993-10-28 | 1997-03-15 | AC_MGR |
Lex De Haan | 1993-01-13 | 1998-07-24 | IT_PROG |
EMPLOYEE_ID 만으로는 Neena의 경력 2건을 구분할 수 없습니다.
부모 키만으로 부족할 때 자식이 자기 키(START_DATE)를 보태는 것 — 이것이 식별관계의 전형입니다.4) 식별관계를 남발하면 벌어지는 일 

시나리오: 학교 → 학과 → 학생 → 수강 을 전부 식별관계로 설계하면?
단계 | 엔터티 | 기본키 구성 | PK 컬럼 수 |
1 | 학교 | 학교코드 | 1개 |
2 | 학과 | 학교코드 + 학과코드 | 2개 |
3 | 학생 | 학교코드 + 학과코드 + 학번 | 3개 |
4 | 수강 | 학교코드 + 학과코드 + 학번 + 과목코드 | 4개 ![]() |
그 결과 조인 조건도 함께 늘어납니다
-- 식별관계로 설계했을 때 — 조인 조건 3개
WHERE S.SCHOOL_CD = E.SCHOOL_CD
AND S.DEPT_CD = E.DEPT_CD
AND S.STUDENT_NO = E.STUDENT_NO
-- 비식별관계였다면 — 조인 조건 1개로 끝
WHERE S.STUDENT_NO = E.STUDENT_NO
SQL
복사
식별관계만 남발하면 | 비식별관계만 남발하면 | |
문제 ① | PK 컬럼 수 증가 → 인덱스가 커지고 느려짐 | 부모를 거슬러 가려면 조인을 계속 타야 함 |
문제 ② | 조인 조건 증가 → SQL이 길어지고 실수 확률 ↑ | 조인이 많아져 성능 저하 |
문제 ③ | 구조 변경 시 자식·손자·증손자까지 연쇄 수정 | — |
결론: 둘은 트레이드오프입니다. 무엇이 정답이라고 외우지 마세요.5. 식별자 설계 가이드
1) 식별관계 / 비식별관계 선택 기준
이런 경우 | 선택 |
자식이 부모 없이는 존재 의미가 없다 (경력, 주문상세) | 식별관계 |
부모가 사라지면 자식도 같이 사라져야 한다 | 식별관계 |
자식이 독립적으로 존재할 수 있다 (사원, 선수) | 비식별관계 |
FK에 NULL이 허용되어야 한다 (선택적 관계) | 비식별관계 |
부모 키가 바뀔 가능성이 있다 | 비식별관계 |
PK 컬럼이 이미 3개 이상으로 늘어났다 | 비식별관계 |
2) 주식별자 선정 원칙
•
업무에서 자주 이용되는 속성을 선택•
명칭·내역 같은 이름은 피한다 (선수명
— 바뀌고 중복됨)•
복합식별자는 속성 수를 최대한 적게•
마땅한 후보가 없으면 인조식별자를 쓰되, 본질 조합에 UNIQUE 를 반드시 건다6. 출제 포인트 한눈에 정리
# | 꼭 외울 것 | 핵심 |
1 | 키의 포함 관계 | 슈퍼키 ⊃ 후보키 ⊃ (기본키 + 대체키) |
2 | 슈퍼키 vs 후보키 | 슈퍼키 = 유일성만, 후보키 = 유일성 + 최소성 |
3 | 주식별자 특징 4가지 | 유일성 · 최소성 · 불변성 · 존재성 |
4 | DB가 자동 보장하는 것 | PK = UNIQUE + NOT NULL (최소성·불변성은 설계자 책임) |
5 | 대표성 분류 | 주식별자 / 보조식별자(=대체키) |
6 | 생성 여부 분류 | 내부식별자 / 외부식별자(=FK) |
7 | 대체 여부 분류 | 본질식별자 / 인조식별자 |
8 | 인조식별자의 단점 | 본질적 중복을 못 막는다 → 본질 조합에 UNIQUE 필요 |
9 | 식별관계 | 부모 PK가 자식 PK에 포함 · 실선 · FK NULL 불가 |
10 | 비식별관계 | 부모 PK가 자식의 일반 속성 · 점선 · FK NULL 가능 |
11 | 식별관계 남발 시 | PK 컬럼·조인 조건이 계속 늘어난다 |
7. 확인 문제
Q1. 주식별자의 특징으로 옳지 않은 것은?
① 유일성 ② 최소성 ③ 가변성 ④ 존재성
정답 보기
Q2. 아래 DDL에서 ORDER_DETAIL과 ORDERS의 관계는 무엇이며, 그렇게 판단한 근거는?
CREATE TABLE ORDERS (
ORDER_NO CHAR(10) NOT NULL,
ORDER_DT DATE,
CONSTRAINT ORDERS_PK PRIMARY KEY (ORDER_NO)
);
CREATE TABLE ORDER_DETAIL (
ORDER_NO CHAR(10) NOT NULL,
LINE_NO NUMBER(3) NOT NULL,
ITEM_CD CHAR(5),
CONSTRAINT ORDER_DETAIL_PK PRIMARY KEY (ORDER_NO, LINE_NO),
CONSTRAINT ORDER_DETAIL_FK FOREIGN KEY (ORDER_NO) REFERENCES ORDERS(ORDER_NO)
);
SQL
복사
정답 보기
Q3. 식별관계와 비식별관계에 대한 설명으로 옳지 않은 것은?
① 식별관계는 부모의 기본키가 자식의 기본키에 포함된다
② 비식별관계에서 외래키는 NULL을 가질 수 있다
③ 식별관계로만 설계하면 PK가 단순해져 조인이 쉬워진다
④ 비식별관계는 ERD에서 점선으로 표기한다
정답 보기









