정규화 (Normalization)
Overview
정규화(Normalization)는 데이터의 일관성, 최소한의 데이터 중복, 최대한의 데이터 유연성을 위해 데이터를 분해하는 과정입니다.
관계형 데이터베이스 설계에서 데이터의 중복을 최소화하고 무결성을 유지하기 위한 핵심적인 기법입니다.
목적
1. 데이터 중복 최소화
- 동일한 데이터의 반복 저장 방지
- 저장 공간 효율성 향상
- 데이터 일관성 유지
2. 데이터 무결성 보장
- 삽입 이상(Insertion Anomaly) 방지
- 갱신 이상(Update Anomaly) 방지
- 삭제 이상(Deletion Anomaly) 방지
3. 데이터 구조의 안정성
- 논리적이고 직관적인 데이터 구조
- 유지보수 용이성
- 확장성 및 유연성 확보
정규화 단계
정규화는 속성의 원자성 확보부터 시작하여 점진적으로 데이터 구조를 개선해 나가는 과정입니다. 개요에서 1~3+BCNF 예시 다이어그램을 그리면서 내용을 정리했습니다.
1정규화 (1NF: First Normal Form)
정의: 기본키 설정
조건:
- 모든 속성은 원자값(Atomic Value)을 가져야 함
- 반복 그룹(Repeating Group) 제거
- 각 행은 고유하게 식별 가능해야 함
적용 전 예시:
주문 테이블
-----------
주문ID | 고객명 | 상품목록
1 | 홍길동 | 사과, 바나나, 오렌지
2 | 김철수 | 우유, 빵
적용 후 예시:
주문 테이블
-----------
주문ID | 고객명 | 상품
1 | 홍길동 | 사과
1 | 홍길동 | 바나나
1 | 홍길동 | 오렌지
2 | 김철수 | 우유
2 | 김철수 | 빵
특징:
- 다중값 속성 제거
- 복합 속성을 단일 속성으로 분해
- 주식별자(Primary Key) 정의 필수
2정규화 (2NF: Second Normal Form)
정의: 기본키가 2개 이상 속성으로 이루어진 경우 부분함수 종속성 제거
조건:
- 1정규화를 만족해야 함
- 모든 비주요 속성이 기본키 전체에 완전 함수 종속되어야 함
- 부분 함수 종속(Partial Functional Dependency) 제거
부분 함수 종속이란? 복합키의 일부 속성에만 종속되는 경우를 의미합니다.
적용 전 예시:
수강 테이블
-----------
학생ID | 과목ID | 학생명 | 교수명 | 성적
---------------------------------------
S001 | C001 | 홍길동 | 김교수 | A
S001 | C002 | 홍길동 | 이교수 | B
S002 | C001 | 김철수 | 김교수 | B
- 학생명은 학생ID에만 종속 (부분 함수 종속)
- 교수명은 과목ID에만 종속 (부분 함수 종속)
적용 후 예시:
학생 테이블
-----------
학생ID | 학생명
S001 | 홍길동
S002 | 김철수
과목 테이블
-----------
과목ID | 교수명
C001 | 김교수
C002 | 이교수
수강 테이블
-----------
학생ID | 과목ID | 성적
S001 | C001 | A
S001 | C002 | B
S002 | C001 | B
3정규화 (3NF: Third Normal Form)
정의: 기본키를 제외한 칼럼간의 이행함수 종속성 제거
조건:
- 2정규화를 만족해야 함
- 이행적 함수 종속(Transitive Functional Dependency) 제거
- 비주요 속성 간의 종속성 제거
이행적 함수 종속이란? A → B이고 B → C일 때, A → C가 성립하는 간접적인 종속 관계를 의미합니다.
적용 전 예시:
사원 테이블
-----------
사원ID | 사원명 | 부서코드 | 부서명 | 부서위치
---------------------------------------------
E001 | 홍길동 | D01 | 영업부 | 서울
E002 | 김철수 | D02 | 개발부 | 판교
E003 | 이영희 | D01 | 영업부 | 서울
- 사원ID → 부서코드 → 부서명 (이행적 종속)
- 사원ID → 부서코드 → 부서위치 (이행적 종속)
적용 후 예시:
사원 테이블
-----------
사원ID | 사원명 | 부서코드
E001 | 홍길동 | D01
E002 | 김철수 | D02
E003 | 이영희 | D01
부서 테이블
-----------
부서코드 | 부서명 | 부서위치
D01 | 영업부 | 서울
D02 | 개발부 | 판교
BCNF (Boyce-Codd Normal Form)
정의: 기본키를 제외하고 후보키가 있는 경우, 후보키가 기본키를 종속함
조건:
- 3정규화를 만족해야 함
- 모든 결정자(Determinant)가 후보키(Candidate Key)여야 함
- 일반 속성이 후보키를 결정하는 경우 제거
적용 전 예시:
수업 배정 테이블
-----------
학생ID | 과목명 | 교수명
S001 | 데이터베이스 | 김교수
S001 | 알고리즘 | 이교수
S002 | 데이터베이스 | 김교수
- (학생ID, 과목명)이 기본키
- 하지만 교수명 → 과목명 종속 관계 존재 (한 교수는 한 과목만 담당)
적용 후 예시:
수업 배정 테이블
-----------
학생ID | 교수명
S001 | 김교수
S001 | 이교수
S002 | 김교수
교수-과목 테이블
-----------
교수명 | 과목명
김교수 | 데이터베이스
이교수 | 알고리즘
4정규화 (4NF: Fourth Normal Form)
정의: 여러칼럼(또는 하나의 칼럼)을 중복시키는 경우 분해하여 다중값 종속성을 제거
조건:
- BCNF를 만족해야 함
- 다중값 종속(Multi-Valued Dependency) 제거
- 독립적인 다중값 속성 분리
다중값 종속이란? 한 속성의 값이 다른 속성의 여러 값과 독립적으로 연결되는 경우를 의미합니다.
적용 전 예시:
교수 테이블
-----------
교수ID | 담당과목 | 연구분야
P001 | 데이터베이스 | 인공지능
P001 | 데이터베이스 | 빅데이터
P001 | 알고리즘 | 인공지능
P001 | 알고리즘 | 빅데이터
- 담당과목과 연구분야가 독립적으로 다중값 관계
적용 후 예시:
교수-과목 테이블
-----------
교수ID | 담당과목
P001 | 데이터베이스
P001 | 알고리즘
교수-연구분야 테이블
-----------
교수ID | 연구분야
P001 | 인공지능
P001 | 빅데이터
추가 설명:
- 다중값 종속 A ↠ B, A ↠ C가 있고 B와 C가 서로 독립적이면, 스키마 A(B C)는 4NF 위배
- 이때 A-B, A-C 두 관계로 분해하면 무손실 분해가 가능하며 중복이 제거됨
설계 팁:
- 설문, 취미, 기술스택 등 독립 다중값 속성은 별도 교차 테이블로 분리
- 다중값 속성 간 상호 제약이 있는지(독립성 위배)를 먼저 확인
5정규화 (5NF: Fifth Normal Form)
정의: 관계가 세 개 이상의 하위 관계로 조인될 때만 원래 관계가 복원되는 조인 종속(Join Dependency)을 만족하면, 해당 조인 종속을 기반으로 무손실 분해
조건:
- 4정규화를 만족해야 함
- 모든 유효한 조인 종속이 후보키에 의해 내재적으로 보장되지 않음
- 조인 종속을 만족하도록 분해해도 정보 손실이 없고, 중복이 더 이상 감소하지 않는 상태
조인 종속이란? 관계 R이 R1, R2, ..., Rn으로 분해되어 R = R1 ⨝ R2 ⨝ ... ⨝ Rn 이 항상 성립하는 경우를 의미합니다.
적용 전 예시:
공급(공급업체, 부품, 프로젝트)
------------------------------
S1 | P1 | J1
S1 | P2 | J1
S1 | P1 | J2
S2 | P1 | J1
- 비즈니스 규칙:
- 공급업체-부품 허용 쌍이 존재
- 공급업체-프로젝트 허용 쌍이 존재
- 부품-프로젝트 허용 쌍이 존재
- 세 쌍이 모두 허용되면 (공급업체, 부품, 프로젝트) 삼자 관계가 성립
- 원본 테이블은 이 조합들 때문에 중복과 삽입/삭제 이상이 발생 가능
적용 후 예시(무손실 분해):
공급업체_부품(공급업체, 부품)
-------------------------
S1 | P1
S1 | P2
S2 | P1
공급업체_프로젝트(공급업체, 프로젝트)
-------------------------------
S1 | J1
S1 | J2
S2 | J1
부품_프로젝트(부품, 프로젝트)
-------------------------
P1 | J1
P1 | J2
P2 | J1
- 세 관계를 조인하면 원래의
공급(공급업체, 부품, 프로젝트)을 정확히 복원 - 각 이항 관계 단위로 관리되어 중복 감소, 이상 현상 완화
주의사항:
- 5NF는 실무에서 빈도는 낮으나, 다:다:다 구조에서 중요한 무결성 이슈를 해결
- 세(또는 그 이상) 관계의 조합이 의미적으로 독립 조건을 충족하는지 반드시 검증
함수적 종속성 (Functional Dependency)
X가 Y를 결정한다, Y는 X에 함수적으로 종속된다
표기법: X → Y
의미:
- X 값이 결정되면 Y 값이 유일하게 결정됨
- X는 결정자(Determinant), Y는 종속자(Dependent)
함수적 종속성의 유형
1. 부분함수 종속성 (Partial Functional Dependency)
기본 키가 두 개 이상이 있는 경우, 일반 속성이 두 개 중 하나의 키에 함수적으로 종속되는 경우
예시: (학생ID, 과목ID) → 학생명
학생ID → 학생명 (부분 함수 종속)
2. 이행함수 종속성 (Transitive Functional Dependency)
기본키를 제외한 컬럼 간의 함수적 종속성 (일반 속성 간의 종속)
예시: 사원ID → 부서코드 → 부서명
사원ID → 부서명 (이행적 종속)
3. BCNF
일반속성이 특정키 중 하나를 종속시킬 때 (특정키 중 하나가 일반속성에 종속될 때)
예시: 교수명 → 과목명
(학생ID, 과목명)이 기본키인데, 교수명(일반 속성)이 과목명(키의 일부)을 결정
정규화의 장단점
장점
-
데이터 중복 최소화
- 저장 공간 절약
- 일관성 유지 용이
-
데이터 무결성 향상
- 이상 현상 방지
- 참조 무결성 보장
-
유지보수 효율성
- 데이터 수정 시 한 곳만 변경
- 확장성 증대
-
논리적 명확성
- 직관적인 데이터 구조
- 이해하기 쉬운 모델
단점
-
조인 연산 증가
- 쿼리 복잡도 증가
- 성능 저하 가능성
-
개발 복잡도 증가
- 테이블 수 증가
- 관계 관리 복잡
-
쿼리 성능 저하
- 여러 테이블 조인 필요
- 응답 시간 증가 가능
역정규화 (Denormalization)
정규화된 데이터베이스에서 성능 향상을 위해 의도적으로 중복을 허용하는 기법입니다.
역정규화가 필요한 경우
-
성능 개선
- 조인 연산이 과도하게 많은 경우
- 응답 시간이 중요한 조회 작업
- 대용량 데이터 처리
-
계산 속성
- 합계, 평균 등 집계 값
- 자주 계산되는 파생 속성
-
이력 관리
- 특정 시점의 데이터 스냅샷
- 감사 추적(Audit Trail)
역정규화 기법
1. 테이블 통합
-- 정규화된 구조
CREATE TABLE 주문 (주문ID, 고객ID, 주문일자);
CREATE TABLE 고객 (고객ID, 고객명, 연락처);
-- 역정규화 (빈번한 조회를 위해)
CREATE TABLE 주문 (
주문ID,
고객ID,
고객명, -- 중복 허용
연락처, -- 중복 허용
주문일자
);
2. 파생 컬럼 추가
CREATE TABLE 주문 (
주문ID,
고객ID,
주문금액,
할인금액,
최종금액 -- 계산 컬럼 (주문금액 - 할인금액)
);
3. 중복 테이블 생성
-- 원본 테이블 (정규화)
CREATE TABLE 거래내역 (...);
-- 집계 테이블 (역정규화)
CREATE TABLE 월별거래집계 (
년월,
총거래건수,
총거래금액,
평균거래금액
);
역정규화 시 주의사항
-
데이터 무결성 관리
- 트리거 또는 애플리케이션 로직으로 동기화
- 정기적인 데이터 검증
-
변경 관리
- 중복 데이터의 일관성 유지 방안 마련
- 명확한 갱신 규칙 정의
-
성능 측정
- 실제 성능 개선 효과 검증
- 모니터링 체계 구축
정규화 Best Practices
1. 적절한 정규화 수준 선택
- OLTP 시스템: 3정규화까지 적용 권장
- OLAP 시스템: 선택적 역정규화 고려
- 하이브리드: 용도에 따라 분리 설계
2. 성능과 무결성의 균형
정규화 수준 무결성 성능 복잡도
-------------------------------------------
1NF 낮음 높음 낮음
2NF 중간 중간 중간
3NF 높음 낮음 높음
BCNF 매우높음 매우낮음 매우높음
3. 단계적 접근
- 처음엔 3정규화까지 진행
- 성능 테스트 수행
- 필요시 선택적 역정규화
- 지속적인 모니터링 및 개선
4. 문서화
- 정규화 수준과 이유 명시
- 역정규화된 부분 명확히 표시
- 데이터 동기화 방법 문서화
교수기 과련번호를 결정
정규화 과정에서 자주 발생하는 실수와 해결 방법입니다.
고수기 1: 과도한 정규화
문제점:
- 필요 이상의 테이블 분리
- 과도한 조인으로 성능 저하
해결책:
- 비즈니스 요구사항 우선 고려
- 성능 테스트 기반 의사결정
고수기 2: 불충분한 정규화
문제점:
- 데이터 중복 발생
- 이상 현상으로 데이터 무결성 훼손
해결책:
- 최소 3정규화 적용
- 함수적 종속성 철저히 분석
고수기 3: 식별자 설계 오류
문제점:
- 자연키 사용으로 인한 복잡도 증가
- 복합키의 과도한 전파
해결책:
- 대리키(Surrogate Key) 활용
- 비즈니스 키와 기술 키 분리
학림(PK1), 과목번호(PK2), 교수
정규화 과정에서 키 관리는 매우 중요합니다.
주식별자 (Primary Key) 관리
특징:
- 유일성(Uniqueness) 보장
- NOT NULL 제약
- 변경 불가능성(Immutability) 권장
예시:
CREATE TABLE 수강 (
학번 VARCHAR(10), -- PK1
과목번호 VARCHAR(10), -- PK2
교수 VARCHAR(50),
성적 CHAR(1),
PRIMARY KEY (학번, 과목번호)
);
복합키 설계 시 고려사항
-
키의 크기
- 가능한 한 작게 유지
- 인덱스 크기 영향 고려
-
의미적 명확성
- 비즈니스 의미를 가진 키 선택
- 자연스러운 조합
-
확장성
- 미래 요구사항 변화 대비
- 유연한 구조 설계
실무 적용 사례
사례 1: 전자상거래 시스템
-- 3정규화 적용
CREATE TABLE 고객 (
고객ID VARCHAR(10) PRIMARY KEY,
고객명 VARCHAR(50),
이메일 VARCHAR(100)
);
CREATE TABLE 주문 (
주문ID VARCHAR(10) PRIMARY KEY,
고객ID VARCHAR(10),
주문일자 DATE,
배송주소 VARCHAR(200),
FOREIGN KEY (고객ID) REFERENCES 고객(고객ID)
);
CREATE TABLE 주문상세 (
주문ID VARCHAR(10),
상품ID VARCHAR(10),
수량 INT,
단가 DECIMAL(10,2),
PRIMARY KEY (주문ID, 상품ID),
FOREIGN KEY (주문ID) REFERENCES 주문(주문ID),
FOREIGN KEY (상품ID) REFERENCES 상품(상품ID)
);
-- 선택적 역정규화 (성능을 위해)
ALTER TABLE 주문 ADD COLUMN 주문총액 DECIMAL(12,2);
-- 트리거로 자동 계산 및 동기화
사례 2: 인사관리 시스템
-- 정규화된 구조
CREATE TABLE 사원 (
사원ID VARCHAR(10) PRIMARY KEY,
사원명 VARCHAR(50),
부서ID VARCHAR(10),
직급ID VARCHAR(10)
);
CREATE TABLE 부서 (
부서ID VARCHAR(10) PRIMARY KEY,
부서명 VARCHAR(50),
상위부서ID VARCHAR(10)
);
CREATE TABLE 직급 (
직급ID VARCHAR(10) PRIMARY KEY,
직급명 VARCHAR(50),
기본급 DECIMAL(10,2)
);
-- 역정규화 (빈번한 조회를 위해)
CREATE VIEW 사원상세정보 AS
SELECT
s.사원ID,
s.사원명,
d.부서명,
j.직급명,
j.기본급
FROM 사원 s
JOIN 부서 d ON s.부서ID = d.부서ID
JOIN 직급 j ON s.직급ID = j.직급ID;
관련 개념
- 엔터티 (Entity)
- 속성 (Attribute)
- 관계 (Relationship)
- 식별자 (Identifier)
- 참조 무결성 (Referential Integrity)
- 데이터 모델링 (Data Modeling)