LabHub
배우기 러닝패스 코스

Database Concepts

Normalisation — The Rules That Remove Update Anomalies

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

한 줄 요약

정규화는 같은 사실이 여러 자리에 적히지 않게 표를 나누는 절차이고, 그렇게 하는 이유는 저장 공간이 아니라 갱신 이상을 없애기 위해서다.

Concept map: 갱신 이상 · 삽입 이상 · 삭제 이상 · 1정규형

왜 이게 필요했나

주문 표 하나에 고객 이름과 주소까지 함께 적어 두었다고 하자. 세 가지 문제가 생긴다.

정규화는 이 세 이상을 없애는 절차다. 공간을 아끼는 것은 부수 효과일 뿐이다.

어떻게 동작하나

실무에서 쓰이는 것은 대체로 3정규형까지다.

핵심은 규칙의 형태가 아니라 하나의 사실은 한 자리에만 적는다는 원리다. 이 원리를 지키면 갱신이 항상 한 곳에서 끝나므로 불일치가 구조적으로 불가능해진다.

함수 종속을 손으로 찾아보기

정규형의 정의는 전부 함수 종속 이라는 한 개념 위에 서 있습니다. A → B 는 "A 가 정해지면 B 가 하나로 정해진다" 는 뜻입니다. 표를 놓고 이 화살표를 그려 보면 정규형 판정이 기계적으로 됩니다.

주문 표를 예로 들겠습니다.

주문상세(주문번호, 상품번호, 수량, 상품명, 단가, 고객번호, 고객명, 고객주소)

키: (주문번호, 상품번호)

화살표를 그려 보면:
  (주문번호, 상품번호) → 수량          ← 키 전체에 종속. 정상
  상품번호 → 상품명, 단가              ← 키의 "일부" 에만 종속. 2정규형 위반
  주문번호 → 고객번호                  ← 키의 "일부" 에만 종속. 2정규형 위반
  고객번호 → 고객명, 고객주소          ← 키가 아닌 것에 종속. 3정규형 위반

화살표대로 표를 쪼갭니다. 왼쪽이 새 표의 키가 됩니다.

주문상세(주문번호, 상품번호, 수량)
상품(상품번호, 상품명, 단가)
주문(주문번호, 고객번호, 주문일)
고객(고객번호, 고객명, 고객주소)

이 절차에 판단이 들어갈 자리는 하나뿐입니다 — 화살표가 실제로 성립하는가. "우편번호 → 도시" 는 한국에서는 대체로 맞지만 예외가 있고, 미국에서는 ZIP 하나가 여러 도시에 걸치기도 합니다. 도메인 지식이 필요한 지점이 여기입니다.

정규형 요약표

정규형 없애는 것 한 줄 판정
1NF 반복 그룹, 다중값 한 칸에 값이 하나인가
2NF 부분 함수 종속 복합 키의 일부 에만 매달린 컬럼이 있나
3NF 이행 함수 종속 키가 아닌 컬럼이 다른 컬럼을 결정하나
BCNF 후보 키가 얽힌 예외 모든 결정자가 후보 키인가

BCNF 는 3NF 를 만족하는데도 이상이 남는 드문 경우를 잡습니다. 후보 키가 여럿이고 서로 겹칠 때 생기며, 실무에서 만나는 빈도는 낮습니다. 3NF 까지가 실전 입니다.

정규화가 성능을 해친다는 오해

"정규화하면 조인이 늘어 느려진다" 는 말은 절반만 맞습니다. 조인은 늘지만, 정규화된 표는 행이 짧아 한 페이지에 더 많이 들어가고 인덱스도 작습니다. 갱신은 한 곳만 건드리므로 훨씬 빠릅니다.

실제로 느려지는 경우는 대개 인덱스가 없는 것 이지 정규화 자체가 아닙니다. 외래 키 컬럼에 인덱스가 없으면 조인마다 전체 탐색이 일어납니다. PostgreSQL 은 기본 키에는 인덱스를 자동으로 만들지만 외래 키에는 만들지 않습니다. 이것을 모르고 "정규화 때문에 느리다" 고 결론 내리는 일이 흔합니다.

현장에서 만나는 모습

정규화는 기본값이지 종교가 아니다. 깨야 할 때가 있고, 그때 무엇을 대가로 내는지 알고 깨야 한다.

역정규화가 정당화되는 전형적인 경우는 집계값의 물리화다. 게시글의 댓글 수를 매번 세는 대신 컬럼에 유지하는 식이다. 대가는 분명하다. 두 곳의 값이 어긋날 수 있고 그것을 막는 책임이 애플리케이션으로 넘어온다. 어긋나는 경로는 하나가 아니다. 트리거를 우회한 대량 삭제, 트리거를 잠시 껐던 마이그레이션, 여러 코드 경로 중 하나의 누락.

그래서 역정규화를 도입할 때는 세 가지를 함께 남겨야 한다. 왜 깼는지, 무엇이 정합성을 보장하는지, 그리고 어긋났을 때 바로잡는 재계산 쿼리다. 세 번째를 미리 써 두지 않으면 사고 대응 중에 급조하게 된다.

인기 게시글에 댓글이 몰릴 때 같은 행을 모두가 갱신하려 해 잠금 경합이 생긴다는 점도 알아 둘 만하다. 대안은 증분을 별도 표에 추가만 하고 주기적으로 합산하거나, 애초에 정확한 실시간 값이 필요한지 다시 묻는 것이다. 대부분의 카운터는 5초 늦어도 아무 일도 일어나지 않는다.

이어지는 퀴즈에서 확인할 것

정규형의 정의를 외우는 대신, 어떤 이상 현상을 없애려는 것인지와 언제 깨는 것이 합리적인지 판단할 수 있는지 확인한다.