397. 제2정규형 (2NF)과 부분 함수 종속
⚠️ 이 문서는 데이터베이스 테이블에 불필요한 중복 데이터가 쌓이는 이상 현상(Anomaly)을 막기 위한 정규화 과정 중, **기본 키가 여러 개로 묶여있을 때 일부 기본 키에만 얌체처럼 빌붙어 있는 컬럼을 찾아내어 쫓아내는 '제2정규형(2NF)'**을 다룹니다.
핵심 인사이트 (3줄 요약)
- 본질: 제2정규형은 제1정규형을 만족하면서, 모든 일반 컬럼들이 '기본 키(PK) 전체'에 완벽하게 종속되어야 한다는 규칙이다.
- 문제점: 복합키(학번 + 과목코드)를 쓸 때, '과목명' 같은 컬럼이 '학번'과는 상관없이 오직 '과목코드' 하나에만 종속되는 현상(부분 함수 종속)이 발생하면 데이터 중복이 일어난다.
- 해결책: 얌체처럼 부분적으로만 종속된 컬럼들을 떼어내서 **새로운 테이블로 독립(분리)**시키면 완벽한 제2정규형이 달성된다.
Ⅰ. 개요: 두 명이 끄는 마차 (Context & Necessity)
우리가 수강신청 테이블을 만들었다고 치자. 학생 한 명이 여러 과목을 들을 수 있으므로, 기본 키(PK)는 무조건 [학번 + 과목코드] 두 개를 합쳐야만(복합키) 특정 줄을 찾아낼 수 있다.
| 학번 (PK) | 과목코드 (PK) | 성적 | 과목명 |
|---|---|---|---|
| 1001 | CS101 | A | 컴퓨터 |
| 1002 | CS101 | B | 컴퓨터 |
이 테이블은 문제가 있다.
성적은 학번과 과목코드가 둘 다 있어야 정해진다. (올바른 종속)
하지만 과목명은 학번과는 아무 상관 없이, 오직 과목코드 하나만 알면 정해진다. 이것을 **부분 함수 종속(Partial Functional Dependency)**이라고 한다.
이대로 두면 1만 명이 'CS101'을 들을 때마다 '컴퓨터'라는 단어를 1만 번 중복해서 써야 한다. (공간 낭비 및 수정 이상 발생)
📢 섹션 요약 비유: 복합키가 2마리의 말(학번, 과목코드)이 끄는 마차라면, '성적'은 두 마리 말이 같이 끌어야 하는 무거운 짐입니다. 하지만 '과목명'은 한 마리(과목코드)만 끌어도 되는 가벼운 짐이죠. 가벼운 짐을 억지로 큰 마차에 싣고 다니면 낭비이므로, 가벼운 마차(새로운 테이블)를 따로 하나 만들어주는 것이 2NF입니다.
Ⅱ. 정규화의 전제 조건: 제1정규형 (1NF)
제2정규형을 논하기 전에, 테이블은 반드시 제1정규형을 만족해야 한다.
- 1NF의 규칙: "모든 컬럼의 값은 무조건 **원자값(더 이상 쪼개지지 않는 단일 값)**이어야 한다."
- ❌ 위반 사례: [이름: 김철수, 취미: 축구, 야구] (한 칸에 두 개가 들어감)
- 🟢 1NF 달성: 취미 테이블을 따로 분리하거나, 행을 두 개로 나눈다. (396번 문서의 다중값 매핑 룰 참조)
Ⅲ. 제2정규형 달성 방법: 테이블 쪼개기 ★
부분 함수 종속을 제거하는 유일한 방법은 **'테이블 분리(Decomposition)'**다.
기존 테이블 (1NF 상태, 2NF 위반)
수강_테이블[학번, 과목코드, 성적, 과목명, 지도교수]- 부분 종속:
과목코드$\rightarrow$과목명,지도교수
테이블 분리 후 (2NF 달성)
이 얌체 컬럼들을 데리고 나가서 새로운 테이블을 차린다.
수강_테이블[학번, 과목코드, 성적] (완전 함수 종속만 남음)과목_테이블[과목코드, 과목명, 지도교수] (새로 독립한 테이블)
이제 과목 이름이 '컴퓨터'에서 '전산학'으로 바뀌더라도, 새로운 과목 테이블에서 딱 1줄만 수정(UPDATE)하면 되므로 데이터 불일치(Anomaly)가 발생하지 않는다.
┌──────────────────────────────────────────────────────────────┐
│ 부분 함수 종속과 2NF(제2정규형) 분리 과정 시각화 │
├──────────────────────────────────────────────────────────────┤
│ │
│ [ ❌ 2NF 위반 (부분 함수 종속 존재) ] │
│ │
│ ┌─────────────────── 성적 ───────────────────┐ │
│ │ │ │
│ [학번(PK)] [과목코드(PK)] [성적] [과목명]│
│ │ │ │
│ └───────── 과목명 ──────┘ │
│ (부분 종속 발생!) │
│ │
│ [ 🟢 2NF 달성 (테이블 분리) ] │
│ │
│ 테이블 1: [학번(PK)] + [과목코드(PK)] ──▶ [성적] │
│ │
│ 테이블 2: [과목코드(PK)] ───────────────▶ [과목명] │
└──────────────────────────────────────────────────────────────┘
Ⅳ. 결론
"완벽한 독립은 짐을 나눠 드는 것에서 시작한다."
제2정규형은 '기본 키가 2개 이상일 때(복합키)'만 고민하면 되는 정규화다. 만약 테이블의 기본 키가 주문번호처럼 딱 1개라면, 그 테이블은 1NF만 만족하면 자동으로 2NF도 만족하게 된다. 설계자는 복합키를 만들 때마다 "이 일반 컬럼들이 정말 이 키들을 '모두' 필요로 하는가?"를 끊임없이 자문해야 하며, 그렇지 않다면 주저 없이 테이블을 썰어내야 한다.
📌 관련 개념 맵
- 선행 조건: 제1정규형 (1NF - 원자값)
- 후행 과정: 제3정규형 (3NF - 이행 함수 종속 제거, 398번 문서)
- 발생하는 문제점: 이상 현상 (Anomaly - 삽입/갱신/삭제 이상)
- 핵심 키워드: 복합키(Composite Key), 완전 함수 종속, 부분 함수 종속
👶 어린이를 위한 3줄 비유 설명
- '학년'과 '반'이 합쳐져야(복합키) 교실을 찾을 수 있어요. "3학년 2반의 담임선생님은 김유신이야." 이건 완벽한 문장이죠.
- 근데 "3학년 2반의 3학년 주임선생님은 이순신이야." 이건 이상해요. 주임선생님은 3학년이기만 하면 무조건 이순신이거든요. '반'은 알 필요가 없죠! (부분 종속)
- 그래서 주임선생님 정보는 억지로 교실마다 써 붙이지 말고, 그냥 교무실(새 테이블)에 따로 "3학년 주임은 이순신"이라고 하나만 적어두는 게 바로 제2정규형이랍니다!