😊 Go to Learn이란?
K-devcon에서 주최하는 멘토링 프로그래밍으로 각 분야에서 전문가이신 멘토분들의 멘토링을 통하여 약 2-3달간 진행하는 프로그램입니다.
Go to Learn 1기 같은 경우 Flutter, Back-end, Full-stack, Writing 등 여러가지 주제가 담긴 멘토링 프로그램이 있었습니다.
그 중 Back-end를 중심으로 진행하는 DDIA 프로그램 같은 경우 데이터 중심 애플리케이션 설계라는 책을 매주 1장 씩 정독하고 요약하면서 괸련된 이야기를 논의하면서 진행하고 있습니다.
K-devcon 이란? : IT 정보를 공유하거나 위에서 설명한 Go to Learn 스터디 및 밋업을 개최하는 활동을 하고있는 IT 커뮤니티입니다.
K-devcon 홈페이지 바로가기
📖 3장 요약 및 정리
데이터베이스가 데이터를 저장하는 방법과 데이터를 요청할 때 다시 찾을 수 있는 방법을 설명한다.
또한 여러 저장소 엔진 중 적합한 엔진을 선택하는 방법을 설명한다.
(트랜젝션에 맞춘 엔진과 분석을 위한 엔진)
데이터 구조
로그(log) : 많은 데이터 베이스 내에 들어있는 추가 전용 데이터 파일 혹은 레코드
- 애플리케이션 로그랑은 다르다. (애플리케이션 로그 : 애플리케이션 내 무슨 일이 일어났는지 알아내는 텍스트)
간단한 데이터베이스의 경우
- set : 한 번 실행 가능
- get : N번 실행되기 때문에 많은 레코드가 있으면 성능이 좋지 않음
- 읽기를 더 효율적으로 처리하기 위해서 색인이 등장하게 되었다.
색인 : 데이터베이스에서 특정 키의 값을 효율적으로 찾기 위한 데이터 구조
- 기본 데이터에서 파생된 추가적인 구조이다.
- 잘 선택한다면 읽기 색인가 향상이 되지만 쓰기 속도를 떨어트린다.
색인
해시 색인 : 키-값 저장소의 형태로 구현하는 방법
- 단순하지만 실제로 많이 사용하는 접근법이다.
- 각 키의 값이 자주 갱신될 때 비트캐스트를 활용한다.
- 세그먼트(segment) : 디스크 공간을 효율적으로 관리하기 위한 방법
- 특정 세그먼트 크기에 도달하게 되면 새로운 세그먼트 파일에서 쓰기를 수행한다.
- 세그먼트가 쓰여진 이후 변경할 수 없기 때문에 병합한 새그먼트는 새로운 파일을 생성한다.
- 병합과 컴팩션은 백그라운드에서 실행 → 읽쓰기 요청을 계속 수행할 수 있다.
- 구현
- 바이너리 파일 형식 / 레코드 삭제 / 고장 복구 / 부분적으로 레코드 쓰기 / 동시성 제어
- 추가전용설계 방식 : 예전 값을 새로운 값으로 덮어서 새로운 파일을 갱신하는 방법
- 제한 사항
- 키가 너무 많으면 문제가 된다. → 디스크(메모리)에서 저장하기 때문
- 범위 질의에 효율적이지 않다.
SS 테이블 (Sorted String Table) : 세그먼트 파일 형식에서 키를 기준으로 정렬하는 방식
- 장점
- 세그먼트 병합으로 사용 가능한 메모리보다 크더라도 간단하고 효율적이다.
- 특정 키를 찾기 위해 메모리에 모든 키의 색인을 유지할 필요가 없다.
- 읽기 요청은 디스크에 쓰기 전에 압축한다.
- 디스크 공간을 절약한다는 점 외도 I/O 대역폭 사용도 줄일 수 있다.생서
- 생성과 유지
- 레드 블랙 트리 & AVL 트리를 이용하여 임의 순서로 키를 삽입하여 읽기가 가능하다.
- 멤테이블 → 레드 블랙 트리 & AVL 트리
- 매번 쓰기를 즉시 추가할 수 있게 분리된 로그를 디스크 상으로 유지해야한다.
- 데이터베이스 손상 시 맴테이블 내 최근 데이터 손실을 막기 위함
- LSM 저장소 엔진 : 정렬된 파일 병합과 컴팩션 원리를 기반으로하는 저장소 엔진
- 성능 최적화
- 블룸 필터(Bloom filter) : 집합 내용을 근사한 메모리 효율적 데이터 구조
- 존재하지 않는 키를 찾는 접근을 최적화하기 위한 저장소 엔진으로 추가
- 크기 계층 컴팩션 : 상대적으로 좀 더 새롭고 작은 테이블을 오래되었고 큰 테이블을 연이어 병합
- 레벨 컴팩션 : 키 범위를 더 작은 테이블을 나누고 오래된 데이터는 개별 레벨로 이동
- 컴팩션을 점진적으로 진행해 디스크 공간을 덜 사용
B트리 (B Tree)
- 관계형 데이터베이스에서 표준 색인 구현으로 사용될 뿐만 아니라 비관계 데이터베이스에서도 사용된다.
- 고정 크기 블록이나 페이지로 나누고 한 번에 하나의 페이지에 읽쓰기를 한다.
- 이러한 설계는 근본적으로 하드웨어와 관련이 있다.
- 색인에서 키를 찾으려면 루트(root)에서 시작한다.
- 최종적으로 개별 키(리프 페이지)에 도달하게 된다.
- 리프 페이지 : 각 키의 값을 포함하거나 찾을 수 있는 페이지의 참조를 포함
- 분기 계수(branching factor) : 한 페이지에서 하위 페이지를 참조하는 수
- 트리가 계속 균형을 유지하는 것을 보장한다.
- 고아 페이지의 발생 : 삽입 때문에 페이지가 많아서 페이지를 나눠야 할 때 일부 페이지가 기록하고 데이터베이스가 고장 날 수 있다.
- 쓰기 전 로그 (재실행 로그) : 데이터베이스가 고장 상황에서 스스로 복구할 수 있게 추가로 구현한다.
- 최적화
- 일부 데이터베이스는 쓰기 시 복사 방식을 사용한다.
- 페이지에 키를 축약해 쓰면 공간을 절약할 수 있다.
- B 트리 구현에서 리프 페이지를 디스크 상에서 연속된 순서로 나타나게끔 할 수 있다.
- 트리에 포인터를 추가
- 프렉탈 트리
- B 트리와 LSM트리
- LSM 트리는 보통 B 트리보다 쓰기 처리량을 높게 유지할 수 있다.
- LSM 트리는 압축률이 더 좋다.
- 그러나 LSM 트리는 컴팩션 과정이 때로는 진행 중인 읽쓰기의 성능에 영향을 준다.
기타 색인 구조
- 보조 색인(Secondary index) : 조율적으로 조인을 수행하는데 결정적인 역할을 한다.
- 색인 안에 값 저장하기 → 힙 파일 / 클러스터드 색인 / 커버링 색인 / 포괄열이 있는 색인
- 다중 칼럼 색인
- 결합 색인 : 다중 칼럼 색인의 가장 일반적인 유형이다.
- 결합 색인은 하나의 키에 여러 필드를 단순히 결합하는 형태이다.
- 다차원 색인 : 한 번에 여러 칼럼에 질의하는 조금 더 일반적인 방법
- 전문 검색과 퍼지 색인
- 철자가 틀린 단어 및 유사한 키와 같은 애매모호한 질의에서 사용하는 기술
- 트라이(tire)와 유사하다.
- 모든 것을 메모리에 보관하는 방법도 있다.
- 인메모리 데이터베이스 : 여러 장비 간 분산해서 보관
- 안티 캐싱
- 비휘발성 메모리
트랙젝션 처리 & 분석
온라인 트랜잭션 (online transaction processing / OLTP)
- 커미셜 트랜잭션처럼 사용자 입력을 기반으로 레코드를 삽입되거나 갱신
- 대화식으로 진행된다.
온라인 분석 처리 (online analytic processing / OLAP)
- 더 나은 의사결정을 하게끔 돕도록 제공하는 데이터 베이스 사용 패턴이다.
- 많은 수의 레코드를 스캔하여 레코드 당 일부 칼럼만 읽어 집계 통계를 계산하는 방법을 활용한다.
- 데이터베이스를 데이터 분석에도 많이 사용하기 시작하면서 등장하기 시작하였다.
데이터 웨어 하우스 (data warehouse)
- OLTP 시스템을 분석 목적으로 사용하지 않고 개별 데이터 베이스에서 분석을 하는 경향이 있었다.
- 위의 분석을 사용하는 개별 데이터 베이스를 데이터 웨어 하우스라고 한다.
ETL(Extract-Transform-Load)
- 데이터 웨어하우스를 데이터로 가져오는 과정이다.
- 위의 과정은 OLTP 작업에 영향을 주지 않는다.
- 데이터를 추출하고 분석 친화적인 스키마로 변환하고 깨끗하게 정리 후 적재하는 방법을 사용한다.
OLTP와 데이터 웨어 하우스의 차이점
- 둘 다 SQL 질의 인터페이스를 지원하기 때문에 비슷해보인다.
- 다른 질의 패턴에 맞게 최적화되었기 때문에 내부는 다르다.
분석용 스키마
- 별 모양 스키마 : 분석에서는 다양성이 적기 때문에 위와 같은 정형화된 방식을 사용한다.
- 사실 테이블 : 각 로우에서 특정 시각에서 발생한 이벤트가 담겨있다.
- 차원 테이블 : 5W1H의 정보가 담겨있다.
- 눈꽃송이 모양 스키마
- 별모양에서 차원이 하위차원으로 더 세분화된 스키마를 의미한다.
- 별모양 스키마보다 더 정규화되었다.
칼럼 지향 저장소
대부분의 OLTP 데이터베이스에서 저장소는 로우 지향 방식으로 데이터를 배치한다.
- 칼럼 지향 저장소 : 모든 값을 하나의 로우에 함께 저장하지 않는 대신 각 칼럼 별로 모든 값을 함께 저장
- 비관계형 데이터에서도 동일하게 적용할 수 있다.
칼럼 압축
- 데이터를 압축하면 디스크 처리량을 더 줄일 수 있다.
- 칼럼 지향 저장소는 압축에 적합하다.
- 비트맵 부호화 : 데이터 웨어하우스에서 사용하는 압축 기법 중 하나
- N이 매우 작으면 로우 당 하나의 비트로 저장 할 수 있다.
- N이 크면 대부분의 비트맵은 0이 더 많다. → 추가적으로 런 랭스 부호화
- 벡터화 처리 : 비트 연산자를 이용하여 압축된 칼럼 데이터 덩어리를 바로 연산 할 수 있도록 처리하는 방법
- 칼럼 저장소에서 로우가 저장되는 순서가 반드시 중요하지 않다.
- 단, 칼럼별로 저장되었을지 라도 데이터는 한번에 전체 로우를 정렬해야한다.
- 정렬된 순서의 장점
- 그룹화하거나 필터링하는 질의에 도움이 된다.
- 칼럼 압축에 도움이 된다.
- LSM 트리를 활용하여 칼럼 지향 저장소의 쓰기를 최적화 할 수 있다.
데이터 큐브와 구체화 뷰
- 구체화 집계 : 질의가 자주 사용하는 일부 카운트나 합을 캐시하는 방법
- 데이터 큐브 → 다양한 차원으로 그룹화한 집계 테이블으로 구성
😉 필자의 생각
위의 장은 데이터를 어떻게 가져오는지 혹은 데이터를 어떻게 불러오는지에 대해 정리하는 내용을 주를 이루었다. 그 중 데이터를 저장하는 방법 같은 경우 트리 및 세그먼트, 트라이 등 다양한 자료구조들을 어떻게 활용하는지에 대하여 알 수 있었고, 왜 트리 자료구조를 채택하게 되었는지 알게 되었다.
트랙젝션 처리 및 저장소 같은 경우 여러 논의가 오갔었는데 그 중 가장 인상 깊었던 논의는 과연 별 모양 스키마에 대한 활용에 대한 논의였었다. 별 모양 스키마의 활용 같은 경우 적게 조인할 수 있기 때문에 국내 주식 원장 데이터 같은 것을 다룰 때 크게 활용된다고 한다.
벡터화 처리 같은 경우 지난 2장 논의에서 이어지는 이야기로써 그래프형 모델 데이터베이스와 활용하여 자연어 분석 및 LLM에 활용되는 사례도 몇몇 알게 되었다.