02. 데이터 모델과 SQL

2. 데이터 모델과 SQL

01. 정규화(Normalization)

데이터 정합성(데이터의 정확성과 일관성을 유지하고 보장)을 위해 엔터티를 작은 단위로 분리하는 과정.

입력, 수정, 삭제 성능은 일반적으로 향상된다고 볼 수 있다.

정규화를 하게 되면 엔터티가 계속 증가하므로 JOIN으로 인한 조회 성능 저하가 발생할 수 있다.


1) 제1정규형

모든 속성은 반드시 하나의 값만 가져야 한다.

  1. 하나의 속성에 여러 속성값을 갖는 경우.

    단점 : 불필요한 split 사용, 데이터 추출의 번거로움


    예시)

    ⬇️ 원본

    이름 나이 별명
    내동생 8 꿀돼지, 두꺼비, 왕자님

    ⬇️ 제1정규형화

    이름 나이
    내동생 8
    이름 별명
    내동생 꿀돼지
    내동생 두꺼비
    내동생 왕자님
  2. 유사한 속성이 반복되는 경우

    단점 : 계속해서 늘어나는 속성 추가, 공간의 낭비 발생 여지


    예시)

    ⬇️ 원본

    이름 나이 학원1 학원2 학원3
    내동생 8 피아노학원 영어학원 태권도

    ⬇️ 제1정규형화

    이름 나이
    내동생 8
    이름 학원
    내동생 피아노학원
    내동생 영어학원
    내동생 태권도

2) 제2정규형

엔터티의 모든 일반속성은 반드시 모든 주식별자에 종속되어야 한다. 주식별자가 단일식별자가 아닌 복합식별자인 경우 일반속성이 주식별자의 일부에만 종속될 수 있다. 이때 데이터 이상 현상이 발생할 수 있다.


주문번호(PK) 상품코드(PK) 수량 상품명
2023082801 A001 1 아메리카노
2023082801 A002 2 바닐라라떼
2023082802 A001 1 아메리카노
🔺주문번호와 상품코드가 주식별자인 경우

위의 경우 주문번호가 없는 상품은 입력 할 수 없는 입력 이상 현상, 상품명이 변경될 경우 해당 상품명에 대한 데이터가 모두 변경되어야 하는 수정 이상 현상이 발생한다.


⬇️ 제2정규형화
주문번호(PK) | 상품코드(PK) | 수량
:---:|:---:|:---:
2023082801 | A001 | 1
2023082801 | A002 | 2
2023082802 | A001 | 1


상품코드(PK) 상품명
A001 아메리카노
A002 바닐라라떼

3) 제3정규형

주식별자가 아닌 모든 속성 간에는 서로 종속될 수 없다.


상품코드(PK) 상품명 제조사코드 제조사명
A001 신라면 ABC 농심
A002 진라면 메운맛 AAA 오뚜기
A002 진라면 순한맛 AAA 오뚜기

일반속성인 제조사명이 다른 일반속성인 제조사코드에 종속되어있다.


⬇️ 제3정규형화
상품코드(PK) | 상품명 | 제조사코드
:---:|:---:|:---:
A001 | 신라면 | ABC
A002 | 진라면 메운맛 | AAA
A002 | 진라면 순한맛 | AAA


제조사코드 제조사명
ABC 농심
AAA 오뚜기

이행 함수 종속성을 제거한다.


4) 주의사항

지나친 정규화는 오히려 성능저하를 일으킬 수 있다.

특정 데이터의 연관 데이터를 조회하기 위해 여러 번의 JOIN을 해야 할 수도 있다. 이때 각 엔터티 간의 관계를 생성하여 성능을 개선할 수 있다.



02. 반정규화(De-Normalization)

데이터의 조회 성능을 향상시키기 위해 데이터의 중복을 허용하거나 데이터를 그룹핑하는 과정. 조회 성능은 향상될 수 있으나 입력, 수정, 삭제 성능은 저하될 수 있으며 데이터 정합성 이슈가 발생할 수 있다. 반정규화 과정은 정규화가 끝난 후 성능상 이슈가 있을때 고려한다.

1) 테이블 반정규화

  • 테이블 병합

    업무 프로세스상 JOIN이 필요한 경우가 많아 테이블을 통합하는 것이 성능 측면에서 유리한 경우 고려한다. 1:M 관계 테이블 병합의 경우 1쪽에 해당하는 엔터티의 속성 개수가 많으면 병합했을 경우 중복 데이터가 많아지므로 테이블 병합에 적절하지 못하다.

    (테이블의 관계가 강결합이어서 같이 조회되는 경우가 대부분일 경우 비정규화를 고려한다.)

    • 1:1 관계 테이블 병합

      회원정보 + 회원개인정보 => 회원정보

    • 1:M 관계 테이블 병합

      주문정보 + 주문상품상세정보 => 주문정보

    • 슈퍼 서브 타입 테이블 병합

  • 테이블 분할

    • 테이블 수직 분할(속성 분할)

      엔터티의 일부 속성을 별도의 엔터티로 분할(1:1 관계 성립)

      수직 분할 시 한 개의 블록에 더 많은 인스턴스를 저장할 수 있게 된다.

      (자주 사용하는 속성이 아니거나 대부분의 인스턴스가 해당 속성값을 NULL로 갖고 있을 때 고려한다.)

      월/일/기념일 => 월/일 기념일

    • 테이블 수평 분할(인스턴스 분할, 파티셔닝)

      엔터티의 인스턴스를 특정 기준으로 별도의 엔터티로 분할

      테이블의 수평 분할을 할 경우 관계가 없는 다수의 테이블이 생성된다.

      주문 => 2023주문, 2022주문

  • 테이블 추가

    • 중복 테이블 추가

      데이터의 중복을 감안하더라도 성능상 반드시 필요하다고 판단되는 경우 별도의 엔터티를 추가한다.

    • 통계 테이블 추가

      통계치를 미리 계산하여 저장

    • 이력 테이블 추가

      이력에 대한 데이터를 관리

    • 부분 테이블 추가


2) 컬럼 반정규화

  1. 중복 컬럼 추가

    업무 프로세스상 JOIN이 필요한 경우가 많아 컬럼을 추가하는 것이 성능 측면에서 유리할 경우 고려한다.

  2. 파생 컬럼 추가

    프로세스 수행 시 부하가 염려되는 계산값을 미리 컬럼으로 추가하여 보관하는 방식으로 상품의 재고나 프로모션 적용 할인가 등이 이에 해당할 수 있다.

  3. 이력 테이블 컬럼 추가

    대량의 이력 테이블을 조회할 때 속도가 느려질 것을 대비하여 조회 기준이 될 것으로 판단되는 컬럼을 미리 추가해 놓는 방식이다. 최신 데이터 여부 등이 이에 해당할 수 있다.


3) 관계 반정규화(중복관계 추가)

업무 프로세스상 JOIN이 필요한 경우가 많아 중복 관계를 추가하는 것이 성능 측면에서 유리할 경우 고련한다. 데이터의 무결성을 깨뜨릴 위험성 없이 데이터 처리 성능을 향상시킬 수 있는 기법이다.



03. 트랜잭션(Transaction)

데이터를 조작하기 위한 하나의 논리적인 작업 단위.

  • 게임 출석 이벤트 미션 달성
    • 게임 접속
    • 게임 메인 페이지
    • 게임 출석 API 호출
      • 출석 이력 저장
      • 저장 성공
      • 이벤트 성공 아이템 제공
      • 제공 성공
    • API 호출 응답

위와 같은 작업의 경우 아이템 제공에 실패 할 경우 아이템 제공 실패, 출석 이력 저장도 롤백되어야 한다.



04. NULL

NULL은 존재하지 않음, 값이 없음을 의미한다. 데이터가 입력되지 않아 NULL값이 된 것이다.

  • 가로연산(동일한 인스턴스 내 계산) : NULL이 포함되어 있는 경우 결과는 NULL이 된다.
  • 세로연산(다른 인스턴스와 계산) : NULL을 제외하고 계산한다.

NULL과의 비교 연산 결과는 늘 NULL이다.

tip! 성능 데이터 모델링

성능 데이터 모델링은 데이터베이스의 성능을 향상시키기 위해 설계 단계부터 성능과 관련된 사항들이 모델링에 반영될 수 있다.

tip! 성능 데이터 모델링의 순서

  • 데이터 모델에 맞게 정규화를 수행한다.
  • 데이터베이스의 용량 및 트랜잭션 유형을 파악하여 성능 저하를 일으키는 부분이 없는지 검토한다.
  • 용량과 트랜잭션 유형에 맞게 반정규화를 수행한다.
  • 성능 향상을 위한 이력모델의 조정, PK/FK 조정, 슈퍼/서브타입 조정 등을 수행한다.
  • 데이터 모델의 성능을 검증한다.

'SQLD' 카테고리의 다른 글

03. SQL 기본  (0) 2023.08.30
01. 데이터 모델링의 이해  (0) 2023.08.24