정규화와 함수 종속성
함수 종속성과 이상 현상을 기준으로 1NF·2NF·3NF·BCNF를 판정하고 반정규화의 적용 조건을 구분한다.
핵심 요약
함수 종속성과 이상 현상을 기준으로 1NF·2NF·3NF·BCNF를 판정하고 반정규화의 적용 조건을 구분한다.
핵심 질문
- 정규화와 함수 종속성를 실제 업무 사례에서 어떤 기준으로 판별하는가?
- 한 행이 나타내는 업무 사실과 유일성·필수성·변경 가능성은 무엇인가?
- 잘못 모델링하면 어떤 중복·이상 현상·변경 영향이 발생하는가?
- 여러 설계안 중 업무 의미와 변경 용이성을 가장 잘 보존하는 안을 어떻게 고르는가?
학습 목표
- 삽입·갱신·삭제 이상과 데이터 중복의 관계를 설명한다.
- 1NF·2NF·3NF·BCNF를 함수 종속성으로 판정한다.
- 반정규화를 측정 가능한 성능 문제에만 적용해야 하는 이유를 설명한다.
개념 지도
후보키·함수 종속성 → 이상 현상 → 정규형 분해 → 성능 측정 → 제한적 반정규화
핵심 내용
정규화는 업무 사실을 한 곳에 표현해 중복으로 인한 이상 현상을 줄이고 무결성과 변경 용이성을 높이는 논리 설계 과정이다.
| 단계 | 판정 기준 |
|---|---|
| 1NF | 모든 속성이 업무상 원자값 |
| 2NF | 1NF + 복합 후보키 일부에만 종속되는 부분 함수 종속 제거 |
| 3NF | 2NF + 일반 속성 사이의 이행 함수 종속 제거 |
| BCNF | 모든 결정자가 후보키 |
X → Y는 X 값이 같으면 Y 값도 하나로 결정된다는 뜻이다. 복합키 전체가 아닌 일부로 일반 속성이 결정되면 부분 함수 종속, Key → A → B처럼 일반 속성을 거쳐 결정되면 이행 함수 종속이다.
- 삽입 이상: 다른 사실이 없어 필요한 사실을 입력하지 못함
- 갱신 이상: 중복 행 일부만 바뀌어 값이 불일치함
- 삭제 이상: 한 사실을 지우며 다른 필요한 사실도 사라짐
반정규화는 조인·집계·반복 계산의 측정된 비용을 줄이기 위해 중복 컬럼, 요약 테이블, 테이블 통합·분할 등을 의도적으로 적용하는 설계다. 원천 데이터, 동기화 시점, 오류 복구와 DML 비용을 함께 정해야 한다.
흔한 오해와 주의점
- 정규화는 무조건 테이블 수를 늘리는 작업이 아니다.
- 2NF는 복합 후보키가 있을 때 부분 종속을 판단한다.
- 3NF와 BCNF의 차이는 결정자가 후보키인지까지 확인하는 데 있다.
- 반정규화는 인덱스보다 먼저 무조건 적용하는 해법이 아니다.
문항 풀이 보강: 표를 보고 정규형 판정하기
정규화 문제는 후보키와 함수 종속성을 먼저 적으면 안정적으로 풀린다.
수강지도(학번, 과목코드, 성적, 지도교수명, 학과명)
후보키: (학번, 과목코드)
(학번, 과목코드) → 성적
학번 → 지도교수명
학번 → 학과명
복합키 일부인 학번만으로 일반 속성이 결정되므로 부분 함수 종속이 있다. 1NF 상태에서 이를 분리하면 2NF로 진행한다.
수강(학번, 과목코드, 성적)
학생지도(학번, 지도교수명, 학과명)
일반 속성 사이에 관서번호 → 관서명·상태·등록일자 같은 종속이 있으면 그 사실을 별도 관서 테이블로 분리한다. 반복되는 증가재고1개월수량, 증가재고2개월수량처럼 기간별 컬럼을 계속 추가하는 구조처럼 같은 유형이 열로 반복되면 새 기간 값이 생길 때 컬럼을 계속 추가해야 하므로 행 구조로 전환할 1NF 위반 가능성을 검토한다.
이상 현상과 성능을 함께 읽기
정규화는 중복을 제거해 입력·수정·삭제 이상을 줄인다. 조인이 늘 수 있지만 중복 데이터 때문에 더 많은 블록을 읽던 SQL은 오히려 I/O가 줄 수도 있다. 성능 문제라는 말만 보고 곧바로 반정규화를 선택하지 않는다.
문제에 적용하는 순서
- 후보키를 찾는다.
- 결정자와 종속자를 화살표로 적는다.
- 반복 속성, 부분 종속, 이행 종속 순서로 확인한다.
- 분리 후 각 테이블의 주제가 하나의 사실인지 검증한다.
함수 종속성으로 분해하기
다음 주문상품 테이블을 가정한다.
ORDER_ITEM(
order_id, product_id,
order_date, customer_id,
product_name, unit_price, qty
)
PK = (order_id, product_id)
함수 종속성은 다음과 같다.
order_id → order_date, customer_id
product_id → product_name, unit_price
(order_id, product_id) → qty
order_date는 복합키 전체가 아니라 order_id 일부에만 종속되고, product_name은 product_id에만 종속된다. 이는 2NF 위반이다.
ORDERS(order_id, order_date, customer_id)
PRODUCT(product_id, product_name, unit_price)
ORDER_ITEM(order_id, product_id, qty)
분해하면 주문 날짜 변경을 상품 행마다 반복 갱신하는 이상이 사라진다.
3NF의 이행 종속
EMP(emp_id, dept_id, dept_name)
emp_id → dept_id
dept_id → dept_name
dept_name은 emp_id에 이행 종속되므로 DEPT로 분리한다. 분해 후에는 Lossless Join과 종속성 보존을 확인한다.
정규형 판단 순서
- 한 Column에 반복 그룹·다중값이 없는가? — 1NF
- 복합 후보키 일부에만 종속된 일반 속성이 없는가? — 2NF
- 일반 속성이 다른 일반 속성에 종속되지 않는가? — 3NF
- 모든 결정자가 후보키인가? — BCNF
성능 문제는 정규화를 건너뛰는 이유가 아니라 정규화된 원인을 이해한 뒤 측정 근거로 제한적 반정규화를 선택하는 단계다.
사례를 판별하는 순서
- 모델이 표현해야 하는 업무 사실과 행 단위(Grain)를 한 문장으로 정의합니다.
- 각 인스턴스를 유일하게 식별할 수 있는 후보와 변경 가능성을 확인합니다.
- 속성이 어느 사실에 종속되는지와 관계의 필수성·카디널리티를 확인합니다.
- 중복 저장으로 삽입·갱신·삭제 이상이 생기는지 검토합니다.
- 물리 성능을 이유로 구조를 바꿀 때 원천 데이터와 동기화·복구 규칙을 함께 설계합니다.
모델 품질 확인표
- 같은 업무 사실이 여러 곳에 중복 저장되지 않는가?
- 이름과 도메인이 한 가지 의미로 사용되는가?
- PK·FK가 실제 업무 관계와 선택성을 정확히 표현하는가?
- 현재 화면이나 프로세스에 과도하게 종속되지 않는가?
- 정규화와 성능 설계의 이유를 측정 가능한 근거로 설명할 수 있는가?
마지막 점검
- 화면의 입력 항목이나 현재 프로세스를 그대로 엔터티·관계로 옮기지 않습니다.
- 한 행의 업무 사실, 후보 식별자와 함수 종속성을 먼저 확정합니다.
- 중복과 비일관성을 만들면서 조회 편의만 얻는 설계를 정답으로 선택하지 않습니다.
- 반정규화와 물리 설계는 측정된 성능 문제와 동기화·복구 대책이 있을 때 적용합니다.
복습 문제
- 부분 함수 종속을 제거하는 단계는?
- 일반 속성 간 이행 종속을 제거하는 단계는?
- 반정규화 전에 반드시 확보해야 할 성능 근거는?
- 이 개념을 실제 업무 사례에서 판별할 수 있는가?