Soyeon Park 님의 블로그
데이터베이스 정규화 본문
0. 정규화는 왜 필요한가?
결론부터 말하자면 중복을 제거하기 위해서이다. 즉, 비일관성으로 인한 오류를 방지하기 위해서이다.
정규화를 하지 않았을 경우에 테이블이 일관적으로 관리되는 것이 어렵다.
참고로, 가용성을 중요하게 생각하는 NoSQL DB는 오히려 중복을 장려한다.
하지만 RDBMS의 경우에는 중복을 제거해야한다. 따라서 정규화가 필요하다.
정규화를 말하기 위해서는 함수 종속성이라는 개념이 필수적이다. 함수 종속성에 대해서는 앞서 따로 글을 썼다.
1. 정규화하지 않으면 발생하는 문제

현재 데이터베이스에 이 테이블 하나만 존재한다고 가정해보자.
정규화가 되지 않은 상태이다. 아래 3가지 상황에서 각각 어떤 문제가 발생하는지 보면서 정규화의 필요성을 명확하게 알게된다.
1.1 insert 시 문제
위와 같이 주문 내역 테이블 하나만 존재한다.
B11 이라는 책을 추가하고 싶다. 그런데, 이 책을 산 사람이 아직 없다. 그렇다면 책의 정보를 넣을 수 없게 되거나, 다른 attribute(name, age 등)의 값을 모두 null로 해서 행을 삽입해야 한다.
새로운 고객이 가입했다. 그런데, 아직 주문을 한 적이 없다. 고객 정보를 저장하기 위해서는 고객 정보와 관련된 id, name, age 필드만 채우고, 나머지는 null 값으로 삽입을 해야 한다.
이 상황들을 모두 억지로 insert를 발생시켜야 한다. 문제가 된다.
1.2 update 시 문제
B1 책의 가격이 올랐다. 책에 대한 정보가 update된 상황이다. 그런데, 테이블이 하나밖에 없으니 B1 책을 가지고 있는 모든 행의 price를 모두 update 해야한다. 만약 주문 정보가 엮여 있지 않은, 책 테이블이 있다면 B1 하나 행만 update 해주면 되는데 정규화가 되어있지 않으니 여러 행을 다 건들여야 하는 비효율성이 발생한다.
1.3 delete 시 문제
B2 책의 정보를 삭제해야 한다. 그런데, 지금 테이블이 주문 내역 테이블이기 때문에, B2 책을 지우기 위해서는 해당 row를 delete 해야 한다. 책의 정보만을 삭제하고 싶었는데, 주문 정보(고객 정보까지)가 지워지게 된다.
반대 상황도 동일하다. 어떤 고객의 정보를 지우려고 했는데, 책의 정보까지 지워지는 불상사가 발생한다.
결론적으로
정규화가 되지 않은 테이블에서 insert / update / delete 할 때 많은 문제가 발생한다.
그 이유는 테이블이 하나로 합쳐져 있기 때문이며, 중복 정보가 생기기 때문이다.
따라서, 정규화를 해야하는 이유는 중복 정보를 제거하기 위함이다.
지금부터는 이 단일 테이블을 어떻게 적절하게 나눌지 정규화에 대한 구체적인 내용을 다뤄보자.
2. 제 1정규화 (1NF)
1NF는 레코드가 atomic 해야 한다.

하나의 row에 2개 또는 3개의 정보가 들어가 있다. 이것은 atomic하지 않다.
하나의 row에는 하나의 정보만 들어가야 한다.

총 5개의 row 각각에 데이터가 하나씩 들어가도록 하였다. 이제 1NF를 만족한다.
3. 제 2정규화 (2NF)
2NF는 부분함수종속성을 제거해야 한다.
2NF의 조건은
1) 1NF을 만족한 상태에서
2) 기본키에 대해서 부분함수종속성이 없다.
부분함수종속성이란
기본키가 여러 속성으로 구성되어 있을 때, 종속자가 기본키의 일부분에만 종속되어있는 것을 말한다.

여기서 기본키는 (sid, cid)의 조합이다.
속성 중에 (sid, cid) 조합으로 결정되는 것이 아닌, sid로만 결정되거나, cid로만 결정되는 것이 있는지 보자.
sname, addr, major는 sid로만 결정된다.
title, iname, iloc은 cid로만 결정된다.
grade만 (sid, cid)의 조합으로 결정되고 있다.
2NF를 만족하기 위해서는 이러한 부분함수종속성을 제거해야 한다.
sid, sname, addr, major → table1
cid, title, iname, iloc → table2
sid, cid, grad → table3
이렇게 나누면 2NF 만족이다.

참고로, sid, cid로 하나씩 기본키가 잡혀있는 테이블에 대해서는 부분함수종속성을 논할 수 없다.. 부분함수종속성은 기본키가 두개 이상인 경우에 부분적으로 종속이 발생한다는 개념이기 때문이다.
4. 제 3정규화 (3NF)
3NF는 이행함수종속성을 제거해야 한다.
3NF의 조건은
1) 2NF를 만족한 상태에서
2) 이행함수종속성이 없다.
이행함수종속성이란
transitive(전이적)인 행이 있는지인데,
x(기본키), y, z 라는 3개의 속성에 대해서 x(기본키) → y, y → z 라는 종속 관계가 있을 경우 x → z가 성립되면 이행함수종속이 있다고 한다.
기본키가 아닌 속성이 다른 기본키가 아닌 속성을 결정하고 있는 경우이다.

2NF를 만족하고 있는 이 테이블에 대해서 이행함수종속을 찾아보자.
cid가 iname을 결정했는데, iname이 iloc을 결정하고 있다. 그리고 이때 cid가 iloc을 결정하는게 성립한다.
이행함수종속이며, 분리해줘야 한다.
여기서 헷갈렸던 부분은 sname이 addr를 결정하고, sname이 major를 결정하는 것도 이행함수종속이 아닌가라고 생각했다.
sid → sname, sname → addr, sid → addr로 보였기 때문이다. 하지만 데이터의 모양만 보고 판단하는 것이 아니라 도메인 규칙을 파악해야한다. sname → addr 일까? sname → major 일까? 아니다. A라는 이름을 가진 사람이 모두 반포에만 사는 것이 아니며, A라는 이름을 가진 사람은 무조검 컴공이 아니기 때문이다. 그러므로 함수 종속이 인정되지 않는다.
이제 3NF를 만족하도록 테이블을 나눠보겠다.

만약, 새로운 레코드가 들어왔는데, ME102에 대해서 iname이 I2이면, cid → iname이 만족하지 않으므로, transitive 하지 않다.
이런 경우, iname → iloc은 만족하고 있으므로 iloc을 수업 장소가 아닌 교수 연구실로 해석할 수 있게 된다.
5. 제 3.5정규화 (BCNF)
BCNF는 모든 결정자가 candidate key(후보키)가 되어야 한다.
BCNF는 Boyce-Codd Normal Form
3NF의 추가적인 버전이기 때문에 3.5NF로 불리며, 3NF보다 더 엄격하다.
3NF를 만족하는 테이블에 대해서 모든 결정자가 후보키가 되어야 한다.
BCNF의 조건은
1) 3NF를 만족한 상태에서
2) 모든 결정자가 후보키여야 한다.

함수종속성을 먼저 찾아보겠다.
(sid, major) → advisor
advisor → major
이때 두번째 관계에서 advisor가 후보키가 아니다. 그러므로, BCNF를 만족하지 못한다.
테이블을 분리해보자.

6. 제 4정규화 (4NF)
4NF는 다중값종속(다치종속)을 제거해야 한다.
4NF의 조건은
1) BCNF를 만족한 상태에서
2) 다치종속을 제거해야 한다.
다치종속이란
A가 B를 결정할 때, B속성이 여러개의 값을 가질 수 있는 경우를 말한다. 그리고 B에 해당하는 값들은 서로 독립적이어야 한다.
기호로는 A →→ B 로 표현한다.
예시를 보자.

course →→ instructor
course →→ textbook 인데, instructor와 textbook은 독립적이다. 다치종속이 발생했다.

7. 제 5정규화 (5NF)
5NF는 조인종속을 제거해야 한다.
중복을 제거하기 위해 분해할 수 있는만큼 전부 분해하는 것이라고 생각하면 된다.
5NF의 조건은
1) 4NF를 만족한 상태에서
2) 조인종속이 없어야 한다.
3) 조인연산을 했을 때 손실이 없어야 한다.
조인종속이란
여러 테이블을 조인할 때, 그 조인이 필수적이지 않거나 불필요한 중복 데이터를 만들 수 있는 경우에 발생한다.
모든 테이블이 최소한의 정보를 가질 수 있도록 분리하는데,
다시 조인을 했을 때 원래 데이터로 복원을 할 수 있어야 한다.
이때, 4NF에서 5NF로 바꿨을 때 4NF가 깨진다면 4NF에서 멈춘다.
오늘 배운 것을 정리해보면
1NF : 각 레코드가 atomic 해야 한다.
2NF : 부분함수종속성을 제거한다.
3NF : 이행함수종속성을 제거한다.
BCNF : 결정자는 모두 후보키여야 한다.
4NF : 다치종속을 제거한다.
5NF : 조인종속을 제거한다.
Reference
- 기초데이터베이스
'데이터베이스' 카테고리의 다른 글
| RAG ; Retrieval-Augmented Generation (0) | 2025.12.20 |
|---|---|
| 검색 엔진의 발전 과정 (0) | 2025.11.25 |
| 함수 종속성 (0) | 2025.11.12 |