😗
SQL Guide
  • 😀SQL 전문가 가이드의 가이드
  • 😦과목1 데이터모델의 이해
    • ⭐제1장 데이터 모델링의 이해
      • 🌠1-1-1. 데이터 모델의 이해
      • 🌠1-1-2. 엔터티(Entity)
      • 🌠1-1-3. 속성(Attribute)
      • 🌠1-1-4. 관계(Relationship)
      • 🌠1-1-5. 식별자
    • ⭐제2장 데이터 모델과 SQL
      • 🌠1-2-1. 정규화
      • 🌠1-2-2. 관계와 조인의 이해
      • 🌠1-2-3. 모델이 표현하는 트랜잭션의 이해
      • 🌠1-2-4. Null 속성의 이해
      • 🌠1-2-5. 본질식별자 vs. 인조식별자
  • 😧과목2. SQL 기본과 활용
    • ⭐제1장 SQL 기본
      • 🌠2-1-1. 관계형 데이터베이스 개요
      • 🌠2-1-2. SELECT문
      • 🌠2-1-3. 함수(FUNCTION)
      • 🌠2-1-4. WHERE 절
      • 🌠2-1-5. GROUP BY, HAVING 절
      • 🌠2-1-6. ORDER BY 절
      • 🌠2-1-7. 조인
      • 🌠2-1-8. 표준 조인
    • ⭐제2장 SQL 활용
      • 🌠2-2-1. 서브 쿼리
      • 🌠2-2-2. 집합 연산자
      • 🌠2-2-3. 그룹 함수
      • 🌠2-2-4. 윈도우 함수
      • 🌠2-2-5. Top N 쿼리
      • 🌠2-2-6. 계층형 질의와 셀프 조인
      • 🌠2-2-7. PIVOT 절과 UNPIVOT 절
      • 🌠2-2-8. 정규 표현식
    • ⭐제3장 관리 구문
      • 🌠2-3-1. DML
      • 🌠2-3-2. TCL
      • 🌠2-3-3. DDL
      • 🌠2-3-4. DCL
  • 😨과목3. SQL 고급 활용 및 튜닝
    • ⭐제1장 SQL 수행 구조
      • 🌠3-1-1. 데이터베이스 아키텍처
      • 🌠3-1-2. SQL 처리 과정
      • 🌠3-1-3. 데이터베이스 I/O 메커니즘
    • ⭐제2장 SQL 분석 도구
      • 🌠3-2-1. 예상 실행계획
      • 🌠3-2-2. SQL 트레이스
      • 🌠3-2-3. 응답 시간 분석
    • ⭐제3장 인덱스 튜닝
      • 🌠3-3-1. 인덱스 기본 원리
      • 🌠3-3-2. 테이블 액세스 최소화
      • 🌠3-3-3. 인덱스 스캔 효율화
      • 🌠3-3-4. 인덱스 설계
    • ⭐제4장 조인 튜닝
      • 🌠3-4-1. NL 조인
      • 🌠3-4-2. 소트 머지 조인
      • 🌠3-4-3. 해시 조인
      • 🌠3-4-4. 스칼라 서브쿼리
      • 🌠3-4-5. 고급 조인 기법
    • ⭐제5장 SQL 옵티마이저
      • 🌠3-5-1. SQL 옵티마이징 원리
      • 🌠3-5-2. SQL 공유 및 재사용
      • 🌠3-5-3. 쿼리 변환
    • ⭐제6장 고급 SQL 튜닝
      • 🌠3-6-1. 소트 튜닝
      • 🌠3-6-2. DML 튜닝
      • 🌠3-6-3. 데이터베이스 Call 최소화
      • 🌠3-6-4. 파티셔닝
      • 🌠3-6-5. 대용량 배치 프로그램 튜닝
      • 🌠3-6-6. 고급 SQL 활용
    • ⭐제7장 Lock과 트랜잭션 동시성 제어
      • 🌠3-7-1. Lock
      • 🌠3-7-2. 트랜잭션
      • 🌠3-7-3. 동시성 제어
Powered by GitBook
On this page
  • 과목1. 데이터 모델링의 이해
  • 제2장 데이터 모델과 SQL
  • 제3절 모델이 표현하는 트랜잭션의 이해

Was this helpful?

  1. 과목1 데이터모델의 이해
  2. 제2장 데이터 모델과 SQL

1-2-3. 모델이 표현하는 트랜잭션의 이해

과목1. 데이터 모델링의 이해

제2장 데이터 모델과 SQL

제3절 모델이 표현하는 트랜잭션의 이해

트랜잭션은 데이터베이스의 논리적 연산단위다. 흔히 계좌이체를 많이 설명하는데, 이보다 더 적합한 사례는찾아보기가 힘들다. 돈을 보내는 사람의 계좌에서 이체금액을 차감하고, 돈을 받는 사람의 계좌에 이체금액을 가산한다.즉 계좌이체라는 업무는 이러한 2가지 단계로 진행되며, 데이터 정합성을 위해 위 작업은 전부 실행되든지 아니면전부 취소되든지 해야 한다. 즉 하나의 업무 단위로 묶여서 처리돼야 한다는 것이고 이러한 업무 단위를 트랜잭션이라고한다. 여기까지는 익히 알고 있는 내용이다. 그렇다면 업무적으로 발생되는 트랜잭션 말고 모델에도 트랜잭션이발생할 수 있다는 것을 알고 있는가? 데이터 모델링 진행 시에도 트랜잭션을 표현할 수 있다.

[그림 I-2-18] 주문과 주문상세 모델 필수 관계

고객이 상품을 구매하면서 발생하는 것이 주문이다. 또한 하나의 주문은 여러 개의 상품을 구매할 수 있다. 이에대한 모델이 [그림 I-2-18]이다. 그렇다면 주문과 주문상세의 데이터는 함께 발생되는지, 아니면 독립적으로 발생되는지를 생각해보아야 한다. IE 표기법에서는 필수적인(Mandatory) 관계일 경우 관계선 끝에 원을 붙이지 않는다.바커 표기법은 필수일 경우 관계선을 실선으로 표기한다. 즉 본 모델은 주문이 발생하면 주문상세 데이터도 함께발생된다는 의미다.

[그림 I-2-19] 주문과 주문상세 모델 선택 관계

[그림 I-2-1위 모델은 주문과 주문상세 모델의 관계가 선택적임을 표현하고 있다. 이는 주문에 대해 주문상세 데이터가 없을 수도 있다는 것이다. 주문만하고 상품을 구매하지 않을 수 있을까? 일반적인 쇼핑몰 업무라면 그럴수는 없을 것이다. 애초에 주문은 고객이 상품을 구매함으로써 발생되기 때문이다. 이처럼 관계선택사양은 매우 중요한 정보를 보여주고 있지만, 실제로 주문 모델을 보면 위와 같이 주문과 주문상세를 선택적 관계로 표현하는 모델을 자주 볼 수 있다. 왜 이런 일이 발생하는지 추측해보면 대부분의 관계는 선택적인 경우가 더 많을 것이다. 이에 따라 대부분의 모델링 툴에서는 선택적 관계 표현이 기본 설정이다. 모델 작성자는 이를 꼭 인지하고, 습관적으로 관계의 선택사양을 간과하고 있는지 고려해봐야 한다.

일반적인 쇼핑몰 모델에서 주문과 주문상세는 [그림 I-2-18]이 올바른 모델이라고 할 수 있다. 그렇다면 본 모델은 어떻게 개발해야 할까? 주문과 주문상세의 데이터가 태생적으로 동시에 발생된다면, 당연히 계좌이체의 경우처럼 하나의 트랜잭션으로 묶어서 처리해야 한다.

여기서 트랜잭션을 하나로 묶는다는 것은 어떻게 처리해야 한다는 것일까? All or Nothing인 원자성이 보장되도록 개발을 해야 한다는 것이다. 즉 커밋(Commit)의 단위를 하나로 묶어야 함을 의미한다. 그래야만 트랜잭션은 전체가 실행되거나 혹은 전체가 취소될 수 있다.

// A → B 계좌이체
Step1. 계좌이체API{잔고수정(고객번호=>A, 수정값> 현재잔고-이체금액);
                  잔고수정(고객번호=>B, 수정값>현재잔고+이체금액);
				  commit();}

위 의사코드(Pseudo Code)는 A 고객이 B 고객에게 계좌이체하는 것을 표현한 것이다. 계좌이체를 하기 위해서는 먼저 A 고객의 잔고에서 이체금액을 차감하고, B 고객의 잔고에 이체금액을 가산해야 한다. 중요한 것은 잔고를 차감하고 가산하는 단계가 모두 완료된 후에 커밋을 수행하는 것이다. 잔고 차감/가산 단계가 모두 성공해야지만 커밋이 수행되어 정상적인 데이터를 반영할 수 있다.

그렇다면 과연 현장에서는 이렇게 개발하고 있을까? 재사용성이라는 이유로 또는 API 개발 패턴으로 인해 모든 트랜잭션의 SQL을 낱개로 뜯어내고 있지 않은지 생각해보아야 한다. 주문과 주문상세 모델은 애초 서로 독립적으로 데이터가 발생될 수 없다. 그렇기에 데이터 발생 시 주문의 INSERT문과 주문상세의 INSERT문이 따로 개발되어서는 안 된다.

만일 이를 따로 개발한다면 어떤 문제가 발생될 수 있을까?

// 고객의 주문 발생
Step1. 주문API {주문입력(주문번호=110001, 고객명=>A, ...);
               commit();}
Step2. 주문상세API{ 주문상세입력(주문번호=110001, 상품번호=1234, ...);
               commit();}

어차피 함께 수행되어야 하는 주문의 INSERT API와 주문상세의 INSERT API를 각각 호출해야 한다. 문제는 주문하는 도중에 핸드폰 배터리가 다 되었을 수도 있고, 앱을 실수로 꺼버렸을 수도 있으며, 장애가 발생되어 연결이 끊어질 수도 있다. 이렇게 다양한 요인들로 인해 주문과 주문상세 API가 함께 수행되지 못하고 하나만 수행된다면, 이는 주문과 주문상세에 잘못된 데이터가 발생할 수 있음을 의미한다. 모델에서 표현하는 트랜잭션은 어차피 따로 수행될 일 자체가 없으므로 재사용성의 이점도 얻을 수 없다고 봐야 한다. 다음과 같이 반드시 하나의 트랜잭션으로 처리되어야 할 것이다.

// 고객의 주문 발생
Step1. 주문API{주문입력(주문번호=>110001, 고객명=>A, ...);
              주문상세입력(주문번호=110001, 상품번호=>1234, ...);
			  commit();}

여기서 중요한 것은 업무적 트랜잭션보다 모델이 표현하는 트랜잭션은 태생 자체가 함께 발생하는 데이터이기에 재사용성의 이점도 없으므로 반드시 하나의 트랜잭션으로 처리해야 한다는 점이다. 프레임워크에서 autocommit 기능 지원으로 대부분 커밋에 대한 부분을 간과하지만, 잘못된 트랜잭션 처리는 데이터 정합성의 문제를 야기하고 데이터 품질에도 큰 영향을 미칠 수 있음을 염두에 둬야 한다.

Previous1-2-2. 관계와 조인의 이해Next1-2-4. Null 속성의 이해

Last updated 3 years ago

Was this helpful?

출처 : 데이터온에어 – 한국데이터산업진흥원()

😦
⭐
🌠
https://dataonair.or.kr