2. 데이터 모델과 SQL

참고 도서: 2022 유선배 SQL개발자 과외노트
참고 자료: Wikipedia, oracle.com, oracletutorial.com
** SQLD 자격 시험을 준비하는 분들께 도움이 되고자 정리한 내용을 올리고 있습니다.
** 암기가 필요한 부분은 계속 보면서 외워주세요.
** 실습 환경 구성이 어려운 분들은 아래 링크를 이용하세요.
Oracle Live SQL 👈 클릭
** 오류가 있다면 댓글 주세요!

2.1 정규화(Nomalization)

2.1.1 제1정규형

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

  1. 🤹‍♀️다중값

    정규화

  2. 👬유사 속성

    정규화

2.1.2 제2정규형

엔터티의 모든 일반 속성은 반드시 모든 주식별자에 종속되어야 한다. 주식별자가 복합식별자인 경우 일반속성이 주식별자의 일부에만 종속될 수 있는데 이는 제2정규형 대상이다.

정규화

2.1.3 제3정규형

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

정규화

2.1.4 정규화 주의사항

지나친 정규화는 성능 저하를 일으킬 수 있다. 성능 저하 이슈가 발생하면 반정규화를 통해서 성능을 개선해야 한다.

2.2 반정규화

2.2.1 반정규화란?

데이터의 조회 성능을 향상시키기 위해 데이터의 중복을 허용하거나 그룹핑하는 활동이다.

조회 성능은 향상될 수 있지만 입력, 수정, 삭제 성능은 저하될 수 있다.

또한 데이터 정합성 이슈 발생에 주의해야 한다.

반정규화 역시 일정한 룰이 존재하므로 룰에 따라서 진행한다.

2.2.2 테이블 반정규화

1. 테이블 병합 1:1 관계 테이블 병합
  1:M 관계 테이블 병합
2. 테이블 분할 테이블 수직 분할(속성 분할)
  태이블 수평 분할(인스턴스 분할, 파티셔닝)
3. 테이블 추가 중복 테이블 추가👯‍♀️
  통계 테이블 추가📊
  이력 테이블 추가
  부분 테이블 추가
  1. 테이블 병합: 업무 프로세스상 JOIN이 필요한 경우 고려할 수 있다. 1:M 관계 테이블 병합일 경우 1쪽에 해당하는 테이블의 속성이 많은 경우 중복 데이터가 많이 발생하므로 주의해야 한다.

  2. 테이블 분할

    1. 테이블 수직 분할: 엔터티의 일부 속성을 별도의 엔터티로 분할한다. 속성의 사용 빈도가 낮거나 대부분의 값이 NULL일 경우 고려한다.(1:1 관계 성립)

    2. 테이블 수평 분할: 엔터티의 특정 인스턴스를 별도의 엔터티로 분할한다.(파티셔닝)

  3. 테이블 추가

    1. 중복 테이블 추가: 데이터의 중복을 감안하더라도 성능상 반드시 필요하다고 판단되는 경우 별도의 엔터티를 추가한다. 다른 업무이거나 서버가 다른 경우 동일한 테이블 구조를 중복 허용하여 원격 JOIN(DBLink)을 제거할 수 있다.

    2. 통계 테이블 추가: 통계 정보를 위해 기존 엔터티의 데이터를 미리 계산하여 별도의 엔터티에 저장한다. e.g. 주문 데이터를 이용하여 월매출 테이블(통계 테이블)에 통계치를 저장.

    3. 이력 테이블 추가: 이력성 정보를 조회하기 위한 별도의 엔터티를 생성한다.

    4. 부분 테이블 추가: 자주 이용하는 컬럼들을 별도의 테이블로 생성

2.2.3 컬럼 반정규화

  1. 중복 컬럼 추가: 업무 프로세스상 JOIN이 필요한 경우가 많아 컬럼을 추가하는 것이 성능 측면에서 유리할 경우 고려한다. JOIN 비용은 감소하나 갱신 비용이 증가한다.

  2. 파생 컬럼 추가: 프로세스 수행 시 부하가 예상될 때 계산값을 미리 컬럼으로 추가하여 보관하는 방식이다. JOIN 비용은 감소하나 갱신 💷비용이 증가한다. e.g. 상품재고, 할인

  3. 이력 컬럼 추가: 대량의 이력 테이블을 조회할 때 속도 저하가 발생할 것을 방지하고자 조회 기준이 될 것으로 판단되는 컬럼을 미리 추가한다. e.g. 최신 데이터 여부

2.2.4 관계 반정규화

중복 관계 추가: 관계가 먼 데이터 간에 빈번한 JOIN 발생 시 고려할 수 있다. 무결성 훼손 없이 반정규화를 통한 성능 개선 가능성이 생긴다.

2.3 트랜잭션

2.3.1 트랜잭션이란?

데이터를 조작하기 위한 하나의 논리적 작업 단위이다. e.g. 🎪이벤트 참여 트랜잭션(이벤트 응모 이력을 저장한다 → 쿠폰을 발행한다)

2.4 NULL

2.4.1 NULL이란?

존재하지 않는 값, 즉 🙅‍♂️‘값이 없음’을 뜻한다. (NULL ≠ 0)

2.4.2 NULL의 처리

  • user Entity

    user_no user_nm user_income user_expenditure
    user0000001 Theodore 0 2500
    user0000002 Samantha NULL 3000
    user0000003 Amy 5000 1000
  1. SELECT user_income - user_expenditure AS ret FROM user WHERE user_no = ‘user0000002’;
    ret = NULL (가로 연산 시 NULL이 포함되어 있으면 결과값은 NULL이다.)

  2. SELECT SUM(user_income) AS ret FROM user;
    ret = 5000 (세로 연산, 다른 인스턴스의 데이터와 연산할 때 NULL이 포함되어 있으면 제외한다.)
    ⁉️ NULL ≠ ‘NULL’