| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- sql
- reversing
- 리버싱
- operating system
- Database
- reversing.kr
- 악성코드 분석
- 드림핵
- AWS 침해 사고 사례 분석
- python
- 운영체제
- crackme
- CrackMe 문제
- 버퍼 오버플로우
- 프로그래머스
- AWS 3 Tier Architecture
- 파일 시스템
- C
- network
- TryHackMe
- 네트워크
- terraform
- AWS
- 악성코드분석
- AWS 사고 사례 분석
- AWS 보안 아키텍처 분석
- AWS 침해사고 사례 분석
- programmers
- dreamhack
- Amazon S3
- Today
- Total
lhywk 님의 블로그
[DB] 정규화 - 이상 현상부터 BCNF까지 본문
1. 이상 현상
이상 현상(Anomaly)은 하나의 릴레이션에 어울리지 않는 여러 정보가 함께 묶여 있을 때, 데이터를 삽입하거나 삭제하거나 갱신하는 과정에서 발생하는 예기치 않은 문제를 의미한다. 다음과 같은 수강 릴레이션을 예로 들어보겠다.
| 학번 | 이름 | 학과 | 학과사무실 |
| 2024001 | 김민준 | 컴퓨터공학 | 공학관 401호 |
| 2024002 | 이서연 | 전자공학 | 공학관 502호 |
| 2024003 | 박지호 | 컴퓨터공학 | 공학관 401호 |
이 릴레이션은 학생 개인의 정보(학번, 이름)와 학과의 정보(학과사무실)가 한 릴레이션에 뒤섞여 있다. 이렇게 설계된 릴레이션에서는 다음과 같은 세 가지 이상 현상이 나타난다.
삽입 이상
삽입 이상(Insertion Anomaly)은 새로운 데이터를 삽입하려고 할 때, 불필요하거나 원하지 않는 다른 데이터까지 함께 입력해야 하는 문제이다. 위 릴레이션에서 만약 아직 학생이 한 명도 배정되지 않은 새로운 학과(예를 들어 신소재공학과)의 사무실 정보를 등록하고 싶다면, 학번이나 이름 같은 학생 정보가 없는 상태로는 튜플을 만들 수 없다. 학과 정보만 등록하고 싶어도 학생 정보가 강제로 따라붙는 구조이기 때문이다.
삭제 이상
삭제 이상(Deletion Anomaly)은 어떤 튜플을 삭제했을 때, 의도하지 않은 다른 정보까지 함께 사라지는 문제이다. 위 릴레이션에서 만약 이서연 학생이 자퇴해서 그 튜플을 삭제한다면, 전자공학과의 사무실 정보(공학관 502호)도 함께 사라지게 된다. 전자공학과 학생이 이서연 한 명뿐이었기 때문이다. 학생 한 명의 정보를 지웠을 뿐인데 학과 정보까지 잃어버리는 것은 분명히 바람직하지 않다.
갱신 이상
갱신 이상(Update Anomaly)은 중복 저장된 데이터 중 일부만 수정되어 데이터 간 불일치가 발생하는 문제이다. 위 릴레이션에서 컴퓨터공학과의 사무실이 공학관 405호로 변경되었다고 하자. 이 경우 김민준과 박지호의 튜플 모두에서 학과사무실 값을 변경해야 하는데, 만약 둘 중 하나만 변경하고 나머지를 빠뜨린다면 같은 컴퓨터공학과인데도 사무실 정보가 서로 다르게 나타나는 모순이 생긴다.
이러한 이상 현상이 발생하는 근본적인 원인은, 서로 다른 의미를 가진 데이터(학생 정보와 학과 정보)가 하나의 릴레이션에 부적절하게 섞여 있기 때문이다. 정규화는 바로 이런 문제를 해결하기 위해, 릴레이션을 적절한 기준에 따라 분해하는 과정이다.
2. 정규화의 단계

정규화(Normalization)는 함수 종속(Functional Dependency)이라는 개념을 기준으로 릴레이션을 분해하는 과정이다. 함수 종속이란 한 속성(또는 속성들의 조합)의 값이 다른 속성의 값을 결정하는 관계를 의미한다. 예를 들어 학번이 결정되면 그 학생의 이름도 자동으로 결정되므로, 이름은 학번에 함수적으로 종속되어 있다고 말한다.
정규화는 단계가 진행될수록 점점 더 엄격한 조건을 만족해야 하며, 상위 단계는 항상 하위 단계의 조건을 포함한다.

제1정규형 (1NF)
제1정규형은 모든 속성이 원자 값(Atomic Value)을 가져야 한다는 조건을 만족하는 정규형이다. 이는 릴레이션의 특징 중 속성의 원자성과 같은 의미이다. 만약 한 학생이 여러 개의 취미를 가지고 있어서 취미 속성에 "독서, 영화감상, 등산"처럼 여러 값이 함께 들어가 있다면 제1정규형을 만족하지 못한다. 이런 경우 취미 정보를 별도의 릴레이션으로 분리해서, 각 튜플이 하나의 취미 값만 가지도록 만들어야 한다.
제2정규형 (2NF)
제2정규형은 제1정규형을 만족하면서, 동시에 부분 함수 종속(Partial Functional Dependency)이 없어야 하는 정규형이다. 부분 함수 종속이란 기본키가 여러 속성으로 구성되어 있을 때, 기본키 전체가 아니라 그 일부에만 종속되는 속성이 있는 경우를 의미한다.
다음과 같은 수강 릴레이션을 예로 들어보겠다. 기본키는 (학번, 과목코드)이다.
| 학번 | 과목코드 | 학생이름 | 과목명 | 성적 |
| 2024001 | C101 | 김민준 | 데이터베이스 | A |
| 2024001 | C102 | 김민준 | 자료구조 | B |
| 2024002 | C101 | 이서연 | 데이터베이스 | A |
이 릴레이션에서 학생이름은 기본키 전체가 아니라 학번에만 종속된다. 마찬가지로 과목명도 기본키 전체가 아니라 과목코드에만 종속된다. 즉 학생이름과 과목명은 모두 부분 함수 종속을 가지고 있어서 제2정규형을 위반한다.
이를 해결하기 위해서는 부분 함수 종속을 가지는 속성들을 분리해서 별도의 릴레이션으로 만들어야 한다.
학생(학번, 학생이름) 과목(과목코드, 과목명) 수강(학번, 과목코드, 성적)
이렇게 분리하면 각 릴레이션 안에서는 기본키 전체에 완전하게 종속되는 속성들만 남게 된다.
제3정규형 (3NF)
제3정규형은 제2정규형을 만족하면서, 동시에 이전 함수 종속(Transitive Functional Dependency)이 없어야 하는 정규형이다. 이전 함수 종속이란 기본키가 아닌 일반 속성이 다른 일반 속성을 결정하는 관계, 즉 A가 B를 결정하고 B가 C를 결정해서 결과적으로 A가 C를 결정하게 되는 관계를 의미한다.
앞서 이상 현상을 설명할 때 사용했던 학생 릴레이션을 다시 살펴보자.
| 학번 | 이름 | 학과 | 학과사무실 |
| 2024001 | 김민준 | 컴퓨터공학 | 공학관 401호 |
이 릴레이션에서 학번은 학과를 결정하고, 학과는 학과사무실을 결정한다. 즉 학번이 학과사무실을 결정하긴 하지만, 그 사이에 학과라는 중간 매개체를 거치는 이전 함수 종속이 존재한다. 이 때문에 컴퓨터공학과 학생이 여러 명이면 학과사무실 정보가 중복 저장되고, 앞서 살펴봤던 삽입, 삭제, 갱신 이상이 발생하게 된다.
이를 해결하려면 이전 함수 종속의 매개체가 되는 속성을 분리해야 한다.
학생(학번, 이름, 학과) 학과(학과, 학과사무실)
이렇게 분리하면 학과사무실 정보는 학과 릴레이션에 단 한 번만 저장되고, 학생 릴레이션은 학과라는 외래키를 통해 그 정보를 참조하게 된다.
BCNF (보이스/코드 정규형)
BCNF(Boyce-Codd Normal Form)는 제3정규형보다 조금 더 엄격한 조건을 추가한 정규형이다. BCNF는 릴레이션에 존재하는 모든 결정자(다른 속성을 결정하는 속성)가 후보키여야 한다는 조건을 요구한다.
제3정규형까지는 만족하지만 BCNF는 만족하지 못하는 경우는, 후보키가 여러 개 존재하면서 그 후보키들이 서로 얽혀 있는 특수한 상황에서 발생한다. 예를 들어 한 강의실에서 특정 시간에는 한 과목만 열릴 수 있고, 한 교수도 특정 시간에는 한 강의실에만 있을 수 있는 상황을 가정해보자. 이런 경우 (시간, 강의실)이라는 조합과 (시간, 교수)라는 조합이 각각 후보키가 될 수 있는데, 동시에 강의실이 교수를 결정하는 관계(결정자이지만 후보키는 아닌 속성)가 존재한다면 BCNF를 위반하게 된다. 이런 상황은 실무에서는 비교적 드물게 나타나지만, 이론적으로 정규화의 가장 엄격한 형태를 보여준다는 점에서 의미가 있다.

3. 반정규화
정규화는 데이터의 중복을 줄이고 무결성을 지키는 데 효과적이지만, 릴레이션이 여러 개로 잘게 나뉘기 때문에 데이터를 조회할 때마다 여러 테이블을 조인해야 하는 단점이 있다. 테이블 수가 많아지고 조인이 빈번해지면 조회 성능이 떨어질 수 있다.
반정규화(Denormalization)는 이런 조회 성능을 개선하기 위해, 일부러 정규화된 릴레이션을 다시 합치거나 중복된 데이터를 의도적으로 추가하는 작업이다. 예를 들어 자주 조인해서 사용하는 두 릴레이션이 있다면, 조회 속도를 높이기 위해 한쪽 릴레이션에 다른 쪽의 일부 속성을 중복해서 저장해두는 방식이다.
다만 반정규화는 정규화의 장점(데이터 일관성, 중복 최소화)을 일부 포기하는 대신 조회 성능을 얻는 절충안이기 때문에, 신중하게 적용해야 한다. 데이터의 갱신이 자주 일어나는 시스템에서는 반정규화로 인한 데이터 불일치 위험이 커지므로, 조회가 압도적으로 많고 갱신이 적은 경우에 제한적으로 사용하는 것이 일반적이다.
'Database' 카테고리의 다른 글
| [DB] SQL 활용 - JOIN, 서브쿼리, GROUP BY, 윈도우 함수 (0) | 2026.06.24 |
|---|---|
| [DB] SQL - DDL, DML, DCL, TCL (0) | 2026.06.24 |
| [DB] 데이터 모델링 - ERD, 개체와 속성, 관계 (0) | 2026.06.24 |
| [DB] 관계대수 - 셀렉션, 프로젝션, 집합연산, 조인, 디비전 (0) | 2026.06.18 |
| [DB] 키와 무결성 제약조건 (0) | 2026.06.18 |