정규화(Normalization)는 관계형 데이터베이스에서 데이터 중복을 줄이고, 그 중복 때문에 생기는 이상현상(anomaly)을 없애기 위해 테이블을 단계적으로 분해하는 과정이다. 정처기 시험 단골이기도 하고, 실무에서 스키마를 설계할 때 실제로 쓰는 사고방식이다.
왜 필요한가 — 이상현상
한 테이블에 모든 걸 몰아넣으면 어떤 문제가 생기는지부터 보자. 수강 정보를 이렇게 저장했다고 하자.
| 학번 | 이름 | 과목 | 교수 | 교수연구실 |
|---|---|---|---|---|
| 101 | 김철수 | 자료구조 | 이영희 | A301 |
| 101 | 김철수 | 운영체제 | 박민수 | B205 |
| 102 | 정지원 | 자료구조 | 이영희 | A301 |
여기엔 세 가지 이상현상이 숨어 있다.
- 삽입 이상: 아직 수강생이 없는 새 과목을 넣으려면 학번을 억지로 채워야 한다.
- 삭제 이상: 김철수가 운영체제를 취소하면 “박민수 교수는 B205”라는 사실까지 함께 사라진다.
- 갱신 이상: 이영희 교수 연구실이 바뀌면 ‘자료구조’ 행을 전부 찾아 고쳐야 하고, 하나라도 놓치면 데이터가 어긋난다.
이 모든 원인은 하나의 테이블에 서로 다른 사실이 뒤엉켜 있다는 것이다. 정규화는 이 얽힘을 풀어낸다.
1NF — 원자값
제1정규형은 모든 속성이 원자값(atomic)이어야 한다. 즉 한 칸에 값이 하나만 들어간다. 만약 ‘과목’ 칸에 자료구조, 운영체제처럼 여러 값이 콤마로 들어 있다면, 행을 나눠 각 칸에 값 하나씩만 두어야 1NF다. 위 표는 이미 1NF를 만족한다.
2NF — 부분 함수 종속 제거
제2정규형은 1NF이면서, 기본키의 일부에만 종속되는 속성이 없어야 한다. 위 테이블의 기본키가 (학번, 과목)이라고 하자. 그런데 ‘이름’은 학번만으로 결정된다 — 과목과는 무관하다. 이렇게 키의 일부에만 매달린 걸 부분 함수 종속이라 하고, 이를 떼어낸다.
학생(학번, 이름)
수강(학번, 과목, 교수, 교수연구실)
3NF — 이행 함수 종속 제거
제3정규형은 2NF이면서, 키가 아닌 속성이 다른 비(非)키 속성을 통해 간접적으로 키에 종속되는 걸 없앤다. 수강 테이블에서 ‘과목 → 교수 → 교수연구실’로 이어진다. 교수연구실은 키(학번, 과목)에 직접 매달린 게 아니라 교수를 거쳐 결정된다. 이게 이행 함수 종속이다. 다시 분해한다.
수강(학번, 과목, 교수)
교수(교수, 교수연구실)
BCNF — 더 엄격한 3NF
BCNF(Boyce-Codd 정규형)는 3NF보다 조건이 강하다. 모든 결정자(determinant)가 후보키여야 한다. 결정자란 다른 속성을 함수적으로 결정하는 속성이다. 3NF를 만족해도, 키가 아닌 속성이 다른 속성을 결정하고 있으면 BCNF 위반이다. 예를 들어 한 과목을 여러 교수가 가르치되 한 교수는 한 과목만 맡는다면 ‘교수 → 과목’이 성립하는데, 교수가 후보키가 아니라면 BCNF를 어긴다. 이 경우 결정자를 기준으로 한 번 더 쪼갠다.
어디까지 할 것인가
정규화를 강하게 밀면 테이블 수가 늘고 조회할 때 조인이 많아진다. 그래서 실무에서는 보통 3NF를 기본 목표로 삼고, 성능이 절실하면 의도적으로 중복을 허용하는 반정규화(denormalization)를 거꾸로 적용하기도 한다. 정규화의 각 단계가 “무엇을 없애려는 것인지”를 이해하면, 시험에서도 실무에서도 판단의 기준이 생긴다.
이 글에 대한 의견은 아래 댓글로 남겨주세요 (GitHub 계정 필요). 로그인 없이 남기고 싶다면