학교/SQLD

[SQLD] 1.2.1 정규화

daykim 2024. 12. 18. 16:55

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


다중 값 문제

  • [연락처] 라는 속성이 있다고 가정하자.
    집전화번호, 휴대폰 번호 1, 2, 3,... 등 다중값(multivalued)이 들어갈수 있을것이다.
이름 연락처
만쥬 010-1234-1234, 02-1234-1234

이 경우 어떤 번호가 무엇인지 알 수 없다.
즉, 원하는 속성값을 추출하기 어렵다.

  • 명확하지 않은 속성은 다른 유형의 데이터를 포함할 수도 있어 본연의 의미가 퇴색될 수 있다.

이와 같이 데이터를 관리한다면

  • 개발의 복잡성 증가
  • 속성의 의미 퇴색
  • 장기적으로 불안정한 데이터 구조 양산
  • 개발의 오류 및 데이터 품질 문제

를 야기할 수 있다.

위와 같은 문제는 엔터티를 추가해 다중값에 대한 문제를 해결할 수 있다. (부모(사람), 자식(연락처) 테이블로 분리)
이처럼 다중값을 제거함으로써 속성을 명확하게 활용한다면 개발의 복잡성을 감소시킬 수 있다.

중복 데이터 문제

  • 정규 1유형은 다른 유형의 중복 데이터도 의미할 수 있다.
주문번호
# 주문번호
* 상품번호 1
* 상품번호 2
고객명

이러한 엔터티가 존재한다면 아래와 같은 문제가 발생할 수 있다.

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

위와 같은 엔터티는 상품을 2개까지만 주문할 수 있다.
만약 2개 이상을 주문하고 싶다면 속성을 매번 추가해야한다.
속성을 추가한다는 것은 테이블 칼럼을 추가하는 것으로 여러 문제가 발생될 수 있다.

또 인덱스를 추가하면 조회 속도는 빨라질 수 있으나 입럭, 수정, 삭제 속도는 느려질 수 있다.

이러한 경우 주문 - 주문상세 와 같이 엔터티를 추가하면 된다.

 

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


주문번호 상품번호 상품명
00001 3 일본여행
00002 5 유럽여행
00003 5 유럽여행
  • 위의 테이블을 보면, 상품번호와 상품명이 중복되는 데이터가 존재한다.
  • 하지만, 상품정보는 고객이 주문함으로써 발생하는 매핑 정보로서의 의미를 가진다.
  • 상품명은 주문번호와 상관 없이, 상품번호에 의해서만 결정된다.
  • 이러한 것을 '종속적' 이라고 한다.

 

함수종속성 (Functional Dependency)

  • 데이터들이 어떤 기준값에 의해 종속되는 현상을 지칭한다.
  • 결정자 (DETERMINANT) -> 종속자 (DEPENDENT)
    ex) 상품번호 -> 상품명
  • 결정자 : 기준값
  • 종속자 : 종속되는 값

 

부분 종속

  • 식별자 전체가 아닌 일부에만 종속적인 것
  • ex) 상품명 

 

이 때, 상품명은 일부에만 종속적이다.
주문상세의 식별자는 주문번호, 상품번호인데 주문번호에는 종속되지 않는다.
이는 제2정규형을 위배한 것이다.

  • 상품명이 변경된다면, 주문상세의 중복된 상품명을 모두 변경해야 한다.
    많이 팔린 상품일수록 변경해야할 상품명의 부하도 크게 증가한다.
  • 주문상세의 상품명을 변경한다 해도, 특정 시점엔 아직 변경되지 않은 상품명이 존재하고, 이 때 들어온 트랜잭션은 일관되지 않는 데이터를 조회하게 된다.

==> 데이터 중복은 정합성에 문제를 발생시킨다.

  • 위와 같이 상품 엔터티를 추가하면, 부분 종속성을 제거할 수 있다.
  • 상품번호를 매핑키로 활용해 상품명을 확인하는 구조로 관리하면 된다.
  • 상품명이 변경되어도, 데이터를 상품 엔터티에서 일원화해 관리하고 있어 중복 데이터에 대한 문제점도 해결할 수 있다.

 

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


  • 고객번호와 고객명은 주문번호에 종속적이라 제2정규형을 만족한다.
  • 고객명은 고객번호에 종속적이다.
  • 고객번호는 주문전호에 종속적이다.
  • 이것을 이행적 종속 (Transitive Dependency) 이라한다.
  • 이러한 이행적 종속을 배제하는 것이 제3 정규형이다.
  • 고객명이 식별자가 아닌 일반속성에 종속적이라 제 3 정규형을 위배했다.

 

  • 고객명이 변경된다면? 주문 엔터티에 고객명을 모두 갱신해야한다.
    이는 주문과는 연관 없는 트랜잭션이다.
  • 데이터 중복으로 발생하는 문제는 제 2정규형과 동일한 문제가 발생한다.

이러한 문제를 해결하려면 고객 엔터티를 분리해서 관리해야한다.

  • 추가로 주문 엔터티에서 고객번호가 Null 허용인 경우는 비회원 주문이 가능한 구조일 수 있다.

 

앞의 내용들은 이해하기 쉬운 모델로 설명했다고 한다.
비즈니스 도메인이 높은 모델이라면 이렇듯 쉽게 생각해 내기 어려울 수 있다.
그러나 지금까지 처럼 근거가 명확한 기준에 의한 모델링은 더 나은 데이터 설계를 가능하게 해주기 때문에,
정규화를 반드시 해야한다고 한다.

 

반정규화와 성능


반정규화

  • 정규화를 반대로 하는 것으로, 역정규화라고도 한다.
  • 반정규화는 성능을 위해 데이터 중복을 허용하는 것이다.
  • 하지만, 조회 성능을 향상시킬 수도 있지만 그로인한 입력, 수정, 삭제 성능은 저하될 수 있다.

 

반정규화의 성능 향상과 저하

  • p. 92
  • 엔터티에 반정규화를 통해 속성을 추가한다면, 특정경우 조인을 하지 않을 수 있게되어 조회 속도가 향상될 수 있을것이다.
  • 그러나 속성 추가로 인해 UPDATE와 같이 불필요한 로직이 추가된다면 배보다 배꼽이 더 큰 경우일 수 있다.
  • 정규화한 모델에 적절한 인덱스가 구성되었다면, 이점이 굉장히 미미하기 때문이다.
  • 클라우드 환경이라면 과금이 늘어나게 될 수 있다.
  • 그럼에도 불구하고 진행해야 할 만한 근거가 뒷받침이 될 때 진행해야 하는것이 반정규화이다.