SQLD 공부 PART 1 - CH2. 데이터 모델과 SQL

SQLD - Week 2 - Part1 - CH2. 데이터 모델과 SQL

1. 성능 데이터 모델링

  • 데이터베이스의 성능을 향상시키기 위해 설계단계부터 성능과 관련된 사항이 모델링에 반영될수 있도록 하는것
  • 방법으로 정규화, 반정규화, 테이블통합, 테이블 분할 등이 있음

    순서

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

2. 성능데이터 모델링 방법

정규화

  • 논리 데이터 모델의 일관성을 확보하고 중복을 제거해서 속성들익 가장 적절한 엔터티에 배치하는것
  • 중복데이터를 허용하지 않는 방식으로 테이블을 설계하는 방식
  • 데이터 정합성(데이터의 정확성/일관성을 유지&보장)을 위해 엔터티를 작은 단위로 분리하는 과정
    • 함수 종속성을 고려해 이상 현상이 생기지 않도록 테이블 분할(반정규화X)
  • 지나친 정규화는 성능저하를 일으킴

함수 종속성 Functional Dependency

  • 함수처럼 어떠한 값을 통해 종속 관계에 있는 다른 값을 유일하게 결정할수 있다
    • e.g. 테이블에 [생일], [나이]라는 컬럼이 존재할때
      • [나이]는 [생일]에 종속한다 : 생일을 알고 있으면 나이를 참조하지 않아도 나이를 결정할수 있음
  • 데이터베이스 설계단계에서 함수 종속 관계를 찾으면 중복된 데이터를 줄일수 있음

함수 종속의 성질(암스트롱의 공리 Armstrong’s axioms)

  • augmentation : X → Y이면, XZ → YZ
  • transitivity : X → Y이고 Y → Z이면, X → Z
  • reflexivity : Y $\sub$ X, X → Y
  • self-determination : X → X (자기 자신은 자신에 의해 함수 종속적이다)
  • union : X → Y이고 X → Z이면, X → YZ
  • decomposition : X → YZ이면, X → Y이고 X → Z

정규화 단계

  1. 제1정규형(1 Normal Form: 1NF) : 엔터티의 모든 속성은 반드시 하나의 값만 가져야 한다
    • 유사한 속성이 반복되면 -> 1차 정규화!
    • 테이블의 컬럼은 하나의 값(원자값)을 갖도록 테이블 분해
  2. 제2정규형(2 Normal Form: 2NF) : 엔터티의 모든 속성은 반드시 모든 주식별자에 종속되어야한다
    • 어떤 속성이 일부 주식별자에만 종속되어있다면 -> 2차 정규화!
    • 부분 함수 종속성 제거 : 완전 함수 종속 만족
      • 릴레이션에서 종속자가 기본키가 아닌 다른 속성에 종속되거나, 기본키가 여러 속성으로 되어있을때
        • 기본키를 구성하는 속성 중 일부만 종속된 경우
  3. 제3정규형(3 Normal Form; 3NF) : 주식별자가 아닌 모든 속성간에는 서로 종속될수 없다
    • 2차 정규화를 진행한 테이블이행적 종속이 없도록 테이블을 분해하는 것
      • 이행적 종속 : A → B, B → C 성립할때 A → C가 성립하는 것
    • 이행함수 종속성 제거
    • 속성간에 종속되어있다면 -> 3차 정규화!
      • 기본키가 있는데 일반속성이 일반속성을 결정하는 경우
  4. 제4정규형 : 다중값 종속성 제거 -> 4차 정규화!

반정규화

  • 데이터 조회 성능 향상을 위해 데이터 중복을 허용/데이터를 그룹핑 하는 과정
  • 정규화 작업 이후에 수행
    • 정규화 작업 이후에 성능상의 이슈가 있으면 실행!
  • 데이터 무결성 저해 가능성 있음 : 디스크 I/O량 감소, 긴 경로의 조인으로 인한 성능저하 해결
  • 조회(SELECT) 속도는 향상시키지만, 데이터모델의 유연성은 낮아짐

반정규화 조건

  • 여러번의 JOIN으로 성능이 저하되는 것을 방지하기 위해
  • 모델링의 마지막 단계에서 성능을 향상시키기 위해
  • 런타임에 컬럼 계산으로 인한 속도 저하가 우려될 경우
  • 다량의 범위를 자주 처리해야하는 경우
  • 특정 범위의 데이터만 자주 처리하는 경우
  • 요약/집계 정보가 자주 요구되는 경우

기법

  1. 테이블 반정규화
    • 테이블 병합 : 업무 프로세스상 JOIN이 많을때
      • 1:M 관계 테이블 병합 : 1쪽에 해당하는 엔터티 속성 개수가 많으면 중복데이터가 많아질수있음
      • 슈퍼/서브타입 테이블 병합
    • 테이블 분할
      • 테이블 수직 분할 : 엔터티 일부 속성을 별도의 엔터티로 분할(1:1 관계 성립)
        • 자주 사용하는 속성이 아니거나
        • 대부분의 인스턴스가 해당 속성값을 NULL로 갖고있을떼
          • e.g. 한 테이블에 속성 개수가 과도하게 많을경우 조회 성능 향상을 위해 수직분할 수행
            • 자주 쓰이는 속성/아닌 속성
            • 분할된 테이블은 1:1 관계 성립
      • 테이블 수평 분할 : 엔터티의 인스턴스를 특정 기준으로 별도의 엔터티로 분할(파티셔닝)
        • 주로 ‘기간’을 기준으로 분할
        • 관계없는 다수의 테이블이 생성될수 있음
    • 테이블 추가
      • 중복 테이블 추가 : 중복을 감안하더라도 성능상 필요한 경우 별도 엔터티 추가
      • 통계 테이블 추가
        • e.g. 주문 데이터를 이용 -> 월매출 테이블에 통계치를 미리 계산해서 저장
      • 이력 테이블 추가
        • e.g. 상품 이력 테이블 -> 과거의 상품가격에 대한 데이터 관리
      • 부분 테이블 추가
        • e.g. 회원 대상 메일 발송건이 다량 생기는 경우 -> 메일 발송에 필요한 정보만 부분 테이블[^1]로 생성
  2. 컬럼 반정규화
    • 중복 컬럼 추가 : 업무 프로세스상 JOIN이 많이 필요한 경우
    • 파생 컬럼 추가 : 프로세스 수행시 부하가 염려되는 계산값을 따로 컬럼에 추가해서 보관
      • e.g. 상품 재고, 프로모션 적용 할인가
    • 이력 테이블 컬럼 추가 : 대량의 이력 테이블을 조회할때 속도 저하를 대비, 조회 기준이 되는 컬럼을 미리 추가
      • e.g. 최신 데이터 여부
  3. 관계 반정규화 - 중복관계추가
    • 업무 프로세스상 JOIN이 많이 필요한 경우 중복관계를 추가하는게 성능 측면에서 유리한 경우
    • 데이터 무결성을 깨뜨릴 위험없이 데이터 처리 성능을 향상시킬수 있음

3. 트랜잭션 Transaction

  • 데이터를 조작하기 위한 하나의 논리적인 작업 단위
  • 하나의 연속적인 업무 단위
  • 트랜잭션에 의한 관계 -> 필수적인 관계 형태를 가짐
    • 하나의 트랜잭션에는 여러 SELECT, INSERT, DELETE, UPDATE가 포함될수 있음
    • e.g. 1) 온라인에서 퀴즈의 정답을 맞히면 쿠폰을 즉시 발행해주는 이벤트 - 쿠폰은 선착순 100명에게만 지급
      • 트랜잭션
        • 이벤트 응모 이력을 저장한다
        • 쿠폰을 발행한다
    • e.g. 2) A가 B에게 100만원을 계좌이체
      • 1) A 잔액이 100만원 이상인지 확인
      • 2) 이상이면, A 잔액을 -100 UPDATE
      • 3) B 잔액에 +100 UPDATE
        • 2,3번이 동시에 수행되어야함(모두 성공/모두 취소) -> 트랜잭션

4. NULL

  • 값이 없음 = 존재하지않음 = 아직 정해지지 않은 값
  • COL = NULL : False(무조건)
    • NULL은 =으로 확인X
    • IS NULL / IS NOT NULL로 확인

특징

  • NULL이 있는 경우
    • 가로연산 : NULL
      • NULL을 치환후 계산
      • SELECT ENAME, SAL, COMM, SAL + NVL(COMM, 0) FROM EMP;
    • 세로연산 : 다른 인스턴스의 데이터와 연산할때 NULL값 제외
      • 집계함수에서 해당
      • e.g. SUM() : 컬럼값이 NULL인 Row 제외하고 합계 계산
  • 정렬이 되는 컬럼에서 NULL은 최댓값(Oracle/ SQL Server: 최솟값) : 오름차순일 경우 맨 마지막에 위치