Database/기타

RDBMS의 한계와 NoSQL을 사용하는 이유 (2) RDBMS의 한계, 트랜잭션

TheWing 2021. 11. 27. 18:35

DB RDBMS의 한계와 NoSQL을 사용하는 이유 (2)  RDBMS의 한계,  트랜잭션

RDBMS(Relational DataBase Management System, 관계형 데이터베이스)

  • 관계형 데이터 모델은 데이터 간의 상관 관계에서 개체간의 관계를 2차원의 테이블 형태로 표현

목표

  • RDBMS의 가장 큰 목표는 데이터 무결성을 높이는 것이다.

무결성의 종류

  1. 엔터티 무결성(Entity Integrity) = 개체 무결성
    • 모든 인스턴스는 고유한 값(=같은 값 존재 X)이거나, 널(Null) 값을 가지면 안 됨
  2. 참조 무결성(Referential Integrity)
    • 참조되는 엔터티의 주 식별자 값과 일치(=참조하는 기본키 값 중에 하나와 일치)하거나, 널(Null) 값이어야 함. 참조 무결성은 FK(Foreign Key) 제약에 의해 지켜짐.
  3. 도메인 무결성(Domain Integrity)
    • 속성 값과 관련된 제약.
    • 같은 속성에 사용되느니 값들은 같은 성격의 값.
    • 기본 값이나 널 여부, 체크 조건 등으로 지켜질 수 있음.

종류

  • MySQL, MariaDB, Oracle, PostgreSQL

장점

  • 명확하게 정의된 스키마, 데이터 무결성 보장
  • 관계는 각 데이터를 중복없이 한번만 저장
  • 데이터의 일관성을 보증할 수 있다.
  • 복잡한 형태의 쿼리도 가능하다(Join 등)

단점

  • 스키마에 준수하지 않는 레코드는 추가할 수 없다. 컬럼을 자유롭게 추가하려면 테이블을 변경시키거나 새로운 테이블을 만들어야한다
  • 관계를 맺고 있기 때문에, JOIN문이 많은 매우 복잡한 쿼리가 만들어 질 수 있다
  • 수평적 확장이 어렵고, 대체로 수직적 확장만 가능하다.(즉 처리의 한계를 직면하게됨)
  • 대량의 데이터를 입력할 경우나 조회할 경우 성능이 저하 될 수 있고 Sharding과 Replication을 구축하는 비용이 많이 든다

트랜잭션

  • 여러 과정을 하나의 행위로 묶을 때 사용된다
  • 여러 단계를 수행했을때, 하나라도 실패하면 모두 취소되어야 한다. 이렇게 함으로써 데이터의 무결성을 보장한다. 모두 반영하거나 반영하지 않음.

트랜잭션 사용 이유

  • 트랜잭션은 DB 서버에 여러 개의 클라이언트가 동시에 액세스 하거나 응용 프로그램이 갱신을 처리하는 과정에서 중단될 수 있는 경우 데이터 부정합을 방지하고자 할 때 사용한다.
  • 부정합이 발생하지 않으려면 프로세스를 병렬로 처리하지 않도록 하여 한 번에 하나의 프로세스만 처리하도록 하면 되는데, 이는 효율이 너무 떨어지게된다.
  • 즉, 병렬로 처리할 수 밖에 없는 현실적인 상황으로 인해 부정합을 방지하고자 트랜잭션을 사용한다.
  • 트랜잭션에서 중요한 것은 스케줄 관리이다
  • 스케줄을 잘못 짜게 되면 데드락에 빠지게 된다

트랜잭션의 특성

ACID : 데이터베이스 트랜잭션이 안전하게 수행된다는 것을 보장하는 성질을 가리키는 약어

원자성(Atomicity)

  • 모든 작업이 반영되거나 모두 롤백되는 특성

일관성(Consistency)

  • 트랜잭션이 성공적으로 완료되면 일관적인 DB상태를 유지한다

ex) 금액의 데이터 타입이 정수형(IntegerE)인데, 갑자기 문자열(string)이 되지 않는 것을 말한다

  • 즉, 송금 전후 모두 금액의 데이터 타입은 정수형이여야 한다는 것이다

격리성(Isolation)

  • 트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것

영구성(Durability)

  • 한 번 저장된 트랜잭션을 영구히 보존된다

트랜잭션 격리 수준

READ UNCOMMITTED : 다른 트랜잭션에서 커밋되지 않은 내용을 참조할 수 있다. Dirty READ 발생

READ COMMITTED : 다른 트랜잭션에서 커밋된 내용만 참조할 수 있다. NON-REPETABLE READ 발생

 

NON-REPETABLE READ

  • 하나의 트랜잭션 내에서 똑같은 SELECT를 수행했을 때 항상 같은 결과를 반환해야한다는 REPEATABLE READ 정합성에 어긋난다. (입출금 처리 시 치명적)
  • EX)
  • B 트랜잭션에서 1번 유저의 나이를 조회 = 27살
  • A 트랜잭션에서 1번 유저의 나이를 27살 → 28살로 바꾸고 COMMIT
  • B 트랜잭션에서 1번 유저의 나이를 다시 조회 28살로 조회

REPETABLE READ: 트랜잭션에 진입하기 이전 커밋된 내용만 참조할 수 있다. UPDATE 부정합, Phantom READ 발생

 

UPDATE 부정합

  • START TRANSACTION; -- transaction id : 1
    SELECT * FROM Member WHERE name='thewing';
    
        START TRANSACTION; -- transaction id : 2
        SELECT * FROM Member WHERE name = 'thewing';
        UPDATE Member SET name = 'thewing2' WHERE name = 'thewing';
        COMMIT;
    
    UPDATE Member SET name = 'thewing3' WHERE name = 'thewing'; -- 0 row(s) affected
    COMMIT;​
  • 트랜잭션 1에서 thewing 조회
  • 트랜잭션 2에서 thewing 조회 후 thewing2로 변경 후 커밋 name = thewing 는 UNDO 영역에 남겨놔야 한다
  • 트랜잭션 1이 바라보고 있는 것은 name = thewing 의 경우는 UNDO 영역의 데이터이고 UNDO 영역에 있는 데이터에 대해서는 쓰기 잠금을 걸 수 없다.
  • 결론적으로 thewing의 데이터는 존재하지 않으므로 변경이 일어나지 않는다.

Phantom READ

  • 한 트랜잭션 내에서 같은 쿼리를 두 번 실행하는데 첫 번째 쿼리에서 없던 유령(Phantom) 레코드가 두 번째 쿼리에서 나타나는 현상

SERIALIZABLE : 트랜잭션에 진입하면 락을 걸어 다른 트랜잭션이 접근하지 못하게 한다. (성능 최저)

적합 업무

  • 데이터 무결성 및 일관성이 중요한 트랜잭션 업무
  • 온라인에서 다양한 집계 및 통계를 분석하는 업무
  • 복잡한 계산 및 실시간 데이터 정합성이 필요한 업무

어떤 상황에 사용하는지?

  • 대부분의 경우에 관계형 데이터베이스를 사용하는 것이 안정
  • 관계를 맺고 있는 데이터가 자주 변경되는 애플리케이션일 경우
  • 변경될 여지가 없고 명확한 스키마가 사용자와 데이터에게 중요한 경우

RDBMS의 한계

채팅 데이터(Message)를 RDBMS(PSQL)에 넣게 된다면? (개인적인 견해)

  • 짧은 시간에 많은 데이터 입력이 처리가 된다.
  • 한정된 규모의 복잡성이 높은 데이터에서 단순한 대량의 데이터가 쌓이며 조회, 삽입이 빈번하게 일어난다.
  • Lock이 자주 발생
  • 데이터가 쌓이게 되면 데이터베이스를 분산 시켜야한다.
    • RDBMS는 분산을 하기 쉽지 않다.

참고