본문 바로가기
Tech/DB Design

정규화-2

by Augustine™ 2026. 7. 8.

하나의 칸에 여러 값을 넣으면 어떻게 될까

정규화에서 가장 먼저 피해야 할 것은 반복 값이다.

예를 들어 주문 테이블에 다음과 같이 상품명을 넣었다고 해보자.

주문번호: 1001
고객명: 김민수
상품명: 세제, 수건, 칫솔
수량: 2, 1, 3
결제금액: 35,000원

이 방식은 엑셀에서는 자연스러워 보인다.
사람이 눈으로 보면 이해할 수 있다.

하지만 데이터베이스 입장에서는 좋지 않다.

세제가 몇 개 팔렸는지 계산하기 어렵다.
수건만 포함된 주문을 찾기 어렵다.
상품별 매출을 계산하기 어렵다.
세제의 상품명을 수정하려면 문자열 일부를 고쳐야 한다.
상품 하나만 취소하거나 반품하는 것도 어렵다.

한 칸에 여러 값이 들어갔기 때문이다.

데이터베이스의 한 칸에는 하나의 값이 들어가는 것이 기본이다.

상품이 여러 개라면 컬럼을 늘리는 것이 아니다.
상품이 여러 개라면 행을 나누어야 한다.

그래서 다음과 같이 주문과 주문상품을 분리해야 한다.

주문은 주문 자체의 정보를 가진다.
주문상품은 주문에 포함된 상품 목록을 가진다.

주문에는 주문번호, 주문일자, 고객, 주문상태, 결제금액이 들어간다.
주문상품에는 주문번호, 상품, 수량, 주문당시가격이 들어간다.

이렇게 하면 하나의 주문에 여러 상품이 들어가도 자연스럽다.
상품별 판매수량도 계산할 수 있다.
일부 상품만 취소하거나 반품하는 것도 표현할 수 있다.

이것이 제1정규형의 출발점이다.

제1정규형은 어렵게 생각할 필요가 없다.
반복되는 값을 한 칸에 넣지 말라는 것이다.
여러 값이 반복되면 별도의 행으로 표현하라는 것이다.

고객 정보를 주문 테이블에 계속 넣으면 어떻게 될까

이번에는 고객 정보를 보자.

주문 테이블에 고객명, 연락처, 주소를 계속 저장한다고 해보자.

김민수라는 고객이 10번 주문하면 고객명도 10번 저장된다.
연락처도 10번 저장된다.
주소도 10번 저장된다.

처음에는 큰 문제가 없어 보인다.

하지만 고객 정보의 연락처가 바뀌면 문제가 생긴다.
10개의 주문 중 어떤 주문에는 예전 연락처가 남고, 어떤 주문에는 새 연락처가 남을 수 있다.

고객 주소가 바뀌어도 마찬가지다.

어떤 주소가 현재 고객 주소인지 알기 어렵다.
같은 고객인지 판단하기도 어렵다.
고객별 주문 이력을 조회할 때도 연락처나 이름으로 문자열 검색을 해야 한다.

이것은 고객 정보를 주문 테이블에 반복해서 넣었기 때문에 생기는 문제다.

고객은 독립적으로 관리해야 하는 대상이다.
고객은 고객명, 연락처, 이메일, 기본 배송지 같은 자기 속성을 가진다.
고객은 여러 주문과 관계를 맺는다.

따라서 고객은 주문의 컬럼으로 남기보다 별도 엔터티로 분리하는 것이 자연스럽다.

이렇게 하면 한 고객은 여러 주문을 가질 수 있다.
고객 정보는 고객 테이블에서 한 번만 관리된다.
주문은 어떤 고객이 한 주문인지 고객 식별자를 통해 연결된다.

중복이 줄어든다.
수정해야 할 위치도 명확해진다.

이것이 정규화의 중요한 목적이다.

정규화는 중복을 무조건 없애는 것이 아니다.
같은 사실을 여러 곳에 저장하지 않도록 하는 것이다.

상품명을 주문 테이블에 직접 적으면 어떻게 될까

상품도 마찬가지다.

주문 테이블에 상품명을 직접 입력한다고 해보자.

어떤 담당자는 “고급 수건”이라고 입력한다.
다른 담당자는 “고급수건”이라고 입력한다.
또 다른 담당자는 “수건 고급형”이라고 입력한다.

사람이 보면 같은 상품일 수 있다.
하지만 데이터베이스는 다르게 본다.

상품별 판매수량을 계산하면 세 개의 상품으로 나뉜다.
상품별 매출도 틀어진다.
상품명을 바꾸고 싶어도 어디까지 수정해야 할지 알기 어렵다.

상품은 주문의 단순 문자가 아니다.

상품은 판매 대상이다.
상품명, 판매가, 상품분류, 판매상태를 가진다.
주문과 관계를 맺고, 판매 통계의 기준이 된다.

따라서 상품도 별도 엔터티로 관리해야 한다.

다만 여기서 조심할 점이 있다.

상품의 현재 판매가와 주문 당시 판매가는 다를 수 있다.

오늘은 수건 가격이 10,000원일 수 있다.
다음 달에는 12,000원으로 오를 수 있다.
하지만 지난달 주문은 여전히 10,000원으로 남아야 한다.

따라서 주문상품에는 주문 당시 가격을 저장해야 한다.

상품 테이블의 판매가는 현재 기준 가격이다.
주문상품의 주문당시가격은 그 주문이 발생한 시점의 가격이다.

둘은 비슷해 보이지만 의미가 다르다.

의미가 다르면 위치도 달라야 한다.

정규화는 이런 차이를 구분하는 과정이다.

주문과 주문상품을 구분해야 하는 이유

주문과 주문상품은 비슷해 보인다.

그래서 초보자는 둘을 하나로 합치고 싶어 한다.

하지만 주문과 주문상품은 다르다.

주문은 고객이 한 번 구매 의사를 확정한 사건이다.
주문상품은 그 주문 안에 포함된 상품의 목록이다.

주문 하나에는 여러 주문상품이 들어갈 수 있다.
주문상품 하나는 특정 상품 하나를 가리킨다.

이 구분을 하지 않으면 다음 질문에 답하기 어렵다.

주문 1건의 총 결제금액은 얼마인가?
한 주문에 어떤 상품들이 포함되어 있는가?
상품별 판매수량은 얼마인가?
특정 상품만 취소되었는가?
특정 상품만 반품되었는가?
한 주문 안에서 어떤 상품은 배송되고 어떤 상품은 아직 배송되지 않았는가?

이 질문들은 모두 주문과 주문상품을 구분해야 답할 수 있다.

주문은 머리 정보다.
주문상품은 상세 정보다.

실무에서는 이런 구조를 마스터-디테일 구조라고 부르기도 한다.
하지만 용어보다 중요한 것은 의미다.

하나의 업무 사건이 있고, 그 안에 반복되는 상세 항목이 있으면 분리해야 한다.

주문과 주문상품은 그 대표적인 예다.

'Tech > DB Design' 카테고리의 다른 글

식별자 설계 - 2  (0) 2026.07.15
정규화-3  (0) 2026.07.08
정규화-1  (0) 2026.07.04
Entity 도출 실습-2  (0) 2026.06.21
Entity 도출 실습-1  (0) 2026.06.21

댓글