본문 바로가기
Infra & Security Eng/Database Engineering

모델링(판매전표 정규화 3단계 과정 실습, 각 단계별 해석과 개념설명) 실습_0326_2

by 엔지니어 E 2026. 3. 26.
반응형
판매전표의 판매전표는 주식별자가 될수도 있고, 되지 않을 수도 있다 (실무 에서) 
* 판매전표를 매장에서 관리: 주식별자 될 수 x, 중앙에서 관리: 주식별자가 될 수 o
(실습에서 내가 만드는 것이므로 판매전표는 주식별자 될 수 있음) 

 

1단계 정규화 전: 반복 그룹의 문제
이미지를 보면 **[제품1_번호, 제품1_명... 제품5_번호, 제품5_명]**까지 옆으로 쭉 늘어져있다. 이게 바로 **'반복 그룹(Repeating Group)'**이다.


데이터의 낭비(공간 문제)

상황: 어떤 손님이 제품을 딱 1개만 샀다
결과: [제품2]부터 [제품5]까지의 모든 칸(번호, 명, 단가, 수량, 금액)은 **빈칸(NULL)**으로 남는다
문제: 컴퓨터는 이 빈칸들도 저장 공간을 차지하게 설계하는 경우가 많아, 하드디스크가 쓸데없이 낭비된다

* 데이터는 열이 아닌 행으로 (가로로) 늘어난다




(사진 2개는 가로로 이어져있는 것)

정규화 과정(1단계)



정규화 과정(1단계)
데이터 낭비 뿐만아니라 데이터 한계, 조회 및 통계 문제가 발생할 수 있다. 그래서 1단계 정규화 적용으로 반복그룹을 제거한다(상자를 분리 한다) 

전표번호가 FK(외래키)인 이유: 상자를 분리했다고 생각했을 때 [판매상세] 상자에는 라면 1개, 콜라 2개 라는 데이터만 덩그러니 있다
문제: 이 라면이 어느 영수증(전표)에 붙어있는지 알 수가 없다
해결: 부모인 [판매전표]의 식별자인 [전표번호]를 복사해서 [판매상세]에 심어준다
이유: 그래야 나중에 1001번 전표의 상세내역을 다 가져오라고 했을때, 전표번호를 이정표 삼아 데이터를 찾아올 수 있다
판매전표 식별자만 적어놓고 그 식별자를 통해 판매전표 데이터에서 추출함

판매순번이 필요한 이유: [판매상세] 상자 입장에서 전표번호만을 가지고 누가 누군지 구분이 안된다 

만약 위 사진대로 판매순번 없이 전표번호만 적고, 1001번 전표의 라면을 불닭볶음면으로 바꾸고 싶다고 가정한다면 컴퓨터는 구분할 꼬리표가 없어서 라면, 콜라, 계란 전부 다 불닭볶음면으로 바꿔버린다 


판매 순번을 붙여 1001번 전표의 순번 1번만 불닭볶음면으로 바꾸라는 명령을 내리면 컴퓨터는 이제 정확히 1001-1인 첫번째 줄만  찾아가  라면을 불닭볶음면으로 바꿀 수 있게 된다

 

정규화 과정(2단계)
전제조건: 제 1정규화가 완료된 상태여야 함 
기본키(PK)가 2개 이상 속성으로 구성된 복합키(전표번호+판매순번)일때만 발생함. 둘 중 하나에만 종속되는 항목을 떼어내는 작업이다 (PK가 2개인데 그 중 하나에만 속성이 매달려 있는 놈들을 쳐낸다(?) 라고 보면 됨)

1. 상자분리: [판매상세]에서 제품 정보를 떼어내 [제품]상자를 만든다

* 완전 함수 종속: 수량과 금액은 전표번호와 판매순번 모두를 알아야 결정이 된다 
예시로 수량을 알고자하는데 전표번호만 알때 컴퓨터는 1001번 전표에서 라면(2개), 콜라(1개), 계란(1개) 세 줄을 찾아낸다. 문제는 전표번호만 아는게 아니라 몇번째줄(순번)인지까지 정해져야 수량을 정확히 알 수 있다 
전표번호와 판매순번을 모두 안다면 컴퓨터는 정확히 1001번 전표의 1번 줄로 찾아가서 2개라는 숫자를 딱 집어낸다 

* 부분 함수 종속: 제품명과 단가는 전표번호와 상관이 없다
예시로 말해서 편의점에서 신라면의 이름(제품명)과 단가는 오늘 팔렸는지, 누가 샀는지 상관없이 이미 진열대에서 정해져있기 때문에 전표번호에 의존하지 않고 제품번호에만 종속이 된다 

선과 기호 (판매상세, 제품 관계)
선: 점선 (제품이 없어도 전표는 존재할 수 있음 - 비식별 관계) 
제품측(까마귀발: --O<): 하나의 제품은 여러 전표에 팔릴 수 있음

 

작업: 기본키가 아닌 일반 속성 간의 종속성(고객번호 → 고객명, 매장코드 → 매장명)을 제거하여 별도 상자로 분리

3단계 정규화는 일반 속성들 사이의 서열 정리라고 보면 된다. 기본키(PK)가 아닌 일반 속성들끼리 서로 종속 관계가 있는지"**를 찾아내어 분리하 쉽게 말해 A가 B를 결정하고 B가 C를 결정하는 관계를 끊어주는 작업이다

정규화 과정(3단계) - 이행 함수 종속성 제거 
1. 기본키(PK)가 아닌 일반 속성들끼리 누가 누구를 결정하는지를 찾아내어 분리하는 단계임
이행 함수 종속 PK(전표번호) -> 속성A(고객번호) -> 속성B(고객명) 

위와 같은 구조에서 전표번호가 고객명을 직접 결정하는게 아니라 고객번호를 거쳐 (이행하여)결정되는 관계를 말한다 

예시로 데이터 구조는 전표번호가 나오면 -> 고객번호가 정해진다. 고객번호가 나오면 -> 고객명이 정해진다

전표번호는 고객의 이름이 무엇인지 직접 관심이 없다. 오직 누구(번호)가 샀는지만 기록한다. 고객명은전표와 상관없이 고객번호에만 종속되어 있는 정보이다. 따라서 전표번호와 고객명 사이에는 고객번호라는 징검다리가 껴 있는 것이다

전표번호는 고객번호만 결정하고, 고객명은 고객번호가 결정한다 (A->B, B->C) 


이런식으로 매장과 판매사원도 따로 상자를 생성하면 된다 
[매장]
전표번호 -> 매장코드 -> 매장명/위치
[판매사원]
전표번호 -> 사원번호 -> 사원명/직급

 

상자별 PK 설정 원리

상자명 기본키 (PK) PK 설정 원리 (왜 이게 PK인가?)
[제품] 제품번호 제품명은 중복될 수 있지만, 제품번호는 고유하여 단 하나의 제품 정보(단가 등)를 특정할 수 있음
[고객] 고객번호 동명이인이 있을 수 있으므로, 중복 없는 고객번호로 한 명의 고객을 식별함
[매장] 매장코드 매장명은 바뀔 수 있으나, 매장코드는 변하지 않는 고유 식별자임
[판매전표] 전표번호 영수증 한 장(Header)을 통째로 대표하는 유일한 번호임
[판매상세] 전표번호 + 판매순번 (복합키) 전표번호만으로는 여러 줄을 구별할 수 없으므로, **줄 번호(순번)**를 합쳐야만 한 줄이 유일해짐

 

각 상자와의 관계

1. 제품(1) --- 판매상세(N)
제품 쪽이 |인 이유:
판매상세에 신라면이라는 데이터가 기록될때 그 라면의 진짜 이름과 가격을 확인하러 [제품] 상자에 가면 정확히 1개의 신라면 정보만 있어야 한다 (같은 번호의 제품이 2개 있으면 컴퓨터는 어떤 가격을 적용할지 결정할 수 없다
판매상세 쪽이 -<(0 or many)인 이유: 하나의 제품(신라면)은 오늘 100명이 사갈 수도 있고, 내일 200명이 사갈 수도 있다. 즉, [판매상세] 상자에는 동일판 제품번호가 여러 번 등장할 수 있다

2.고객(1) --- 판매전표(N)

고객쪽이 |인 이유: 어떤 전표(영수증) 이 발행 되었을때, 그 영수증의 주인인 고객을 [고객] 상자에서 찾으면 반드시 1명의 고객만 나와야 한다. 한 장의 영수증 주인이 동시에 2명일 수 없다 
판매전표 쪽이 0<인(0 or many) 이유: 단골고객은 우리 매장에서 영수증(전표)를 수십장, 수백장 만들 수 있다 

3. [매장] (1) --- [판매전표] (N)
매장 쪽이 |인 이유: 특정 전표가 어느 맴장에서 결제되어있었는지 확인하면, 딱 그 매장 한곳만 특정되어야 한다
판매전표 쪽이 0<인(0 or many) 이유: 한 매장에서는 하루에도 수천 건의 전표가 발행 된다 

4. 판매전표(1) --- 판매상세(N)
판매 전표 쪽이 |인 이유: [판매상세]에 적힌 라면 2개라는 줄이 어느 영수증 거인지 확인하면, 무조건 1개의 전표번호와 연결되어야 한다
판매 상세 쪽이 0<인(0 or many) 이유: 영수증 한장에는 물건 목록이 라면, 콜라, 계란 등 여러줄이 들어갈 수 있다 

* 판매전표와 판매상세는 보통 실선으로 연결된다. 영수증(전표)없는 상세 내역은 세상에 존재할 수 없기 때문이다 
각 상자 설정하는 메커니즘 요약 매우중요함

1. 부모-자식 정하기: 정보를 주는 쪽(부모)과 받는 쪽(자식)을 정한다
정보를 주는 쪽이 부모, 그 번호를 받아서 자기 상자에 적는 쪽이 자식임
예: **[고객]**의 번호를 **[판매전표]**가 가져가서 적으므로, 고객이 부모이고 전표가 자식임


2. 선의종류(실선/점선): 자식이 부모의 번호를 이름(PK)으로 쓸것인지, 아니면 그냥 참고용(FK)으로만 쓸것인지 결정함 
부모 번호가 내 이름은 아니고, 그냥 **참고용 데이터(Attribute)**인 경우임
예: [판매전표] 상자 하단 일반 칸에 고객번호를 넣으면 점선임(전표의 이름은 전표번호일 뿐, 고객번호는 메모일 뿐임)

3. 기호(1:N): 자식 상자에 부모 번호가 여러 번 나올 수 있는지 보고 까마귀 발을 그린다