노트

정규화 (1NF~5NF)

Database Normalization

백엔드#db · 연결된 개념 5개

쉽게 말하면

정규화는 친구 전화번호를 모임 명단마다 따로 적지 않고 연락처 한 곳에만 두는 것처럼, 같은 사실이 여러 곳에 중복되지 않게 표를 나누는 거예요. 번호가 바뀌어도 한 곳만 고치면 되죠.

비유가 깨지는 곳 표를 너무 잘게 나누면 조회할 때 조인이 늘어 느려져요. 그래서 실무에선 보통 3NF나 BCNF까지 하고, 읽기가 중요한 곳은 일부러 비정규화해서 중복을 맞추는 비용을 대신 져요.

정규화(normalization)는 테이블을 나눠 데이터 중복을 줄이고 삽입·삭제·갱신 이상을 막는 설계 과정이다. 각 단계(정규형, normal form)는 특정한 종속 관계를 없앤다. "도부이결다조"는 각 단계의 앞 글자를 딴 암기법이다.

단계조건없애는 것
1NF (도)모든 값이 원자값한 칸에 여러 값
2NF (부)1NF + 부분 함수 종속 없음복합키의 일부에만 종속
3NF (이)2NF + 이행 함수 종속 없음키가 아닌 컬럼을 거친 종속
BCNF(Boyce-Codd Normal Form) (결)모든 결정자가 후보키후보키가 아닌 결정자
4NF (다)BCNF + 다치 종속 없음독립적인 다중값의 조합
5NF (조)4NF + 조인 종속 없음분해·재조인 시 손실

예로 보기

  • 1NF 위반: 전화번호 칸에 010-1111-1111, 010-2222-2222 → 행을 나누거나 전화번호 테이블로 분리
  • 2NF 위반: 수강(학번+과목코드 → 성적) 테이블에 학생 이름이 있다. 이름은 학번에만 종속 → 학생 테이블로 분리
  • 3NF 위반: 사원(사번 → 부서코드 → 부서명) → 부서명은 부서 테이블로
  • BCNF 위반: 수강(학번, 과목, 교수)에서 "교수 → 과목"인데 교수가 후보키가 아님 → (학번, 교수)와 (교수, 과목)으로 분해
  • 4NF 위반: 학생의 동아리와 수강과목이 서로 무관한데 한 테이블에 모든 조합이 생김 → 두 테이블로

이상 현상

중복이 있으면 부서명 하나를 바꿀 때 여러 행을 고쳐야 하고(갱신 이상, update anomaly), 사원이 없으면 부서를 저장할 수 없으며(삽입 이상, insertion anomaly), 마지막 사원을 지우면 부서 정보까지 사라진다(삭제 이상, deletion anomaly).

어디까지 하나

실무에서는 보통 3NF나 BCNF까지 한다. 더 나누면 조인이 늘어 조회가 느려질 수 있어, 읽기가 중요한 곳은 의도적으로 비정규화(denormalization)하기도 한다. 그때는 중복된 값을 맞추는 비용을 대신 진다(DB 인덱스와 트레이드오프의 트레이드오프와 같다). 코드에서 같은 지식을 한 곳에만 두라는 DRY 원칙와 같은 생각이다.

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 코드 냄새

    당장 버그는 아니지만 이해나 변경 비용을 높이는 구조적 신호. 리팩터링을 언제 시작하고 멈출지에 정확한 공식은 없어서, 냄새라는 어휘로 직관을 공유한다.

  • 최종 일관성

    최종 일관성(eventual consistency)은 "지금 당장은 저장소마다 값이 다를 수 있지만, 새 변경이 멈추면 결국 같아진다"는 보장이다. 원본 DB와 검색 색인·캐시·다른 서비스처럼 물리적으로 분리된 저장소를 한 트랜잭션으로 묶을 수 없을 때 받아들이는 일관성 모델(consistency model)이다.

  • 구성요소 줄이기

    셀 수 있는 모든 구성요소(파일, 폴더 깊이, 클래스, 함수, 분기, 변수, 테이블, 필드, 테스트 케이스…)는 비용이라는 관점. 심플 디자인의 네 번째 규칙을 실무 기준으로 풀어낸 것이다.

  • 리팩터링 기법 카탈로그

    리팩터링 기법을 무엇을 정리하는지에 따라 묶어 본 지도. 기법마다 거의 항상 반대 방향 기법이 짝으로 있어서(추출↔인라인, 올리기↔내리기) 상황에 따라 양쪽으로 오간다. 아래 묶음은 Refactoring.Guru 카탈로그(1판 기반)의 분류를 따랐고, 기법 이름은 2판 기준으로 적었다.

  • 운영 Node 프로세스의 메모리 누수 찾기

    살아 있는 Node 서버에 inspector를 붙이고, 힙 스냅샷 두 장을 비교해 무엇이 쌓이는지, retainer로 누가 붙잡고 있는지 찾는 절차.

보기 옵션