Home DDIA - 저장소와 검색
Post
Cancel

DDIA - 저장소와 검색

Table of Contents

  1. 들어가기
  2. 데이터베이스를 강력하게 만드는 데이터 구조
    1. 해시 색인
    2. SS테이블과 LSM 트리
      1. SS테이블 생성과 유지
      2. 성능 최적화
      3. 모아보기
    3. B 트리
      1. 최적화
    4. B 트리와 LSM 트리 비교
      1. LSM 트리의 장점
    5. 기타 색인 구조
      1. 색인에 값 저장하기
      2. 다중 컬럼 색인
      3. 전문 검색과 퍼지 색인
      4. 모든 것을 메모리에 보관
  3. 트랜잭션 처리나 분석?
    1. 데이터 웨어하우징
    2. 분석용 스키마: 별 모양 스키마와 눈꽃송이 모양 스키마
  4. 칼럼 지향 저장소
    1. 칼럼 압축
      1. 메모리 대역폭과 벡터화 처리
    2. 칼럼 저장소의 순서 정렬
      1. 다양한 순서 정렬
    3. 칼럼 지향 저장소에 쓰기
    4. 집계: 데이터 큐브와 구체화 뷰

들어가기

해당 챕터에서는 데이터베이스가 데이터를 저장하는 방법, 데이터를 다시 찾는 방법 에 대해서 설명한다.

애플리케이션 개발자가 해당 내용을 알아야 하는 이유

  • 애플리케이션에 적합한 엔진을 선택하는 작업이 필요
  • 특정 작업부하 유형에서 저장소 엔진의 성능을 조정
    저장소 엔진이 내부에서 수행되는 작업에 대한 대략적인 개념을 이해할 필요

데이터베이스를 강력하게 만드는 데이터 구조

많은 데이터베이스는 내부적으로 추가 전용(append-only) 데이터 파일인 로그를 사용

  • 일반적으로 파일 추가 작업은 매우 효율적

반면 로그(append-only)에 많은 레코드가 있고, 로그에서 단순한 조회 처리는 성능이 매우 좋지 않다.(검색 비용 O(n))
이렇듯 특정 키의 값을 효율적으로 찾기 위해서는 다른 데이터 구조가 필요한데, 이것이 바로 색인 이다.

색인

  • 일반적인 개념은 어떤 부가적인 메타데이터를 유지하는 것
    이 메타데이터는 이정표 역할을 해서 원하는 데이터의 위치를 찾는 데 도움을 준다.
  • 기본 데이터에서 파생된 추가적인 구조
    추가적인 구조의 유지보수는 특히 쓰기 과정에서 오버헤드가 발생 -> 쓰기 속도를 느리게 만듬

해시 색인

매우 일반적이고 더욱 복잡한 색인을 위한 구성 요소로 유용하다.

단순히 파일에 추가하는 방식으로 데이터 저장소를 구성한다고 가정해보자.
그러면 가장 간단한 색인 전략은 키를 데이터 파일의 바이트 오프셋에 매핑해 인메모리 해시 맵을 유지하는 전략이다.

img
키-값 쌍의 로그, 인메모리 해시 맵으로 색인

파일에 항상 추가만 한다면 결국 디스크 공간이 부족해진다. 이 상황은 어떻게 피할 수 있을까?
좋은 해결책으로 특정 크기의 세그먼트(segment) 로 로그를 나누는 방식이 있다.

  • 특정 크기에 도달하면 세그먼트 파일을 닫고 새로운 세그먼트 파일에 이후 쓰기를 수행
  • 세그먼트 파일들에 대해 컴팩션을 수행
    컴팩션은 각 키의 최신 갱신 값만 유지하는 것을 의미
  • 고정된 세그먼트의 병합과 컴팩션은 백그라운드 스레드에서 수행할 수 있다.
  • 컴팩션 동안 이전 세그먼트 파일을 사용해 읽기와 쓰기 요청을 처리
  • 병합 이후, 새로 병합한 세그먼트로 전환(이전 세그먼트 파일은 삭제)

    img

컴팩션과 병합을 동시에 수행

조회 처리 과정

  1. 최신 세그먼트 해시 맵을 확인
  2. 1에서 키가 없다면 두 번째 최신 세그먼트 등을 확인

추가 전용 설계의 장점

  • 추가와 세그먼트 병합은 순차 쓰기 작업이므로 보통 무작위 쓰기보다 훨씬 빠르다.
  • 세그먼트 파일이 추가 전용 또는 불변이면 동시성과 고장 복구 측면에서 훨씬 간단하다.
  • 오래된 세그먼트 병합은 조각화되는 데이터 파일 문제를 피할 수 있다.

해시 테이블 색인의 제한 사항

  • 메모리에 저장해야 하므로 키가 너무 많으면 문제
  • 비효율적인 범위 질의

SS테이블과 LSM 트리

지금까지 이야기한 세그먼트 파일의 형식에서 간단한 변경 사항 한 가지를 적용해보자.
키-값 쌍을 키로 정렬하는 것 이다.

이것을 정렬된 문자열 테이블(Sorted String Table) 또는 짧게 SS테이블이라 부른다.
또한 각 키는 각 병합된 세그먼트 파일 내에 한 번만 있어야 한다.

SS테이블은 해시 색인을 가진 로그 세그먼트와 비교해 몇 가지 장점 가진다.

  1. 세그먼트 병합은 파일이 사용 가능한 메모리보다 크더라도 간단하고 효율적
    • 각 파일의 첫 번째 키를 확인, 가장 낮은 키를 새 병합 세그먼트 파일로 복사를 반복
    • 여러 세그먼트가 동일한 키를 포함한 경우, 가장 최근 세그먼트의 값을 유지하고 오래된 세그먼트의 값은 버린다.

      img
      SS테이블 세그먼트 병합, 각 키의 최신 값만 유지

  2. 특정 키를 찾기 위해 메모리에 모든 키의 색인을 유지할 필요가 없다.

    img
    일부 키에 대한 오프셋만 유지한 인메모리 색인(희소 색인)을 가진 SS테이블

  3. 레코드들을 블록으로 그룹화하고 디스크에 쓰기 전에 압축
    • 읽기 요청은 요청 범위 내에서 여러 키-값 쌍을 스캔해야 하기 때문
    • 디스크 공간 절약
    • I/O 대역폭 사용 절약

SS테이블 생성과 유지

  • 쓰기 요청은 인메모리 균형 트리 데이터 구조(red-black tree, AVL tree 등)에 추가
    memtable이라고도 함
  • 멤테이블이 임계값보다 커지면 SS테이블 파일로 디스크에 기록
    해당 SS 테이블은 가장 최신 세그먼트
    디스크에 기록하는 동안 쓰기는 신규 멤테이블에 기록
  • 읽기 요청은 멤테이블, 최신 세그먼트, 다음 세그먼트 … 순으로 진행
  • 가끔 세그먼트들을 병합, 컴팩션 과정을 수행
    백그라운드에서 수행

장애를 대비하기 위해 별도의 로그를 디스크에 작성한다.
이 로그는 장애 후, 멤테이블을 복원하기 위해서만 사용하기에 정렬되지 않아도 된다.
멤테이블이 SS테이블로 기록되면 해당 로그는 지우고 새로 작성할 수 있다.

성능 최적화

LSM 트리 알고리즘은 데이터베이스에 존재하지 않는 키를 찾는 경우 느릴 수 있다.
해당 경우를 최적화하기 위해 저장소 엔진은 보통 블룸 필터(Bloom filter)를 추가적으로 사용한다.

SS테이블을 압축하고 병합하는 순서와 시기를 결정하는 전략은 다양하다.
일반적으로 2가지가 존재한다.

  • 크기 계층(size-tiered)
    상대적으로 최신의 작은 SS테이블을 상대적으로 오래된 큰 SS테이블에 연이어 병합
  • 레벨 컴팩션(leveled compaction)
    키 범위를 더 작은 SS테이블로 나누고 오래된 데이터는 개별 레벨로 이동
    그래서 컴팩션을 점직적으로 진행해 디스크 공간을 덜 사용

모아보기

지금까지 이야기 한 내용의 색인 구조는 로그 구조화 병합 트리(Log-Structured Merge-Tree)라고 불린다.
그리고 LSM 트리의 구조를 보면 아래와 같다.
SS테이블은 LSM 저장소 엔진의 한 구성 요소이다.

이 개념은 데이터셋이 가능한 메모리보다 훨씬 더 크더라도 효과적이다.
데이터가 정렬된 순서로 저장돼 범위 질의를 효율적으로 수행할 수 있다.
디스크 쓰기는 순차적이기에 매우 높은 쓰기 처리량도 보장한다.

img
출처 : http://kflu.github.io/2018/02/09/2018-02-09-lsm-tree

B 트리

특징

  • 가장 널리 사용되는 색인 구조이다.
  • 정렬된 키-값 쌍을 유지
    키-값 검색과 범위 질의에 효율적이다.
  • 고정 크기 블록 혹은 페이지 단위로 읽기 또는 쓰기
  • 리프 페이지는 각 키의 값 혹은 실제 값을 포함한 페이지의 참조를 포함
  • 동시성 제어는 보통 래치(latch)로 트리의 데이터 구조를 보호
  • WAL 또는 Redo log 데이터 구조 관리

데이터 베이스 크래시 상황을 대비해 디스크 상에 쓰기 전 로그(write-ahead log, WAL) 또는 재실행 로그(redo log) 데이터 구조를 관리
쓰기 전 로그는 트리 페이지에 변경된 내용을 적용하기 전 모든 B 트리의 변경 사항을 기록하는 추가 전용 파일이다.
이 로그는 복구 시에 일관성 있는 상태로 B 트리를 다시 복원하는 데 사용한다.

최적화

  • WAL 대신 일부 데이터베이스는 쓰기 시 복사 방지(copy-on-write scheme)를 사용
  • 키를 축약해 공간을 절약
    트리 내부 페이지에서 키가 범위 사이의 경계 역할을 할수 있을 정도
  • 리프 페이지를 디스크 상에 연속된 순서로 배치하려고 시도
    하지만 트리가 커지면 순서를 유지하기가 어려움
  • 트리에 포인터를 추가
    예를 들어 각 리프 페이지에 양쪽 형제 페이지에 대한 포인터
  • 트랙탈 트리

B 트리와 LSM 트리 비교

LSM 트리는 보통 쓰기가 빠르지만 B 트리는 보통 읽기가 빠르다.
LSM 트리가 보통 읽기가 느린 이유는 각 컴팩션 단계에 있는 여러 가지 데이터 구조와 SS 테이블을 확인해야 하기 때문이다.

LSM 트리의 장점

B 트리의 장점

  • 로그 구조화 저장소 엔진보다 예측이 쉬운 성능
  • 각 키가 색인의 한 곳에만 정확히 존재
  • 강력한 트랜잭션 시맨틱을 제공하는 데이터베이스에 매력적
  • 많은 작업 부하에 지속적으로 좋은 성능을 제공

B 트리 단점

  • B 트리 색인은 모든 데이터 조각을 최소 2번 기록
    쓰기 전 로그, 트리 페이지에 최소 1번 기록해야 하기 때문(쓰기 증폭)
  • 페이지 내 몇 바이트만 바뀌어도 전체 페이지를 기록해야 하는 오버헤드 발생
  • 파편화로 인해 사용하지 않는 디스크 공간 일부 낭비

LSM 트리의 장점

  • B 트리 대비 높은 쓰기 처리량
    상대적으로 낮은 쓰기 증폭
    컴팩션된 SS 테이블을 파일에 순차적 쓰기
  • B 트리 대비 높은 압축률
    컴팩션 및 머지 프로세스를 통해 주기적으로 파편화 제거

LSM 트리 단점

  • SS 테이블의 반복된 컴팩션과 병합으로 여러 번 데이터를 다시 기록(쓰기 증폭)
  • 컴팩션 과정이 때로는 진행 중인 읽기와 쓰기 성능에 영향
    디스크가 가진 자원의 한계로 인해 발생
    이로 인해서 상위 백분위 질의의 응답 시간이 때때로 꽤 길다.
  • 데이터베이스가 커질수록 컴팩션을 위해 더 많은 디스크 대역폭이 필요
  • 컴팩션이 유입 쓰기 속도를 못 따라갈 수 있다.
    디스크 상에 병합되지 않은 세그먼트 수가 디스크 공간이 부족할 때까지 증가할 수 있다.
    병합되지 않은 세그먼트 수가 늘어나 읽기 속도가 느려진다.
    컴팩션 설정에 주의가 필요
  • 여러 세그먼트에 같은 키의 다중 복사본이 존재할 수 있다.

기타 색인 구조

기본키(primary key) 색인

  • 키-값 색인의 대표적인 예
  • 대상 데이터(로우/문서/정점)를 키로 고유하게 식별 및 참조

보조 색인(secondary index)

  • 보통 조인을 효율적으로 수행하는 데 결정적인 역할
  • 키가 유일하지 않음

보조 색인에서 키가 고유하지 않은 문제를 해결하는 방안(B 트리 & 로그 구조화 색인 모두 사용 가능)

  • 색인의 각 값에 일치하는 로우 식별자 목록을 만드는 방법(전문 색인에서 포스팅 목록과 같음)
  • 로우 식별자를 추가해 각 키를 고유하게 만드는 방법

색인에 값 저장하기

색인에서 값

  • 실제 로우(문서, 정점)
  • 힙 파일을 가리키는 참조

힙 파일 : 로우가 실제로 저장된 파일, 특정 순서 없이 데이터를 저장
힙 파일 접근은 일반적인 방식, 여러 보조 색인이 존재할 때 데이터 중복을 피할 수 있기 때문이다.

힙 파일 접근 방식

  • 키를 변경하지 않고 값을 갱신할 때 꽤 효율적
  • 새로운 값이 이전 값 보다 많은 공간을 필요로 하지 않으면 레코드를 제자리에 덮어쓸 수 있다.
  • 새로운 값이 많은 공간을 필요로 한다면 새로운 곳으로 위치를 이동
    • 모든 색인이 레코드의 새로운 힙 위치로 갱신
    • 이전 힙 위치에 전방향 포인터 기록

클러스터드 색인(clustered index)

  • 색인 안에 색인된 로우를 저장
    색인에서 힙 파일로 다시 이동하는 일은 읽기 성능에 불이익이 많기 때문
  • MySQL의 InnoDB에서 테이블의 기본키가 언제나 클러스터드 색인
  • MySQL의 InnoDB에서 보조 색인은 기본키를 참조

커버링 색인(covering index)

  • 포괄열이 있는 색인(index with included column)으로도 불림
  • 클러스터드 색인과 비클러스터드 색인 사이의 절충안
  • 색인 안에 테이블의 컬럼 일부를 저장

모든 종류의 데이터 복제와 마찬가지로 클러스터드 색인과 커버링 색인은 읽기 성능을 높일 수 있다.

하지만 추가적인 저장소가 필요하고 쓰기 오버헤드가 발생한다.
애플리케이션 단에서 복제로 인한 불일치를 파악할 수 없기 때문에 데이터베이스는 트랜잭션 보장을 강화하기 위해 별도의 노력이 필요하다.

다중 컬럼 색인

지금까지 이야기한 색인은 하나의 키만 값에 대응한다.
그래서 다중 컬럼에 동시에 질의를 해야 한다면 충분하지 않다.

결합 색인(concatenated index)

  • 다중 컬럼 색인의 가장 일반적인 유형
  • 하나의 컬럼에 다른 컬럼을 추가하는 방식으로 하나의 키에 여러 필드를 단순히 결합

다차원 색인

  • 조금 더 일반적인 방법
  • 지리 공간 데이터에 중요하게 사용되지만 여기에 국한되지 않는다.
  • k-d 트리, 사분 트리, R 트리 등

B 트리와 LSM 트리 색인에서도 지리 공간을 처리하는 한 가지 방법으로 공간 채움 곡선(space-filling curve)을 이용해 단일 숫자로 변환한 다음 색인에 사용하는 것이 있다.

전문 검색과 퍼지 색인

지금까지 설명한 색인들은 키의 정확한 값이나 정렬된 키의 값의 범위를 질의할 수 있다고 가정한다.
그래서 유사한 키에 대해서 검색을 할 수 없다.
이처럼 애매모호한(fuzzy) 질의에는 다른 기술이 필요하다.

루씬은 용어 사전을 위해 SS 테이블 같은 구조를 사용한다.
인메모리 색인은 키를 찾는 데 필요한 정렬 파일의 오프셋을 질의에 알려주는 데 사용한다.
루씬의 인메모리 색인은 여러 키 내 문자에 대한 유한 상태 오토마톤(finite state automaton)으로 트라이(trie)와 유사하다.
이 오토마톤은 레벤슈타인 오토마톤(levenshtein automaton)으로 변환할 수 있다.
레벤슈타인 오토마톤은 특정 편집 거리 내에서 효율적인 단어 검색을 제공한다.

자세한 내용은 관련해서 찾아보자.

모든 것을 메모리에 보관

지금까지 설명한 데이터 구조는 모두 디스크 한계에 대한 해결책이다.
디스크는 메인 메모리와 비교해 다루기 어렵지만, 디스크는 지속성과 가격면에서 장점이 있다.

하지만 램이 점점 저렴해져서 기가바이트당 가격 논쟁도 약해지고 여러 장비 간 분산해서 보관할 수도 있다.
이런 이유로 인메모리 데이터베이스가 개발됐다.

멤캐시드 같은 일부 인메모리 키-값 저장소는 장비가 재시작되면 데이터 손실을 허용하는 캐시 용도로만 사용된다.
하지만 다른 인메모리 데이터베이스는 지속성을 목표로 한다.

지속성을 달성하는 방법

  • 특수 하드웨어 사용(배터리 전원 공급 RAM 등)
  • 디스크에 변경 사항 로그 기록
  • 디스크에 주기적 스냅샷
  • 다른 장비에 인메모리 상태를 복제

하지만 디스크 기반 저장소 엔진도 충분한 메모리를 가진 경우에 OS의 페이지 캐시, 버퍼 캐시를 통해서 디스크에서 읽을 필요가 없다.
오히려 인메모리 데이터 구조를 디스크에 저장하기 위한 형태로 부호화하는 오버헤드를 피할 수 있어 더 빠를 수도 있다.

디스크 기반 색인으로 구현하기 어려운 데이터 모델을 제공
메모리에 모든 데이터를 유지하기 때문에 레디스의 우선순위 큐와 셋 등과 같이 다양한 구조를 구현하기가 비교적 간단하다.

안티 캐싱(anti-caching) 접근 방식
LRU 알고리즘과 같이 가장 최근에 사용하지 않은 데이터를 메모리에서 디스크로 적제하는 방식도 있다.
하지만 여전히 전체 색인이 메모리에 있어야 한다.

트랜잭션 처리나 분석?

특성OLTPOLAP
주요 읽기 패턴적은 수의 레코드, 키 기준 조회레코드에 대한 집계
주요 쓰기 패턴임의 접근, 사용자 입력을 낮은 지연 시간으로 기록Bulk import(ETL) 또는 이벤트 스트림
주요 사용처애플리케이션을 통한 최종 사용자/소비자의사결정 지원을 위한 내부 분석가
데이터 표현데이터의 최신 상태시간이 지나며 일어난 이벤트 이력
데이터셋 크기GB - TBTB - PB

과거 OLTP 시스템을 분석 목적으로 사용하지 않고 분석을 수행하기 위한 개별 데이터베이스를 데이터 웨어하우스(data warehouse)라고 불렀다.

데이터 웨어하우징

OLTP 시스템은 대개 사업 운영에 대단히 중요하기 때문에 일반적으로 높은 가용성과 낮은 지연 시간의 트랜잭션 처리를 기대한다.
반대로 데이터 웨어하우스는 분석가들이 OLTP 작업에 영향을 주지 않고 마음껏 질의할 수 있는 개별 데이터베이스다.

데이터는 OLTP 데이터베이스에서 추출(extract)하고 분석 친화적인 스키마로 변환(transform)하고 깨끗하게 정리한 다음 데이터 웨어하우스에 적재(load)한다.
데이터웨어하우스로 데이터를 가져오는 이 과정을 ETL(Extract-Transform-Load)이라 한다.

이 형태의 장점은 분석 접근 패턴에 맞게 최적화할 수 있다는 것이다.

분석용 스키마: 별 모양 스키마와 눈꽃송이 모양 스키마

분석용 스키마 특징

  • 사용하는 데이터 모델의 종류가 많지 않음
  • 대부분 별 모양 스키마(star schema)로 알려진 정형화된 방식 사용
    또는 차원 모델링(dimentional modeling)이라고도 불림
  • 보통 테이블의 속성(컬럼)이 매우 많음

별 모양 스키마 특징

  • 스키마 중심에 사실 테이블(fact table)이 존재
    • 각 로우는 특정 시각에 발생한 이벤트
    • 보통 개별 이벤트를 저장
      분석의 유연성 극대화 목적
      이로 인해서 사실 테이블이 매우 커질 수 있음
    • 사실 테이블의 다른 컬럼은 차원 테이블(dimension table)인 다른 테이블을 가리키는 외래 키 참조
  • 차원은 이벤트 속성인 누가, 언제, 어디서, 무엇을, 어떻게, 왜를 나타냄
    • 차원은 차원 테이블의 로우
  • 눈꽃송이 모양 스키마 대비 작업이 쉬워서 보통 분석가들이 더 선호

img
별 모양 스키마 예제

눈꽃송이 모양 스키마 특징

  • 별 모양 스키마의 변경
  • 차원이 하위 차원으로 더 세분화
  • 별 모양 스키마 보다 더 정규화
  • 별 모양 스키마 대비 작업이 더 어려움

칼럼 지향 저장소

사실 테이블(fact table)은 컬럼이 보통 100개 이상이지만 질의는 한 번에 소수의 칼럼만 접근하며 다른 컬럼은 무시한다.

이때 100개의 칼럼 중 5개의 칼럼을 사용한 조건에 부합한 로우를 찾는다고 하자
로우 지향 방식의 경우, 조건을 처리하기 위해서 색인을 사용하겠지만 부분적으로 색인이 존재하지 않을 수 있다.
그러면 모든 로우를 메모리로 적재해 필요한 조건을 충족하지 않은 로우를 필터링해야 한다.
이 작업은 오랜 시간이 걸릴 수 있다.

위와 같은 경우 컬럼 지향 저장소의 필요성이 부각될 수 있다.

칼럼 지향 저장소 특징

  • 모든 값을 하나의 로우에 함께 저장하지 않는다. 대신 각 칼럼별로 모든 값을 함께 저장한다.
  • 각 칼럼 파일에 포함된 로우가 모두 같은 순서인 점에 의존

img
사실 테이블을 컬럼 단위로 저장

칼럼 압축

칼럼 지향 저장소는 대개 압축에 적합한데, 데이터를 압축하면 디스크 처리 요청을 더 줄일 수 있다.

칼럼의 데이터에 따라 다양한 압축 기법을 사용할 수 있다.
그 중 한 가지로 데이터 웨어하우스에서 특히 효과적인 비트맵 부호화(bitmap encoding) 이 있다.

img
비트맵 부호화 & 런랭스 부호화 예제

메모리 대역폭과 벡터화 처리

수백만 로우를 스캔해야 하는 데이터 웨어하우스 질의는 디스크로부터 메모리로 데이터를 가져오는 대역폭이 큰 병목이다.
또한 CPU 주기를 효율적으로 사용하도록 신경 써야 한다.

칼럼 저장소 배치는 CPU 주기를 효율적으로 사용하기에 적합하다.
칼럼 압축을 사용하면 같은 양의 L1 캐시에 컬럼의 더 많은 로우를 저장할 수 있다.
AND와 OR 연산자는 압축된 칼럼 데이터 덩어리를 바로 연산할 수 있게 설계할 수 있다.
이런 기법을 벡터화 처리(vectorized processing) 라고 한다.

칼럼 저장소의 순서 정렬

칼럼 저장소는 삽입된 순서로 저장하는 방식이 가장 쉽지만, 순서가 반드시 중요한 것은 아니다.
SS테이블에서 했던 것처럼 순서를 도입해 이를 색인 메커니즘으로 사용할 수 있다.

장점

  • 질의 최적화기는 모든 로우를 스캔하기보다 범위 질의에 포함되는 로우만 스캔 가능
  • 칼럼 압축에 도움

순서 지정은 여러개를 지정할 수 있지만 압축 효과는 첫 번째 정렬 키에서 가장 효과적이다.

다양한 순서 정렬

상업용 데이터 웨어하우스인 버티가에서 채택
데이터를 잃지 않기 위해 데이터를 여러 장비에 복제해 두는 작업이 필요하다.
복제 데이터를 서로 다른 방식으로 정렬 해서 저장하고 질의를 처리할 때 질의 패턴에 가장 적합한 버전 을 사용할 수 있다.

칼럼 지향 저장소에 쓰기

칼럼 지향 저장소, 압축, 정렬은 모두 읽기 질의를 더 빠르게 하지만 쓰기를 어렵게 한다는 단점이 존재
정렬된 테이블의 중간에 있는 로우에 삽입을 해야 하면 모든 칼럼 파일을 재작성해야 한다.

LSM 트리에서 이런 문제에 좋은 해결책있고 버티카가 채택한 방식이다.
모든 쓰기는 먼저 인메모리 저장소(WOS)에서 정렬된 구조에 추가해 디스크(ROS)에 쓸 준비를 한다.
충분한 인메모리 저장소 데이터가 모이면 디스크에 추가한다.(Moveout)
이렇게 모인 디스크의 데이터는 병합 하고 새로운 파일에 기록 한다.(Mergeout)

Vertica의 ROS와 WOS 참고
Vertica의 WOS Deprecation 참고

집계: 데이터 큐브와 구체화 뷰

데이터 웨어하우스 질의는 보통 SQL의 COUNT, SUM, AVG, MIN, MAX 같은 집계 함수를 포함한다.

이렇게 자주 사용되는 집계 함수를 캐시를 하기 위해 구체화 뷰(materialized view) 라는 방법을 사용한다.
구체화 뷰는 디스크에 기록된 질의 결과의 실제 복사본 이다.

복사본이기에 원본 데이터를 변경하면 구체화 뷰를 갱신해야 한다.
이런 갱신 비용이 비싸기 때문에 OLTP 데이터베이스에서는 자주 사용하지 않는다.
데이터 웨어하우스는 읽기 비중이 크기 때문에 구체화 뷰를 사용하는 전략은 합리적이다.

여기서 이야기할 데이터 큐브(data cube) 또는 OLAP 큐브라고 알려진 구체화 뷰는 일반화된 구체화 뷰의 특별 사례다.

img
합으로 데이터를 집계한 2차원 데이터 큐브

예제는 2차원이지만 일반적으로 2차원 이상이다.

구체화 데이터 큐브

  • 장점은 특정 질의를 미리 계산했기 때문에 해당 질의를 수행할 때 매우 빠름
  • 단점은 원시 데이터에 질의하는 것과 동일한 유연성이 없다는 점
This post is licensed under CC BY 4.0 by the author.

DDIA - 데이터 모델과 질의 언어

DDIA - 부호화와_발전