본문 바로가기
Book & Lecture Review/SQL 전문가 가이드

[SQL-1] 정규화란? - 제 1/2/3정규형

by iyos 2022. 3. 10.

 

 

정규화의 개념과 필요한 이유에 대해서 알아보자

 


 

1. 제1정규형 : 모든 속성은 반드시 하나의 값을 가져야 한다.

 

1) 잘못된 사례1 => 다중 값을 가지는 경우

다음과 같은 모델이 있다고 가정했을 때 발생할 수 있는 문제는 다음과 같다.

 

  1. 연락처 정보에서 집전화 번호와 핸드폰 번호를 구별할 수 없다.
  2. 집전화가 여러대인 '장소오'와 핸드폰번호가 여러개인 '장소삼'이 혼재되어잇기 때문에 원하는 데이터만 추출하기 어렵다.
  3. 이메일처럼 다른 유형의 데이터를 포함할 수도 있어 본연의 의미가 퇴색될 수 있다.

 

이와 같이 데이터를 관리한다면 '연락처' 속성의 의미는 퇴색될 것이고, 개발의 복잡성은 증가할 것이며 장기적으로 불안정한 데이터 구조를 양산할 것이다. 

 

사원번호 사원명 연락처
10001 장소이 010-1111-2222
10002 장소삼 010-2222-3333, 010-9999-3333
10003 장소사 010-4444-8888, 02-9999-2093
10004 장소오 02-1232-3535, 032-1232-9874

 

사원연락처라는 엔터티를 추가하면 다중 값에 대한 문제점을 해결할 수 있다. 고객의 연락처가 많아져도 아무런 문제가 되지 않는다. 

또한 '연락처 구분코드'라는 속성까지 추가한다면 이메일/휴대폰번호/집전화번호 등의 정보도 수용히 가능하고 더 명확하게 활용할 수 있다.

 

 

 

2) 잘못된 사례2 => 중복 데이터를 속성으로 분리하는 경우

 

중복데이터를 속성으로만 분리하면 어떨까? 아래와 같이 반복되는 속성을 가지게 될 것이다. 하나의 속성에 하나의 값만 들어가기는 하지만, 아래와 같은 문제점이 예상된다.

 

  1. 상품을 4개 이상 주문할 수 없다.
  2. 상품1, 상품2, 상품3을 모두 빠르게 조회하고 싶다면 속성마다 인덱스를 추가해야한다.

속성을 추가한다는 것은 테이블의 칼럼을 추가하는 것으로 대부분 DBMS에서 테이블 Lock을 발생시키고, 환경에 따라서는 사이트 중지가 필요할수도 있는 작업이다. 또한 위 경우엔 조회 성능을 위해 각 속성에 모두 인덱스를 추가해야하는데, 인덱스를 추가하는 것은 조회속도는 빨라질 수 있으나, 입력/수정/삭제 속도는 느려진다는 것을 고려해야 한다.

 

 

이 모델에서는 상품을 몇 개를 주문하던 아무런 제약을 받지 않는다. 또한 추가적인 인덱스도 필요 없다. 이와 같은 설계는 단순히 데이터 모델적 설계를 떠나 안정적인 서비스를 기여할 수 있다.

 

 

 

 


 

2. 제2정규형 : 엔터티의 일반속성은 주식별자 전체에 종속적이어야 한다

 

잘못된 사례 => 함수종속성을 고려하지 않은 경우

 

위에서 개선한 모델을 다시한번 보면, 중복해서 쌓이고 있는 데이터가 있다는 것을 발견할 수 있다. 

바로 '상품명'이다.

 

상품명은 주문번호와는 관계없이 오직 상품번호에 의해서만 결정된다. 이러한 것을 우리는 '종속적이다' 라고 한다. 

즉 '주문번호 + 상품번호'가 아닌 '상품번호'에만 종속성을 가지고 있다.

이때 기준값을 '결정자'라고 하고, 종속되는 값을 '종속자'라고 한다.

 

 

이러한 데이터는 어떤 문제점을 가질까?

 

  1. 상품명이 변경되어 업무적으로 반영해주어야 한다면, 주문상세 테이블의 상품명을 모두 변경해야 한다. 이때 많이 팔린 상품일부록 주문상세에서 변경해야 할 상품명의 부하도 크게 증가한다.
  2. 상품명을 면경한다고 해도 특정 시점에는 아직 변경되지 않은 상품명이 존재하고, 이때 들어온 트랜젝션은 일관되지 않은 데이터를 조회하게 된다.

 

​상품 엔터티를 추가하여 주문상세 엔터티의 부분 종속성을 제거할 수 있다. 이렇게하면 제2정규형을 만족하게 된다. 

 

 

 


 

3. 제3정규형 : 엔터티의 일반속성 간에는 서로 종속적이지 않는다

 

잘못된 사례 => 일반속성끼리 종속적인 경우

 

위의 경우에 주문테이블을 보자. 고객번호는 주문번호에 종속적이지만, 고객명은 고객번호에 종속적이다. 이는 '고객명이 주문번호에 종속적'임을 의미한다. 이것을 '이행적 종속'이라하고 이행적 종속을 배제하는 것을 제3정규형이라고 한다.

 

고객명이 식별자가 아닌 일반속성에 종속적인 제3정규형 위배에 해당한다. 이 모델에서의 문제점을 생각해보자

 

  1. 만일 고객이 이름을 바꾼다면 주문 엔터티에 고객명을 전부 갱신해야 한다. 이는 주문과는 전혀 연관 없는 트랜젝션이다. (고객명이 아닌 고객주소라고 생각하면 더 이해가 빠를 것이다.)
  2. 데이터 중복으로 인해 성능 부하 및 정합성 오류가 발생할 수 있다. 

 

 

위 모델과 같이 개선할 경우 고객 속성 변경이 주문 엔터티에 영향을 주지 않는 구조다. 또한 데이터 중복에 대한 문제도 개선되었다고 볼 수 있다. 

 

 


 

 

만일 비즈니스 도메인이 높은 모델이라면, 엔터티를 분리할 생각을 쉽게 할 수 없다. 이것을 위해 정규화를 배우는 것이다. 엔터티를 분리해야 하는 기준을 알고 있다면, 더 쉽게 데이터 모델링이 가능하다. 경험치에 기반한 직감적 모델링이 아닌, 근거가 명확한 모델링을 통해 더 나은 데이터 설계가 가능하다.

 

상황에 따라 반정규화를 진행할 수도 있다. 하지만 중요한 것은 기본적으로 정규화를 진행하고 나서 반정규화를 고려해야한다. 무분별한 반정규화를 방지할 수 있다.

 

 

 

반응형