Chapter 7. Relational Database Design

핵심 요약: “좋은” 릴레이션 설계는 정보 중복과 null을 최소화한다. 나쁜 스키마는 **분해(decomposition)**로 개선하되, 원본을 복원할 수 있는 lossless decomposition이어야 한다. 좋음의 기준은 함수적 종속성(Functional Dependency, FD) 위에 정의된 **정규형(Normal Form)**으로 판단한다. BCNF는 모든 비자명 FD의 좌변이 superkey여야 하고, 3NF는 BCNF의 조건을 완화하여 dependency preservation을 항상 보장한다. Armstrong’s axioms와 attribute closure 로 FD를 추론하고 BCNF/3NF 분해 알고리즘을 적용한다.


1. Features of Good Relational Designs

나쁜 설계의 증상을 in_dep(instructor와 department를 natural join한 결과)로 관찰한다:

IDnamesalarydept_namebuildingbudget
22222Einstein95000PhysicsWatson70000
12121Wu90000FinancePainter120000
45565Katz75000Comp. Sci.Taylor100000
10101Srinivasan65000Comp. Sci.Taylor100000
76766Crick72000BiologyWatson90000

증상

  • 정보 중복(Repetition of information): Comp. Sci. 학과의 building·budget이 여러 행에 반복.
  • Null의 필요성: 교수가 없는 학과를 추가하려면 교수 속성에 null을 써야 함.

해결 — Decomposition

  • in_depinstructordepartment 두 스키마로 분해해야만 중복을 제거할 수 있다.
  • 그러나 모든 분해가 좋은 것은 아니다.

2. Decomposition — Lossless vs Lossy

2.1 Lossy Decomposition 예시

employee(ID, name, street, city, salary)

employee1(ID, name)
employee2(name, street, city, salary)

로 분해하면, 같은 이름을 가진 두 직원(예: Kim)이 있을 때 natural join 결과에 원본에 없던 튜플이 생긴다:

IDnamestreetcitysalary
57766KimMainPerryridge75000
57766KimNorthHampton67000 ← 가짜
98776KimMainPerryridge75000 ← 가짜
98776KimNorthHampton67000

원본을 복원할 수 없다lossy decomposition.

2.2 Lossless Decomposition 정의

일 때, 모든 가능한 인스턴스 에 대해

이 성립하면 lossless decomposition. 만약

이면 lossy.

r 이라는 relation에서 any column R1, R2를 뽑아 projection하고
natural join 했을 때, 원본 복구가 돼냐?
“쪼갰다 붙이면 원본 복구됨?”

반대로 loosy를 생각해보면 아까 위에서 visual 적으로 불필요한게 늘어난 경우니까, 부등호 방향을 기억하기!

직관 — "lossless"는 사실 "가짜 튜플 무발생"

  • 튜플은 절대 사라지지 않음: 는 항상 성립. 원본의 어떤 튜플이든 쪼갰다 붙이면 반드시 돌아옴.
  • 문제는 반대 방향: 가 깨질 수 있음 → join 결과에 원본에 없던 가짜 튜플(spurious tuple) 이 섞임 = lossy.
  • 따라서 lossless = “쪼갰다 붙여도 가짜가 안 생김”. 이름은 “lossless”지만 실제로는 “spurious-free”가 더 정확한 표현.

기호 정의

  • : 릴레이션 스키마 (속성 이름들의 집합), 예:
  • (소문자): 스키마 인스턴스 — 실제 튜플들이 담긴 테이블
  • : 분해로 생긴 부분 스키마. , 는 공통 속성
  • : 의 한 튜플(행)
  • : 튜플 에서 속성만 뽑은 값 (한 행의 부분 투영)
  • : 전체 컬럼으로만 잘라낸 테이블 (중복 제거)
  • : natural join — 공통 속성 값이 같은 행끼리 붙임

방향(튜플 안 사라짐)은 항상 성립하는가
원본의 임의의 튜플 을 잡자. 그러면:

  1. 안에 존재 (으로 자른 조각).
  2. 안에 존재 (로 자른 조각).
  3. 같은 원본 튜플 에서 잘린 조각이므로 공통 속성 에서의 값이 자동으로 일치 → natural join 조건을 만족.
  4. 따라서 가 join 결과에 반드시 포함됨.

즉 project는 “세로로 자르기”일 뿐 행을 버리지 않고, natural join은 매칭되는 쌍을 반드시 복원하므로, 모든 원본 튜플은 복구 보장. 그래서 수학적으로 항상 참인 부등식이고, 실제 lossless/lossy를 가르는 것은 오직 방향뿐.

왜 가짜가 생기는가: 분해 시 “ID ↔ salary의 짝 정보”가 끊어지고, join은 공통값으로 모든 조합을 만들어버리기 때문. 공통 속성이 한쪽의 key이면 조합이 1:1이라 가짜 불가 → 그래서 §5의 lossless 조건이 “공통 속성 한쪽 전체”인 것.

2.3 Lossless 예시

, , 로 분해:

| A | B | C | → | A | B | | B | C |

|---|---|---| |---|---| |---|---|
| α | 1 | A | | α | 1 | | 1 | A |
| β | 2 | B | | β | 2 | | 2 | B |

natural join 결과가 원본과 일치 → lossless.
조건 : 공통 속성이 한 쪽의 superkey일 것.


3. Normalization Theory 개요

  • 주어진 릴레이션 이 “good” form인지 판단한다.
  • good form이 아니면 로 분해하되 각 가 good form이고, lossless여야 한다.
  • 이론은 Functional dependenciesMultivalued dependencies 위에 구축된다.

3.1 “Good form”의 의미 — 왜 분해하는가

분해의 궁극적 목표는 redundancy 제거를 통해 3가지 anomaly를 방지하는 것:

anomaly : 변칙, 예외, 이상치, 이상 징후

Anomaly증상
Update anomaly같은 사실이 여러 행에 반복되어, 일부만 갱신하면 불일치 발생
Insertion anomaly특정 정보를 넣으려면 아직 모르는 값(NULL)까지 억지로 채워야 함
Deletion anomaly한 튜플 삭제 시 무관한 다른 정보까지 함께 사라짐

예: inst_dept(ID, name, salary, dept_name, building, budget)에서 한 학과의 교수가 10명이면 building, budget이 10번 반복됨 → 건물 정보 변경 시 10줄 모두 갱신 필요(update), 교수 없는 신설 학과는 삽입 불가(insertion), 마지막 교수 퇴직 시 학과 정보까지 소실(deletion).

3.2 분해의 3가지 목표

“good form으로 분해”는 동시에 3가지 품질 기준을 만족해야 한다:

  1. Lossless join (§2) — 반드시 만족. 원본 복원 가능해야 함.
  2. Dependency preservation (§6) — 가능한 한 만족. 원래 FD들을 분해 후에도 각 안에서 검사 가능해야 함.
  3. 최소 redundancy — 가능한 한 높은 정규형(BCNF 이상)에 도달.

3.3 이론의 전체 지도

FD(+MVD) 주어짐
    │
    ├─ F⁺, α⁺ 계산 (§10)  ← 모든 후속 판정의 기초
    │
    ├─ Candidate key 도출
    │
    ├─ 정규형 판정
    │    ├─ BCNF? (§7)   ← 가장 엄격, redundancy 최소
    │    ├─ 3NF?  (§8)   ← 느슨, dep-preservation 보장
    │    └─ ... (4NF, 5NF는 MVD 기반)
    │
    └─ 위반 시 분해 알고리즘 적용 (§11)
         ├─ BCNF decomp: lossless ✓ / dep-preservation ✗ 가능
         └─ 3NF  decomp: lossless ✓ / dep-preservation ✓ 보장

3.4 BCNF vs 3NF — 왜 두 개가 필요한가

  • 이상적: BCNF (redundancy 최소).
  • 현실적 타협: 일부 스키마는 BCNF로 가면 dependency preservation이 깨져서 원래 제약을 여러 테이블 join으로만 검사 가능해짐 → 성능·일관성 비용.
  • 그래서 3NF가 **“lossless + dep-preservation + 거의 BCNF 수준의 정규화”**라는 절충점으로 제공됨.

한 줄 요약

Normalization = “redundancy를 제거하되(높은 정규형), 정보와 제약은 잃지 않는(lossless + dep-preservation) 분해를 찾는 이론.” FD는 이 모든 판정·알고리즘의 입력 언어이다.


4. Functional Dependencies (FDs)

= 함수 : i.e. x 정해지면 y도 deterministic함?

4.1 직관

현실에는 다양한 제약(rule)이 있다. 예: 대학 DB에서

  • 학생·교수는 ID로 유일 식별된다.
  • 각 학생·교수는 이름을 하나만 가진다.
  • 각 학생·교수는 기본적으로 하나의 학과에 소속된다.
  • 각 학과는 하나의 building·budget 값을 가진다.

모든 실세계 제약을 만족하는 릴레이션 인스턴스를 legal instance라 한다.

4.2 FD의 형식적 정의

릴레이션 스키마 에 대해 , 일 때,

hold on한다는 것은: 임의의 legal instance 에서 임의의 두 튜플 에서 일치하면 에서도 반드시 일치함. 즉,

예시 — 인스턴스 :

AB
14
15
37
  • hold (4→1, 5→1, 7→3 모두 일관) : 함수 관점.
  • hold 하지 않음 (A=1인데 B가 4도 5도 됨)

4.3 FD와 Key의 관계

  • superkey이다 ⇔
  • candidate key이다 ⇔ (1) , (2) 의 어떤 진부분집합도 을 결정하지 않음 ()
  • FD는 superkey로 표현할 수 없는 제약도 표현한다.

예시in_dep(ID, name, salary, dept_name, building, budget)

  • 성립: dept_name → building, ID → name
  • 성립하지 않음: dept_name → salary (같은 학과라도 급여는 다름)

4.4 FD의 활용

두 가지 목적:

  1. Legal 검사: 인스턴스가 주어진 FD 집합 아래에서 legal한지 검사 → satisfies .
  2. 제약 명시: legal 릴레이션 집합에 제약을 부과 → holds on.

주의: 특정 인스턴스가 우연히 어떤 FD를 만족한다고 해서 그 FD가 모든 legal 인스턴스에서 성립한다는 뜻은 아니다. 예: instructor 인스턴스에서 우연히 name → ID가 성립할 수 있지만, 일반적으로는 성립하지 않는다.

4.5 Trivial Functional Dependencies

모든 인스턴스에서 항상 성립하는 FD를 trivial이라 한다.

  • 예: ID, name → ID, name → name
  • 일반 규칙: 일 때 trivial.

4.6 Closure of a Set of FDs —

  • 주어진 FD 집합 로부터 논리적으로 함의되는 추가 FD들이 있다. 예: , 이면 .
  • 가 논리적으로 함의하는 모든 FD의 집합을 closure라 하며, 로 표기한다.

FD / / 세 층위 정리

층위타입예시
FD화살표 식 하나 (한 개의 주장)dept_name → building
FD들을 원소로 갖는 집합
로부터 Armstrong’s axioms로 연역 가능한 모든 FD의 집합

Span 비유: 선형대수 이 선형결합 규칙 아래 닫힌 최소 공간이듯, 는 Armstrong 규칙(reflexivity / augmentation / transitivity) 아래 닫힌 최소 FD 집합. 수학적으로는 closure operator — (extensive), monotone, idempotent .

Sound + Complete (§10.1)의 역할: “모든 legal instance에서 성립” ⇔ “에 속함”을 보장. 즉 **의미론(모든 테이블 조사)**을 **구문론(규칙 유도)**으로 환원 — 이게 없으면 FD 추론은 불가능한 무한 검사가 됨.

쌍둥이 주의 — vs (§10.5)

기호입력출력용도
FD 집합 FD들의 집합개념적 존재 (보통 전체를 만들지 않음)
속성 집합 (+ 고정된 )속성들의 집합실무 계산 도구, 다항시간

실무에선 를 직접 생성하지 않고 $\beta \subseteq \alpha^+$? 꼴의 membership test로 대체. BCNF 판정(§11.1)에서 “의 모든 FD 대신 각 원소의 만 보면 충분”한 이유가 바로 이것.


5. Lossless Decomposition — FD 기반 판정

표기 해설 — 가 무슨 뜻?

괄호 (...)는 tuple 표기 — 순서대로 나열한 구성 요소. 괄호 안에 무엇이 들어가느냐에 따라 의미가 달라짐.

표기괄호 안의미
속성 이름은 속성 로 이루어진 스키마” — 스키마 정의
부분 스키마분해했다” — decomposition

각 기호 정리 (§2.2에서도 정의됨):

  • : 원본 릴레이션 스키마 (속성 이름들의 집합). 예:
  • : 부분 스키마 — 각각 속성들의 부분집합
    • 조건: (두 조각을 합치면 원본 전체 속성)
    • : 공통 속성 (join의 연결 고리)
    • 예: , 로 분해 → 공통 속성은
  • (참고) : 스키마 인스턴스 — 실제 튜플이 담긴 테이블. 스키마는 “설계도”, 인스턴스는 “그 설계대로 만든 실제 데이터”

일 때, 다음 중 적어도 하나에 있으면 lossless decomposition:

직관: 공통 속성이 한쪽 전체를 결정하면, join이 원본 튜플만 복원.
아까 위에서 본 예제 그 상황? | join 시 한쪽이라도 primary.

예시

,

  • , 성립 → Lossless
  • , 성립 → Lossless

Notation: 의 축약.

대비 — lossless 비교

케이스분해판정
in_dep → instructor, department공통 dept_name이 department 전체 결정Lossless
employee → employee1, employee2공통 name이 어느 쪽도 결정 못 함Lossy

6. Dependency Preservation

6.1 맥락 — 왜 이걸 신경 쓰나

FD는 DBA가 “이 규칙은 항상 지켜져야 한다”고 선언한 법규야 (§4.4의 holds on). 법규는 매 INSERT/UPDATE마다 검사되어야 해. 문제는 검사 비용:

  • 분해 전 ( 한 덩어리): FD 의 모든 속성이 안에 있음 → SELECT 한 번으로 검사 끝. 싸다.
  • 분해 후 (): 만약 FD 하나의 속성이 여러 에 걸쳐 흩어지면 → 검사하려면 먼저 들을 JOIN해서 원래 모양 복원해야 함. 매 연산마다 JOIN = 비용 폭발.

핵심 질문

“분해 후에도 원래 의 모든 FD를 한 테이블 안에서 검사할 수 있나?”

  • 예 → Dependency Preserving
  • 아니오 (JOIN 필요) → NOT Dependency Preserving

6.2 정의 — 쉬운 말로

분해 dependency preserving이다 ⇔ 의 모든 FD를 각 안에서만 검사하여 원래 전체를 재구성할 수 있음.

엄밀히: 각 에 투영된 FD 집합을

로 정의할 때,

말로: “각 조각에서 발견되는 FD들을 합치면 원본 FD 전체가 함의된다”. 즉 쪼개도 제약의 정보 손실이 없음.

6.3 성공 예시 (Dep Preserving ✓)

세팅: , .
분해: , .

FD어디서 검사?
안에서 바로 ✓
안에서 바로 ✓

두 FD 모두 한 테이블 내에서 검사 가능 → Dependency Preserving.

6.4 실패 예시 (NOT Dep Preserving ✗) — 자세히

세팅: dept_advisor(s_ID, i_ID, dept_name)

실세계 의미:

  • i_ID → dept_name: 한 교수는 한 학과에만 소속
  • (s_ID, dept_name) → i_ID: 한 학생은 한 학과에서 한 명의 advisor만 가짐

원본 테이블 (분해 전):

s_IDi_IDdept_name
s1i1CS
s2i1CS
s3i2Physics

BCNF 위반 (i_ID는 superkey 아닌데 i_ID → dept_name 존재). 분해:

분해 후 테이블:

advisor_dept(i_ID, dept_name):

i_IDdept_name
i1CS
i2Physics

student_advisor(s_ID, i_ID):

s_IDi_ID
s1i1
s2i1
s3i2

이제 FD 2 (s_ID, dept_name) → i_ID 검사를 해보자:

  • 이 FD의 속성 s_ID, dept_name, i_ID세 속성이 세 군데에 흩어짐
    • s_ID: 에만
    • dept_name: 에만
    • i_ID: 양쪽 다
  • 어느 테이블도 세 속성을 함께 갖지 않음

구체적 시나리오: INSERT 두 개를 동시에 추가한다고 해보자:

  • student_advisor(s1, i3) 추가 (s1에게 advisor i3 지정)
  • advisor_dept(i3, CS) 추가 (i3는 CS 소속)

원본 FD 2 관점에서: 이제 s1이 CS에서 advisor i1과 i3를 동시에 갖게 됨 → 위반. 그런데 이걸 탐지하려면:

  1. student_advisor ⋈ advisor_dept JOIN → 원래 모양 복원
  2. JOIN 결과에서 (s_ID, dept_name) 그룹별로 i_ID가 유일한지 검사

매 INSERT마다 JOIN — 비용 폭발. 어떻게 분해해도 세 속성을 한 테이블에 담을 수 없음NOT Dependency Preserving.

6.5 왜 이게 현실 문제인가

  1. 제약 위반 탐지 불가능 or 극도로 느림 — 매 연산에 JOIN이 끼면 TPS 급감.
  2. SQL의 표현력 한계 — 표준 PK/FK/UNIQUE로는 multi-table 제약을 선언 못 함. ASSERTION이 있지만 거의 구현되지 않음 (§13 SQL과의 괴리).
  3. 일관성 보장 포기 — 실무에선 트리거나 애플리케이션 레벨 체크로 땜빵 → 코드 복잡도 ↑ + 버그 리스크 ↑.

6.6 BCNF와의 긴장 관계

이 예시가 보여주는 것:

  • dept_advisorBCNF로 가려면 dep preservation을 포기해야 함.
  • 반대로 dep preservation을 지키려면 BCNF를 포기하고 3NF에 머물러야 함 (§8에서 봄: 같은 스키마가 3NF에는 속함).

이게 BCNF vs 3NF 트레이드오프의 핵심 — BCNF는 중복 제거의 이상형이지만, 일부 스키마에서는 dep preservation과 양립 불가.

한 줄 요약

Dependency preservation = “쪼갠 뒤에도 원래 규칙들을 각 조각 안에서 검사 가능하게 남겨두는 속성”. 이게 깨지면 규칙 검사에 JOIN 필요 → 매 연산마다 비싸짐. BCNF와 항상 양립하진 않고, 3NF는 항상 양립.


7. Boyce-Codd Normal Form (BCNF)

7.1 정의

이 FD 집합 에 대해 BCNF에 있다 ⇔ 의 모든 FD (단, , )에 대해 다음 중 적어도 하나가 성립:

  1. 가 trivial ()
  2. 의 superkey

7.2 위반 예시

in_dep(ID, name, salary, dept_name, building, budget)

  • dept_name → building, budget성립
  • 그러나 dept_name은 superkey 아님 → BCNF 위반

분해:

instructor(ID, name, salary, dept_name)  ← BCNF
department(dept_name, building, budget)  ← BCNF

7.3 BCNF 분해 규칙

BCNF를 위반하는 FD 에 대해 을 두 스키마로 분해:

예시 — in_dep에서 , :

7.4 BCNF와 Dependency Preservation

  • BCNF와 dependency preservation을 동시에 달성하는 것이 항상 가능한 것은 아니다.
  • 예: dept_advisor(s_ID, i_ID, dept_name),
    • i_ID는 superkey 아님 → BCNF 위반.
    • 어떤 분해도 s_ID, dept_name → i_ID의 세 속성을 한 릴레이션에 두지 못함 → dependency preserving 아님.

8. Third Normal Form (3NF)

8.1 정의

3NF에 있다 ⇔ 의 모든 FD 에 대해 다음 중 적어도 하나 성립:

  1. 가 trivial ()
  2. 의 superkey
  3. 의 각 속성 어떤 candidate key에 포함 (각 속성은 서로 다른 candidate key에 속해도 됨)

관찰:

  • BCNF ⇒ 3NF (앞 두 조건이 BCNF와 동일).
  • 3번째 조건은 BCNF의 최소한의 완화로, dependency preservation을 보장하기 위해 도입.

8.2 3NF 예시

dept_advisor(s_ID, i_ID, dept_name),

  • Candidate keys: ,
  • BCNF 위반 (i_ID가 superkey 아님).
  • 그러나 3NF:
    • s_ID, dept_name → i_ID: 좌변이 superkey ✓
    • i_ID → dept_name: i_ID가 superkey는 아니지만, 이 candidate key의 일부 ✓

8.3 3NF의 Redundancy 잔존

R = (J, K, L), .
인스턴스:

JLK
null
  • 정보 중복: 이 반복.
  • null 필요: 관계를 표현하려면 에 null.

8.4 BCNF vs 3NF 비교

측면BCNF3NF
중복없음 (이상적)일부 허용
Dependency preservation보장 안 됨항상 달성 가능
Lossless달성 가능달성 가능
Null 값일반적으로 불필요필요할 수 있음

3NF의 장점: lossless + dependency preservation을 항상 동시에 달성 가능.


9. How Good is BCNF? — Multivalued 동기

inst_info(ID, child_name, phone) — instructor가 여러 자녀, 여러 전화번호를 가질 수 있음.

IDchild_namephone
99999David512-555-1234
99999David512-555-4321
99999William512-555-1234
99999William512-555-4321
  • non-trivial FD 없음 → 이미 BCNF.
  • 그러나 명백한 insertion anomaly: 새 phone 981-992-3443을 추가하려면 자녀 David, William 각각에 대해 두 튜플을 삽입해야 함.

해결 — Higher Normal Forms

분해:

  • inst_child(ID, child_name) = {(99999, David), (99999, William)}
  • inst_phone(ID, phone) = {(99999, 512-555-1234), (99999, 512-555-4321)}

이는 Fourth Normal Form (4NF) — multivalued dependency 기반. (Chapter 7.6에서 다룸)


10. Functional-Dependency Theory

10.1 Closure 계산 — Armstrong’s Axioms

Armstrong’s Axioms(건전 + 완전)로 를 계산:

규칙내용
Reflexive rule이면
Augmentation rule이면
Transitivity rule, 이면

성질:

  • Sound: 실제로 성립하는 FD만 생성.
  • Complete: 성립하는 모든 FD를 생성.

10.2 추가 규칙 (axioms로부터 유도 가능)

규칙내용
Union rule 그리고 이면
Decomposition rule이면 그리고
Pseudotransitivity rule 그리고 이면

10.3 예시

,

의 원소들:

  • — transitivity (, )
  • augment with , 그리고 와 transitivity
  • augment → ; augment → ; transitivity

10.4 계산 절차

F⁺ := F
repeat
    for each f in F⁺
        apply reflexivity and augmentation to f, add results to F⁺
    for each pair f₁, f₂ in F⁺
        if combinable by transitivity
            add result to F⁺
until F⁺ does not change

10.5 Attribute Set Closure

속성 집합 에 대해 하에서 로부터 함수적으로 결정되는 모든 속성의 집합을 closure 라 한다.

알고리즘:

result := α
while (changes to result) do
    for each β → γ in F do
        if β ⊆ result then
            result := result ∪ γ

10.6 예시 —

  1. result = AG
  2. 적용 → result = ABCG
  3. 적용 (CG ⊆ ABCG) → result = ABCGH
  4. 적용 → result = ABCGHI

AG가 candidate key인지 판정:

  1. Superkey 여부: ? —
  2. 어떤 부분집합이 superkey 인지: ?, ?
    • 각 크기 부분집합을 검사.

11. Algorithms for Decomposition

11.1 Testing for BCNF

비자명 FD 가 BCNF를 위반하는지:

  1. 를 계산.
  2. 의 모든 속성을 포함하는지 (즉 superkey인지) 확인.

Simplified test: 의 모든 FD를 검사할 필요 없이 의 FD만 검사하면 충분의 FD가 모두 BCNF를 준수하면 의 FD도 준수.

주의: simplified test는 자체를 검사할 때만 유효. 분해 후의 를 검사할 때는 만으로는 부정확.

  • 예: , . 검사 시 의 어느 FD도 의 속성만을 포함하지 않아 BCNF 같아 보이지만, 에 있는 로 인해 는 BCNF 위반.

11.2 BCNF Decomposition Algorithm

result := {R}
done := false
compute F⁺
while (not done) do
    if (there is a schema Rᵢ in result that is not in BCNF)
    then begin
        let α → β be a non-trivial FD holding on Rᵢ
            such that α → Rᵢ is not in F⁺, and α ∩ β = ∅
        result := (result − Rᵢ) ∪ (Rᵢ − β) ∪ (α, β)
    end
    else done := true

는 BCNF이며, 분해는 lossless-join.

11.3 BCNF Decomposition — 예시

class(course_id, title, dept_name, credits, sec_id,
      semester, year, building, room_number, capacity, time_slot_id)

FDs:

Candidate key: .

Step 1: 가 성립하지만 는 superkey 아님 → 분해

  • course(course_id, title, dept_name, credits) ← BCNF
  • class-1(course_id, sec_id, semester, year, building, room_number, capacity, time_slot_id)

Step 2: class-1에서 성립하지만 는 superkey 아님 → 분해

  • classroom(building, room_number, capacity) ← BCNF
  • section(course_id, sec_id, semester, year, building, room_number, time_slot_id) ← BCNF

11.4 Testing for 3NF

  • 의 FD만 검사해도 됨.
  • 각 FD 에 대해:
    • 가 superkey인지 (attribute closure로 검사) → OK
    • 아니면 의 각 속성이 어떤 candidate key에 포함되는지 검사.
  • candidate key 찾기는 expensive.
  • 3NF 검사는 NP-hard, 그러나 3NF 분해는 polynomial time에 가능.

11.5 3NF Decomposition Algorithm

Let Fc be a canonical cover for F
i := 0
for each functional dependency α → β in Fc do
    if none of the schemas Rⱼ (1 ≤ j ≤ i) contains αβ then
        i := i + 1
        Rᵢ := αβ
if none of the schemas Rⱼ contains a candidate key for R then
    i := i + 1
    Rᵢ := any candidate key for R
/* Optionally, remove redundant relations */
repeat
    if any schema Rⱼ is contained in another schema Rₖ
    then /* delete Rⱼ */
        Rⱼ = Rᵢ
        i = i − 1
return (R₁, R₂, ..., Rᵢ)

결과: 각 는 3NF이고, 분해는 dependency preserving + lossless-join.

11.6 3NF Decomposition — 예시

cust_banker_branch(customer_id, employee_id, branch_name, type)

FDs:

Canonical cover 계산: 첫 번째 FD에서 branch_name이 extraneous (두 번째 FD에 의해 이미 결정됨). → :

For loop으로 각 FD에 대해 스키마 생성:

Candidate key 포함 확인: 가 원 스키마의 candidate key 를 포함 → 추가 스키마 불필요.

Redundancy 제거: 의 부분집합 → 삭제.

최종 3NF 스키마:

FD 고려 순서에 결과가 의존하지 않는다.


12. Comparison of BCNF and 3NF — 정리

속성BCNF3NF
중복 제거완전부분
Lossless항상 가능항상 가능
Dependency preserving항상은 아님항상 가능
Null 값불필요필요할 수 있음

13. Design Goals

관계형 DB 설계의 목표:

  1. BCNF
  2. Lossless join
  3. Dependency preservation

이 셋을 모두 달성할 수 없으면 다음 중 하나를 수용:

  • Dependency preservation 포기 (BCNF 유지)
  • 3NF로 완화 (중복 허용)

SQL과의 괴리

  • SQL은 superkey 외의 FD를 직접 명시하는 방법이 없다.
  • Assertions로 표현 가능하지만 비용이 크고 (거의) 구현되지 않음.
  • Dependency preserving 분해라도, 좌변이 key가 아닌 FD를 효율적으로 검사할 SQL 수단이 없다.

14. 정규형 요약 테이블

Normal Form요구 조건 (각 비자명 에 대해)
1NF모든 속성이 atomic
2NF비주요 속성이 candidate key의 부분집합에 부분 의존하지 않음
3NF(1) 가 superkey, 또는 (2) 의 각 속성이 candidate key에 포함
BCNF가 superkey
4NFmultivalued dependency 기반 (Chapter 7.6)

포함 관계: .


15. 학습 포인트 — 알고리즘 흐름 정리

  1. 스키마와 FD 집합 가 주어진다.
  2. Candidate key를 찾는다 — 각 속성 부분집합의 closure를 계산하여 전체를 함의하는 최소 집합.
  3. Normal form 판정:
    • 각 FD 에 대해 BCNF/3NF 조건 확인.
  4. 좋은 form이 아니면 분해:
    • BCNF 분해 알고리즘 — lossless 보장, dependency preservation은 보장 안 됨.
    • 3NF 분해 알고리즘 — lossless + dependency preservation 보장.
  5. 검증: 분해 스키마들의 공통 속성이 한쪽을 결정하는지 확인 (lossless), 모든 FD가 한 릴레이션 안에서 검사 가능한지 확인 (dependency preservation).

출처: Database System Concepts, 7th Edition (Silberschatz, Korth, Sudarshan)