데이터베이스 개념 · 정규화 · 이론
정규화 — 갱신 이상을 없애는 규칙
한 줄 요약
정규화는 같은 사실이 여러 자리에 적히지 않게 표를 나누는 절차이고, 그렇게 하는 이유는 저장 공간이 아니라 갱신 이상을 없애기 위해서다.
왜 이게 필요했나
주문 표 하나에 고객 이름과 주소까지 함께 적어 두었다고 하자. 세 가지 문제가 생긴다.
- 갱신 이상 — 고객이 이사하면 그 고객의 모든 주문 행을 고쳐야 한다. 하나라도 빠뜨리면 같은 고객의 주소가 두 가지가 된다.
- 삽입 이상 — 아직 주문하지 않은 고객은 등록할 자리가 없다.
- 삭제 이상 — 마지막 주문을 지우면 그 고객 정보까지 함께 사라진다.
정규화는 이 세 이상을 없애는 절차다. 공간을 아끼는 것은 부수 효과일 뿐이다.
어떻게 동작하나
실무에서 쓰이는 것은 대체로 3정규형까지다.
- 1정규형 — 모든 속성이 원자값이어야 한다. 한 칸에 쉼표로 여러 값을 넣지 않는다.
- 2정규형 — 1정규형이면서, 기본 키의 일부에만 종속된 속성이 없어야 한다. 복합 키일 때만 문제가 된다. 예를 들어
(주문번호, 상품번호)가 키인데상품명이 상품번호에만 종속되면 분리한다. - 3정규형 — 2정규형이면서, 키가 아닌 속성에 종속된 속성이 없어야 한다.
우편번호가도시를 결정한다면 그 관계를 별도 표로 뺀다.
핵심은 규칙의 형태가 아니라 하나의 사실은 한 자리에만 적는다는 원리다. 이 원리를 지키면 갱신이 항상 한 곳에서 끝나므로 불일치가 구조적으로 불가능해진다.
현장에서 만나는 모습
정규화는 기본값이지 종교가 아니다. 깨야 할 때가 있고, 그때 무엇을 대가로 내는지 알고 깨야 한다.
역정규화가 정당화되는 전형적인 경우는 집계값의 물리화다. 게시글의 댓글 수를 매번 세는 대신 컬럼에 유지하는 식이다. 대가는 분명하다. 두 곳의 값이 어긋날 수 있고 그것을 막는 책임이 애플리케이션으로 넘어온다. 어긋나는 경로는 하나가 아니다. 트리거를 우회한 대량 삭제, 트리거를 잠시 껐던 마이그레이션, 여러 코드 경로 중 하나의 누락.
그래서 역정규화를 도입할 때는 세 가지를 함께 남겨야 한다. 왜 깼는지, 무엇이 정합성을 보장하는지, 그리고 어긋났을 때 바로잡는 재계산 쿼리다. 세 번째를 미리 써 두지 않으면 사고 대응 중에 급조하게 된다.
인기 게시글에 댓글이 몰릴 때 같은 행을 모두가 갱신하려 해 잠금 경합이 생긴다는 점도 알아 둘 만하다. 대안은 증분을 별도 표에 추가만 하고 주기적으로 합산하거나, 애초에 정확한 실시간 값이 필요한지 다시 묻는 것이다. 대부분의 카운터는 5초 늦어도 아무 일도 일어나지 않는다.
이어지는 퀴즈에서 확인할 것
정규형의 정의를 외우는 대신, 어떤 이상 현상을 없애려는 것인지와 언제 깨는 것이 합리적인지 판단할 수 있는지 확인한다.