Post

3. DB 설계와 정규화

3. DB 설계와 정규화

DB 설계 과정

1
2
3
4
5
6
7
8
9
10
11
요구사항 분석
  ↓
개념적 설계 (ER 모델)
  ↓
논리적 설계 (릴레이션 변환)
  ↓
정규화
  ↓
물리적 설계 (인덱스, 저장 구조)
  ↓
구현

ER 모델 (Entity-Relationship Model)

현실 세계를 개체(Entity)관계(Relationship)로 모델링하는 개념적 데이터 모델.

구성 요소

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1. 개체 (Entity)
   - 독립적으로 존재하는 현실 세계의 객체
   - 직사각형으로 표현
   - 예: 학생, 과목, 교수

2. 속성 (Attribute)
   - 개체의 특성
   - 타원으로 표현
   ├── 단순 속성: 더 이상 분해 불가 (이름)
   ├── 복합 속성: 분해 가능 (주소 → 시, 구, 동)
   ├── 단일값 속성: 하나의 값 (학번)
   ├── 다치 속성: 여러 값 (전화번호) - 이중 타원
   ├── 저장 속성: 실제 저장 (생년월일)
   └── 유도 속성: 계산으로 도출 (나이) - 점선 타원

3. 관계 (Relationship)
   - 개체 간의 연관성
   - 마름모로 표현
   - 예: 학생 --수강-- 과목

4. 키 속성
   - 개체를 유일하게 식별
   - 밑줄로 표현

관계의 카디널리티 (대응 수)

1
2
3
4
5
6
7
8
9
10
11
12
13
1. 1:1 (일대일)
   - 하나의 개체가 상대 개체 하나와만 연관
   - 예: 학생 ── 졸업논문 (한 학생이 하나의 논문)

2. 1:N (일대다)
   - 하나의 개체가 상대 여러 개체와 연관
   - 예: 학과 ── 학생 (하나의 학과에 여러 학생)
   - 가장 흔한 유형

3. N:M (다대다)
   - 양쪽 모두 여러 개체와 연관
   - 예: 학생 ── 과목 (학생은 여러 과목, 과목에 여러 학생)
   - 릴레이션 변환 시 별도 테이블 생성 필요

참여 제약 조건

1
2
3
4
5
6
7
8
9
전체 참여 (Total Participation)
  - 모든 개체가 관계에 참여해야 함
  - 이중 실선으로 표현
  - 예: 모든 학생은 반드시 학과에 소속

부분 참여 (Partial Participation)
  - 일부 개체만 관계에 참여
  - 단일 실선으로 표현
  - 예: 일부 교수만 프로젝트에 참여

약한 개체 (Weak Entity)

1
2
3
4
5
6
7
- 자체 키 속성이 없어 독립적으로 존재할 수 없는 개체
- 소유 개체(Owner Entity)에 종속
- 이중 직사각형으로 표현
- 부분키(Partial Key): 소유 개체의 키와 결합하여 유일하게 식별

예: 직원(소유) ──── 부양가족(약한)
    직원번호 + 부양가족이름 = 유일 식별

ER 모델 → 릴레이션 변환

변환 규칙

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
1. 강한 개체 → 릴레이션
   - 개체의 속성이 릴레이션의 속성
   - 키 속성이 기본키

   Student(id, name, dept)

2. 약한 개체 → 릴레이션
   - 소유 개체의 기본키를 FK로 포함
   - 부분키 + FK = 기본키

   Dependent(emp_id, dep_name, relation)
   PK: (emp_id, dep_name), FK: emp_id → Employee

3. 1:1 관계 → 한쪽에 FK 추가
   - 전체 참여 쪽에 FK를 넣는 것이 유리 (NULL 방지)

   Student(id, name, thesis_id)  -- FK 추가

4. 1:N 관계 → N쪽에 FK 추가
   - N쪽 릴레이션에 1쪽의 PK를 FK로 추가

   Student(id, name, dept_id)    -- FK: dept_id → Department

5. N:M 관계 → 별도 릴레이션 생성
   - 양쪽의 PK를 FK로 포함하고 이들이 PK
   - 관계의 속성도 포함

   Enrollment(student_id, course_id, grade)
   PK: (student_id, course_id)

6. 다치 속성 → 별도 릴레이션
   - 개체의 PK + 다치 속성으로 구성

   StudentPhone(student_id, phone)
   PK: (student_id, phone)

변환 예시

1
2
3
4
5
6
7
8
9
10
11
12
ER 모델:
  [학생] ──(수강)── [과목]
  학번     성적     과목번호
  이름              과목명
  학과              학점

릴레이션 변환:
  Student(student_id, name, dept)
  Course(course_id, course_name, credit)
  Enrollment(student_id, course_id, grade)
    FK: student_id → Student
    FK: course_id → Course

정규화 (Normalization)

릴레이션을 분해하여 이상(Anomaly)을 제거하는 과정.

이상 (Anomaly)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
잘못 설계된 릴레이션:
StudentCourse(학번, 이름, 학과, 과목번호, 성적)

1. 삽입 이상 (Insertion Anomaly)
   - 수강 기록 없이 학생 정보만 삽입 불가
   - 과목번호가 PK의 일부이므로 NULL 불가

2. 삭제 이상 (Deletion Anomaly)
   - 수강 기록 삭제 시 학생 정보도 함께 삭제
   - 마지막 수강 과목을 삭제하면 학생 자체가 사라짐

3. 갱신 이상 (Update Anomaly)
   - 학과 변경 시 해당 학생의 모든 튜플을 수정해야 함
   - 일부만 수정하면 불일치 발생

정규형의 관계

1
2
3
4
5
6
7
8
9
비정규형 → 1NF → 2NF → 3NF → BCNF → 4NF → 5NF

높은 정규형일수록:
  ✅ 이상(Anomaly) 감소
  ✅ 데이터 중복 감소
  ❌ 조인 연산 증가 (릴레이션 분해)
  ❌ 질의 성능 저하 가능

실무에서는 보통 3NF 또는 BCNF까지 정규화

제1정규형 (1NF)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
조건: 모든 속성 값이 원자값(Atomic Value)이어야 함
→ 다치 속성, 복합 속성, 반복 그룹 제거

위반 예시:
┌──────┬────────┬─────────────────┐
│ 학번  │ 이름   │ 전화번호         │
├──────┼────────┼─────────────────┤
│ 1001 │ 홍길동  │ 010-1234, 02-555│  ← 다치 값!
└──────┴────────┴─────────────────┘

1NF 변환:
┌──────┬────────┬──────────┐
│ 학번  │ 이름   │ 전화번호  │
├──────┼────────┼──────────┤
│ 1001 │ 홍길동  │ 010-1234 │
│ 1001 │ 홍길동  │ 02-555   │
└──────┴────────┴──────────┘

또는 별도 테이블로 분리 (추천):
Student(학번, 이름)
StudentPhone(학번, 전화번호)

제2정규형 (2NF)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
조건: 1NF + 기본키에 대한 부분 함수적 종속 제거
→ 기본키가 복합키일 때 의미 있음 (단일 키이면 자동으로 2NF)

위반 예시:
Enrollment(학번, 과목번호, 이름, 학과, 성적)
PK: {학번, 과목번호}

FD:
  {학번, 과목번호} → 성적  (완전 종속 ✅)
  {학번} → 이름, 학과       (부분 종속 ❌)

2NF 변환:
Student(학번, 이름, 학과)           -- 부분 종속 분리
Enrollment(학번, 과목번호, 성적)    -- 완전 종속만 유지

제3정규형 (3NF)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
조건: 2NF + 이행적 함수적 종속 제거
→ 비키 속성이 기본키에 직접 종속해야 함

위반 예시:
Student(학번, 이름, 학과, 학과장)
PK: {학번}

FD:
  학번 → 학과    (직접 종속 ✅)
  학과 → 학과장  (비키 → 비키)
  학번 → 학과장  (이행 종속 ❌)

3NF 변환:
Student(학번, 이름, 학과)    -- FK: 학과 → Department
Department(학과, 학과장)     -- 이행 종속 분리

BCNF (Boyce-Codd Normal Form)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
조건: 모든 결정자가 후보키여야 함
→ 3NF보다 강한 조건

3NF vs BCNF:
  3NF: 비키 속성이 키에 직접 종속
  BCNF: 모든 결정자(→의 좌변)가 후보키

위반 예시:
Teaches(학생, 과목, 교수)
PK: {학생, 과목}

FD:
  {학생, 과목} → 교수  (키 → 비키 ✅)
  교수 → 과목          (비키 → 키의 일부 ❌, BCNF 위반)

  교수는 결정자이지만 후보키가 아님

BCNF 변환:
TeachesProf(교수, 과목)      -- 교수 → 과목
StudentProf(학생, 교수)       -- 분리

주의: BCNF 분해 시 함수적 종속 보존이 안 될 수 있음
→ 3NF까지만 정규화하는 경우도 있음

정규형 요약

정규형조건제거 대상
1NF원자값다치 값, 반복 그룹
2NF1NF + 완전 함수 종속부분 함수 종속
3NF2NF + 이행 종속 제거이행적 함수 종속
BCNF모든 결정자가 후보키후보키가 아닌 결정자

정규형 판별 흐름

1
2
3
4
5
6
7
8
9
원자값인가? ─ No → 1NF 위반
  │ Yes
부분 함수 종속이 있는가? ─ Yes → 2NF 위반
  │ No
이행적 종속이 있는가? ─ Yes → 3NF 위반
  │ No
모든 결정자가 후보키인가? ─ No → BCNF 위반
  │ Yes
  BCNF ✅

역정규화 (Denormalization)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
정규화된 릴레이션을 의도적으로 합치는 것

이유:
- 조인 연산 비용이 큰 경우
- 읽기 성능이 중요한 경우 (OLAP, 보고서)
- 실시간 조회가 필요한 경우

방법:
1. 테이블 합치기: 자주 조인하는 테이블을 하나로
2. 중복 속성 추가: 조인 없이 조회하기 위해
3. 계산 속성 추가: 집계 값을 미리 저장

트레이드오프:
  정규화 → 이상 방지, 저장 공간 절약, 쓰기 유리
  역정규화 → 조회 성능 향상, 중복 허용, 읽기 유리

핵심 정리

1
2
3
4
5
6
1. DB 설계: 요구사항 → 개념적(ER) → 논리적(릴레이션) → 물리적
2. ER 모델: 개체(□) + 관계(◇) + 속성(○)
3. 카디널리티: 1:1, 1:N, N:M → N:M은 별도 테이블
4. 이상: 삽입/삭제/갱신 이상 → 정규화로 해결
5. 정규화: 1NF(원자값) → 2NF(부분종속) → 3NF(이행종속) → BCNF
6. 역정규화: 성능을 위해 의도적 중복 허용

면접 포인트

자주 나오는 질문

Q1. 정규화란 무엇이고 왜 하는가?

  • 릴레이션을 분해하여 이상(Anomaly)을 제거하는 과정
  • 삽입/삭제/갱신 이상을 방지하고 데이터 무결성을 보장
  • 데이터 중복을 최소화하여 저장 공간을 절약

Q2. 1NF, 2NF, 3NF, BCNF의 차이는?

  • 1NF: 모든 속성이 원자값
  • 2NF: 1NF + 부분 함수 종속 제거 (복합키일 때)
  • 3NF: 2NF + 이행적 함수 종속 제거
  • BCNF: 모든 결정자가 후보키 (3NF보다 강한 조건)

Q3. 역정규화는 언제 하는가?

  • 조인 비용이 큰 읽기 위주 시스템에서 성능 향상 목적
  • OLAP, 데이터 웨어하우스, 보고서 시스템
  • 쓰기 성능 + 무결성 vs 읽기 성능의 트레이드오프

Q4. ER 모델에서 N:M 관계는 어떻게 릴레이션으로 변환하는가?

  • 별도의 릴레이션(교차 테이블)을 생성
  • 양쪽 개체의 PK를 FK로 포함하고, 이들의 조합이 PK
  • 관계 자체의 속성(예: 성적)도 해당 릴레이션에 포함

Q5. 3NF까지만 정규화하고 BCNF로 안 가는 이유는?

  • BCNF 분해 시 함수적 종속 보존이 안 될 수 있음
  • 3NF는 종속 보존 분해(Dependency-Preserving Decomposition)가 항상 가능
  • 실무에서 3NF로 충분한 경우가 대부분

Q6. 함수적 종속에서 완전/부분/이행 종속의 차이는?

  • 완전 종속: PK 전체에 의해서만 결정 (정상)
  • 부분 종속: PK의 일부에 의해 결정 → 2NF 위반
  • 이행 종속: A→B→C에서 A→C가 간접적으로 성립 → 3NF 위반
This post is licensed under CC BY 4.0 by the author.