본문 바로가기
데이터베이스

정규화는 무엇이고 왜 필요할까?

by do_it! 2024. 10. 4.
728x90

정규화에 대한 쓴 기억...

찬 바람이 불기 시작하던 2023년 10월 쯔음, 판교에  개발자 면접을 보러 갔다. 1대 3 면접이였고, 1시간 가량의 면접이 진행되었다. 당시 이제 막 부트캠프 과정을 끝낸 햇 병아리, 아니 햇 달걀조차도 안되는 나에게 면접관은 정규화가 뭔지 설명하라고 했다. 햇 달걀인 나는 어설프게 대답하였다. 그렇게 면접은 끝났고 역시나 그 회사는 가지 못했다. 

 

정규화는 무엇이고 왜 필요할까?

정규화란 "테이블을 규정된 올바른 형태로 개선해나가는 것"이다. 이는 RDB가 효율적으로 동작하도록 만들기 위해 필요하다. "하나의 데이터는 한 곳에 있어야 한다."라는 정규화의 규칙을 기반으로 중복하거나 반복되는  부분을 찾아내서 테이블을 분할하고 기본키를 작성하는 것이다. 

위의 과정을 단계적으로 실시하는 것이 제 1정규형 , 제 2정규형 ,제 3정규형이다.

다음은 예제 테이블이다.

 

주문

주문번호 날짜 성명 연락처 주문상품
1 1/1 박준용 010-xxxx 0001 00 1개,0002 xx 10개
2 2/1 김재진 010-xxxx 0001 00 2개,0002 xx 3개
3 2/5 박준용 010-xxxx 0001 00 3개,0003 zz 1개

 

정규화의 목적은 뭐다? 중복하거나 반복되는 부분을 찾아내고 테이블을 분할하고 기본키를 작성하는 것이다.

 

제 1정규형 - 셀에 들어가는 값은 하나로! 테이블 분리와 키본키 정의

테이블의 하나의 셀에는 하나의 값만 저장할 수 있어야한다. 예제에서 주문상품 데이터를 보면 하나의 셀에 여러개의 값이 저장된 것을 볼 수 있다. 주문상품에 있는 데이터를 보고 주문상품 -> 상품코드,상품명,개수로 분리한다.

 

주문

주문번호 날짜 성명 연락처 상품코드  상품명 개수
1 1/1 박준용 010-xxxx 0001  00  1
1 1/1 박준용 010-xxxx 0002  xx 10
2 2/1 김재진 010-xxxx 0001 00 2
2 2/1 김재진 010-xxxx 0002 xx 3
3 2/5 박준용 010-xxxx 0001 00 3
3 2/5 박준용 010-xxxx 0003 zz 1

 

주문상품 데이터를 상품코드,상품명,개수로 분할하게 되면서 열이 추가 되었고 행도 늘어났다. 이렇게 하나의 셀에 하나의 값만 저장할 수 있도록 하고, 반복되는 부분을 세로 방향으로 제 1정규화의 제 1단계이다. 

제 1정규화에서는 중복을 제거하는 테이블의 분할도 이루어진다. 주문 테이블에 어떤 부분이 중복일까? 바로 주문번호,날짜,성명,연락처이다. 동일한 값을 가지는 행이 여러 개 존재하지 않도록 주문과 주문상품 2개의 테이블로 나눈다.

 

주문

주문번호 날짜 성명 연락처
1 1/1 박준용 010-xxxx
2 2/1 김재진 010-xxxx
3 2/5 박준용 010-xxxx

 

 

 

주문상품

주문번호 상품코드 상품명 개수
1 0001 00 1
1 0002 xx 10
2 0001 00 2
2 0002 xx 3
3 0001 00 3
3 0003 zz 1

 

주문 테이블을 보면 주문번호에는 중복된 값이 존재하지 않기 때문에, 주문번호를 기본키로 지정할 수 있다.

주문상품 테이블에서는 주문번화와 상품코드를 한데 묶어 기본키로 지정할 수 있다.

이처럼 제 1정규화에서는 반복되는 부분을 찾아내서 테이블을 분할하고 기본키가 될 열을 작성하는 것이다.

 

제 2정규형 - 기본키에 종속되어 중복되는 데이터가 있다면 테이블을 분리

제 2정규형은 기본키에 따라 중복되는 데이터가 없는지 조사하여 테이블을 분리하는 것이다.이 때 중복되는 데이터의 기준은 기본키에 종속되어 있느냐이다. 위에서 주문상품의 기본키는 주문번호화 상품명이라고 정의했다. 이 기본키에 따라 상품명 열에는 상품코드에 따라 값이 정해진다. 반면에 개수열에는 주문번호,상품코드와 상관 없이 값이 정해질 수 있다. 

 상품명 열에 상품코드에 종속된 데이터 값이 존재한다. 반면 개수 열은 주문번호나,상품코드에  종속된 데이터 값이 존재하지 않는다. 따라서 주문상품을 주문상품과 상품이라는 두 개의 테이블로 분리하였다.

 

주문상품

주문번호 상품코드 개수
1 0001 1
1 0002 10
2 0001 2
2 0002 3
3 0001 3
3 0003 1

 

상품

상품코드 상품명
0001 00
0002 xx
0003 zz

 

제 3정규형

마지막으로 제 3정규형이다. 이 또한 중복하는 부분을 찾아내어 테이블을 분할하는 방법이다. 제 2정규화는 기본키에 종속되어 중복되는 데이터를 분리하였다면, 제 3정규화는 기본키 이외의 부분에서 중복이 없는지를 조사하는 것이다.

 

 

주문

주문번호 날짜 성명 연락처
1 1/1 박준용 010-xxxx
2 2/1 김재진 010-xxxx
3 2/5 박준용 010-xxxx

 

주문 테이블을 보자면 성명,연락처가 중복되는 데이터가 있음을 알 수 있다. 따라서 주문 테이블을 고객 테이블과 주문 테이블로 나눌 수 있다. 

 

고객

고객번호 성명 연락처
1 박준용 010-xxxx
2 김재진 010-xxxx

 

주문

주문번호 날짜 고객번호
1 1/1 1
2 2/1 2
3 2/5 1

 

그런데 고객이라는 테이블이 꼭 필요할까? 중복이라는 관점에서 주문테이블을 보면 고객번호도 중복이다. 왜 고객 테이블로 나눌 필요가 있었을까?  이유는 관리에 용이하기 때문이다.

 

주문

주문번호 날짜 성명 연락처
1 1/1 박준용 010-xxxx
2 2/1 김재진 010-xxxx
3 2/5 박준용 010-xxxx

 

이 테이블에서 만약 박준용의 연락처 변경이 되어야 한다면, 1번 테이블과 3번 테이블의 연락처 변경을 해야한다. 2건이니 다행지만 몇 백, 몇 천건의 연락처를 변경해야한다면? 변경하기 매우 불편할 것이며, 연락처 변경을 놓치는 주문도 생길 수 있다.

 

고객

고객번호 성명 연락처
1 박준용 010-xxxx
2 김재진 010-xxxx

 

주문

주문번호 날짜 고객번호
1 1/1 1
2 2/1 2
3 2/5 1

 

그러나 주문 테이블을 주문 테이블과 고객 테이블로 나눈다면, 고객 테이블의 연락처만 변경하면 되니 관리하기 훨씬 용이해진다.

 

정리

정규화의 목적은 RDB를 효율적으로 이용하기 위함이다. 이를 위해서 데이터 중복을 최소화하는 정규화 과정을 거치는 것이다.

  1. 제 1정규형 : 하나의 셀에는 하나의 값만 -> 테이블과 기본키로 분리
  2. 제 2정규형 : 기본키에 종속되며 중복되는 데이터는 분리
  3. 제 3정규형 : 그 외에 중복되는 부분을 분리하여 데이터 유지보수성을 높이기