함수 종속성과 정규화
정규화의 기준이 되는 함수 종속성을 먼저 보고, 이를 하나씩 없애 나가는 정규화 단계(1NF → BCNF)와 외우는 요령, 직접 풀어 본 연습 문제 6개까지 이어서 정리했습니다.
함수 종속성: X를 알면 Y를 알 수 있다
함수 종속성은 "속성 X의 값을 알면 속성 Y의 값이 자동으로 하나로 정해진다"는 관계입니다. X → Y로 표기하고, X를 결정자, Y를 종속자라고 부릅니다.
주의할 점: 화살표는 한쪽 방향으로만 성립합니다. X → Y가 성립한다고 Y → X도 성립하는 건 아닙니다. (학번을 알면 이름을 알 수 있지만, 이름만으로는 학번을 알 수 없는 것처럼요.)
정규화를 이해하려면 세 가지 종속을 구분할 수 있어야 합니다. 기본키가 [학번, 과목코드] 두 개로 이루어진 성적 테이블을 예로 들어보겠습니다.
| 학번 | 과목코드 | 학생이름 | 성적 | 학과 | 학과사무실 |
|---|---|---|---|---|---|
| 100 | C1 | 철수 | A | 컴공 | 3동 401호 |
| 100 | C2 | 철수 | B | 컴공 | 3동 401호 |
- 완전 함수 종속: 기본키 전체에 종속되는 경우.
[학번, 과목코드] → 성적은 학번과 과목코드가 둘 다 있어야 성적이 정해지므로 완전 함수 종속입니다. - 부분 함수 종속: 기본키의 일부에만 종속되는 경우.
학번 → 학생이름은 과목코드 없이 학번만으로도 정해지므로 부분 함수 종속입니다. - 이행적 함수 종속:
X → Y이고Y → Z이면 결과적으로X → Z가 되는 경우.학번 → 학과이고학과 → 학과사무실이므로,학번 → 학과사무실도 성립합니다. 학번이 학과사무실을 "간접적으로" 결정하는 셈입니다.
이 세 가지 종속을 하나씩 없애 나가는 과정이 바로 다음에 나올 정규화입니다.
정규화: 중복 데이터를 안 두는 기술
정규화는 한마디로 "같은 정보를 여러 곳에 중복해서 저장하지 않도록 테이블을 쪼개는 작업"입니다. 중복이 있으면 하나만 수정했을 때 나머지가 낡은 값으로 남는 문제(이상현상)가 생기는데, 정규화는 이걸 예방합니다. 단계가 올라갈수록 규칙이 하나씩 더 붙습니다.
1정규형 (1NF): 한 칸엔 값 하나만
모든 속성 값이 원자값이어야 합니다. 한 학생의 "취미" 칸에 "축구, 독서"가 같이 들어있다면, 이걸 행 단위로 쪼개야 합니다.
2정규형 (2NF): 부분 함수 종속 제거
1NF를 만족하고, 기본키 일부에만 종속되는 속성을 별도 테이블로 뺍니다. [학번, 과목코드]가 기본키인 테이블에서 [학번]에만 종속되는 [학생이름]을 별도의 "학생" 테이블로 분리하는 식입니다. (기본키가 원래 속성 1개뿐이면 이 문제는 자동으로 해결됩니다.)
3정규형 (3NF): 이행적 함수 종속 제거
2NF를 만족하고, 기본키가 아닌 속성끼리 원인-결과로 얽혀 있는 것도 분리합니다. 학번 → 학과 → 학과사무실 관계라면, [학과, 학과사무실]을 별도 테이블로 뺍니다.
BCNF: 결정자는 전부 후보키여야 함
3NF까지 만족해도 예외적으로 남는 문제가 있습니다. [학번, 과목명]이 복합 기본키인 테이블에서, 각 과목을 가르치는 [교수]가 한 명뿐이고 그 교수가 오직 그 과목만 가르친다고 하면 교수 → 과목명이 성립합니다. 그런데 [교수]는 후보키가 아닙니다(학번을 구분 못 함). 이렇게 결정자인데 후보키가 아닌 경우가 있으면 BCNF 위반이고, 해결책은 [학번, 교수]와 [교수, 과목명] 두 테이블로 다시 쪼개는 것입니다.
정규화 정도 ─────────────────▶
1NF → 2NF → 3NF → BCNF
(원자값) (부분종속×) (이행종속×) (결정자=후보키)정규화를 많이 할수록 중복은 줄지만, 조회할 때 조인해야 할 테이블 수가 늘어나는 트레이드오프가 있습니다.
한 번에 외우기: 도부이결다조
BCNF 뒤로도 4NF, 5NF가 더 있습니다. 실무에서는 보통 3NF나 BCNF까지만 하지만, 단계 이름은 앞 글자만 따서 **"도부이결다조"**로 외우면 편합니다.
| 단계 | 앞 글자 | 없애는 것 |
|---|---|---|
| 1NF | 도 | 도메인이 원자값이 아닌 것 (한 칸에 값 여러 개) |
| 2NF | 부 | 부분 함수 종속 |
| 3NF | 이 | 이행적 함수 종속 |
| BCNF | 결 | 결정자인데 후보키가 아닌 것 |
| 4NF | 다 | 다치 종속 |
| 5NF | 조 | 조인 종속 |
연습 문제
직접 풀어 본 문제들입니다. 종속성 문제는 테이블의 기본키(PK)가 무엇인지부터 확인하고 시작하면 훨씬 쉽습니다. 그리고 표에 들어 있는 데이터만 보고는 종속성을 "틀렸다"고는 말할 수 있어도 "항상 맞다"고 확신할 수는 없다는 점도 기억해 두세요. 반례는 아직 안 들어온 데이터에 있을 수 있습니다.
문제 1. 1정규형을 만족하려면?
[회원] 테이블이 정규화 전 상태입니다. 1정규형을 만족하려면 어떻게 해야 할까요?
| 회원ID (PK) | 회원명 | 연락처 | 취미 |
|---|---|---|---|
| M001 | 김철수 | 010-1111-2222 | 축구, 등산, 독서 |
| M002 | 이영희 | 010-3333-4444 | 요리, 영화시청 |
- '취미' 속성을 삭제한다.
- '취미' 속성의 데이터 타입을 가변 문자열(VARCHAR)로 바꾼다.
- 한 칸에 여러 개 들어 있는 '취미' 값을 나눠서, 한 칸에 값 하나만 들어가게 행을 쪼갠다.
- '회원ID'와 '취미'를 함께 주식별자(PK)로 지정한다.
정답과 해설
정답: 3번
1정규형의 조건은 "모든 속성 값은 원자값 하나"입니다. 김철수의 취미 칸에 값이 세 개나 들어 있으니, 개별 행이나 별도 테이블로 나눠서 한 칸에 하나씩만 들어가게 해야 합니다.
문제 2. 2정규형으로 쪼개기
[수강등록] 테이블은 1정규형을 만족합니다. 주식별자는 [학번 + 과목코드] 복합키이고, 종속성은 이렇습니다.
[학번 + 과목코드] → [성적](완전 함수 종속)[과목코드] → [과목명], [강의실](부분 함수 종속)
| 학번 (PK) | 과목코드 (PK) | 성적 | 과목명 | 강의실 |
|---|---|---|---|---|
| 202601 | CS01 | A | 데이터베이스 | 301호 |
| 202601 | CS02 | B | 알고리즘 | 402호 |
| 202602 | CS01 | A+ | 데이터베이스 | 301호 |
2정규형으로 올바르게 쪼갠 것은?
[학번, 과목코드, 성적, 과목명, 강의실]그대로 둔다.[학번, 과목코드, 성적]과[과목코드, 과목명, 강의실]로 나눈다.[학번, 과목명]과[과목코드, 성적, 강의실]로 나눈다.[학번, 성적]과[과목코드, 과목명, 강의실]로 나눈다.
정답과 해설
정답: 2번
2정규형은 부분 함수 종속을 없애는 단계입니다. 과목명과 강의실은 기본키 전체가 아니라 일부인 과목코드에만 종속되어 있으니, 이 묶음을 [과목코드, 과목명, 강의실] 테이블로 따로 빼고, 원래 테이블에는 [학번, 과목코드, 성적]만 남깁니다. 4번은 성적이 어느 과목의 성적인지 알 수 없게 되어서 틀립니다.
문제 3. 이행적 함수 종속 찾기
[임직원] 테이블은 2정규형을 만족하고, 주식별자는 [사원번호]입니다. 사원번호를 알면 부서코드를 알 수 있고, 부서코드를 알면 부서위치(층)를 알 수 있습니다.
| 사원번호 (PK) | 사원명 | 부서코드 | 부서위치 |
|---|---|---|---|
| E001 | 박민수 | DEPT_IT | 5층 |
| E002 | 최현우 | DEPT_HR | 3층 |
| E003 | 윤지아 | DEPT_IT | 5층 |
이 테이블의 이행적 함수 종속(X → Y → Z)은?
- 사원번호 → 사원명 → 부서코드
- 사원번호 → 부서코드 → 부서위치
- 부서위치 → 부서코드 → 사원번호
- 부서코드 → 사원번호 → 부서위치
정답과 해설
정답: 2번
기본키 사원번호(X)가 일반 속성 부서코드(Y)를 결정하고, 부서코드(Y)가 또 다른 일반 속성 부서위치(Z)를 결정합니다. 결국 사원번호가 부서위치를 간접적으로 결정하는 이행적 종속이라, 3정규형을 만족하려면 [부서코드, 부서위치]를 따로 빼야 합니다.
문제 4. 성립할 수 없는 함수 종속은?
[도서대여] 테이블입니다. 회원ID가 같으면 회원명과 등급은 항상 같고, 도서코드가 같으면 도서명은 항상 같습니다.
| 대여번호 (PK) | 회원ID | 회원명 | 등급 | 도서코드 | 도서명 |
|---|---|---|---|---|---|
| R_01 | M01 | 홍길동 | VIP | B100 | SQL기본 |
| R_02 | M02 | 이순신 | GOLD | B200 | 자바정복 |
| R_03 | M01 | 홍길동 | VIP | B200 | 자바정복 |
| R_04 | M03 | 강감찬 | GOLD | B300 | 웹디자인 |
- 대여번호 → 회원ID
- 회원ID → 회원명
- 도서코드 → 도서명
- 도서명 → 회원ID
정답과 해설
정답: 4번
X → Y가 성립하려면 X 값이 같을 때 Y 값도 반드시 하나로 같아야 합니다.
- 1번: 대여번호는 기본키라서 모든 속성을 결정합니다. (성립)
- 2번: 회원ID가 M01로 같을 때 회원명이 둘 다 홍길동입니다. (성립)
- 3번: 도서코드가 B200으로 같을 때 도서명이 둘 다 자바정복입니다. (성립)
- 4번: 도서명이 자바정복으로 같은데 회원ID는 M02와 M01로 다릅니다. (성립 안 함)
문제 5. 완전 함수 종속 vs 부분 함수 종속
[주문상세] 테이블은 [주문번호 + 상품코드]가 복합 기본키입니다. 종속성은 [주문번호, 상품코드] → [주문수량], [상품코드] → [상품명]입니다.
| 주문번호 (PK) | 상품코드 (PK) | 주문수량 | 상품명 |
|---|---|---|---|
| O_001 | P_A | 5 | 모니터 |
| O_001 | P_B | 2 | 키보드 |
| O_002 | P_A | 3 | 모니터 |
다음 중 올바르지 않은 설명은?
주문수량은 기본키 전체에 종속되므로 완전 함수 종속이다.상품명은 복합 기본키의 일부인상품코드에만 종속되므로 부분 함수 종속이다.- 이 테이블은 부분 함수 종속이 있으므로 2정규형을 위반한다.
- 2정규형을 만족하려면
[주문번호] → [주문수량]관계로 분해해야 한다.
정답과 해설
정답: 4번
- 1번: 주문수량은 어떤 주문에서 어떤 상품을 샀는지 두 정보가 다 있어야 정해지므로 완전 함수 종속이 맞습니다.
- 2번: 상품명은 주문번호와 상관없이 상품코드만 알면 정해지므로 부분 함수 종속이 맞습니다.
- 3번: 부분 함수 종속이 있으면 2정규형 위반이 맞습니다.
- 4번: 떼어내야 하는 건 원인인
상품코드와 결과인상품명입니다.[상품코드, 상품명]테이블로 분리하고, 주문수량은[주문번호, 상품코드, 주문수량]에 그대로 남아야 합니다.
문제 6. 기호로 이행적 함수 종속 찾기
속성 A, B, C, D가 있고, 다음 종속성이 확인되었습니다.
A → B(A는 기본키)B → CA → C(B를 거쳐 간접적으로 결정됨)A → D
3정규형을 위해 없애야 하는 이행적 함수 종속(X → Y → Z)은?
- A → B → C
- B → C → D
- A → C → D
- B → A → C
정답과 해설
정답: 1번
기본키 A가 일반 속성 B를 결정하고(A → B), B가 또 다른 일반 속성 C를 결정하므로(B → C) A → B → C가 이행적 종속입니다. [A, B, D] 테이블과 [B, C] 테이블로 나누면 3정규형을 만족합니다.
손으로 풀어 본 노트
정규화 문제 풀이 노트 (이미지)


함수 종속성 문제 풀이 노트 (이미지)


정리
| 단계 | 조건 | 없애는 것 |
|---|---|---|
| 1NF | 모든 속성 값이 원자값 | 한 칸에 여러 값 |
| 2NF | 1NF + 기본키 전체에 완전 함수 종속 | 부분 함수 종속 |
| 3NF | 2NF + 키가 아닌 속성끼리 종속 없음 | 이행적 함수 종속 |
| BCNF | 모든 결정자가 후보키 | 후보키가 아닌 결정자 |
- 함수 종속
X → Y: X(결정자)를 알면 Y(종속자)가 하나로 정해지며, 한 방향으로만 성립합니다. - 정규화할수록 중복은 줄지만 조회 시 조인할 테이블 수가 늘어납니다.
- 단계 이름은 도부이결다조(1NF 도메인 원자값 → 2NF 부분 → 3NF 이행 → BCNF 결정자 → 4NF 다치 → 5NF 조인)로 외웁니다.
참고: 개인 Notion 학습 노트
