데이터 중심 애플리케이션 설계 3장 정리
대부분 애플리케이션은 하나의 데이터 모델을 다른 데이터 모델 위에 계층을 둬서 만듬
- 그래서 데이터 저장과 질의를 위한 다양한 범용 데이터 모델을 살펴본다.
관계형 모델과 문서 모델
Relation
- 각 관계는 순서 없는 tuple 모임
- 근원은 비즈니스 데이터 처리(트랜잭션이나 일괄처리)
NoSQL
- Not Only SQL
- RDB에서 지원하지 않는 특수 질의
- RDB보다 동적이고 표현력이 풍부한 데이터 모델 요구 등
객체 관계형 불일치
보통은 개발이 객체지향 프로그래밍으로 이루어짐
임피던스 불일치에의 문제
- 관계형 <-> 객체 사이의 전환 계층을 필요로 하는것
- ORM은 이러한 보일러플레이트 양을 줄여주지만 차이를 완벽히 숨길수는 없음
예시
이력서 같은걸 생각해보면 JSON표현으로 적합
- JSON을 쓰면 모든 정보가 한곳에 있어서 한번 가져오면 싹다 들고옴
다대일, 다대다 관계
- 지역이나 회사같은것들은 그냥 평문이 아니라 ID값을 가지고 있으면 여러 장점이 있다.
- 일관된 문자 저장
- 모호함 회피(동명의 다른거)
- 갱신의 편리함
- 현지화 지원(한 ID에 여러 언어를 저장한다면)
- 더 나은 검색 가능
- ID는 변경 필요X
- documentDB는 조인 지원이 약함(JSON같은거는 위에서 아래를 찾아가기는 쉽지만 하위를 통해 상위를 찾기는 힘드니까)
- 다대일 관계 적합하지 않다는것
- 하려면 DB가 아니라 애플리케이션에서 데이터를 가져와서 처리해야한다.
- 보면 처음에는 Join이 없어도 됐어도 구현하다보면 필요해질수 있다. 어떻게 하지?
- 네트워크 모델
- == 코다실 모델
- 얘는 다중 부모가 있을 수 있다.
- 아까 이력서같은걸로 생각해보면 지역->그지역사람 전체 이렇게 사람밑에 있으면서 동시에 지역밑에 있는 느낌
- 요런 식으로 하면 다대일, 다대다 모델링 가능
- 아까 이력서같은걸로 생각해보면 지역->그지역사람 전체 이렇게 사람밑에 있으면서 동시에 지역밑에 있는 느낌
- 레코드 접근을 하려면 최상위부터 쫘라락 내려가는 수밖에 없음
- 딱봐도 변경을 하거나 하면 모든 부모를 찾아가는 복잡한 문제가 있어 유연성 떨어짐
- 관계형 모델
- 얘는 우리가 아는 그 RDB같은걸로 단순히 튜플의 컬렉션이 다임
- 네트워크 모델
- 다대일 관계 적합하지 않다는것
- 지역이나 회사같은것들은 그냥 평문이 아니라 ID값을 가지고 있으면 여러 장점이 있다.
정리하자면 documentDB는 별도 테이블이 아닌 상위 레코드 내에 중첩된 레코드(일대다)를 저장함.
그러나 다대일과 다대다의 경우 RDB와 동일하고, 거기서는 FK라고 부르던걸 여기서는 Document Reference 즉 문서 참조라고 부른다.
RDB와 요즘의 documentDB
일단 차이만 집중하면
- documentDB의 장점
- 스키마 유연성, 지역성에 기인한 더 나은 성능
- 특정 애플리케이션의 경우 그곳의 데이터 구조와 비슷
- RDB
- 조인, 다대일, 다대다를 더 잘 지원함
- documentDB의 장점
보통 한번에 데이터를 가져오기만 하는 문서같은 느낌에는 documentDB
다대다같은걸 쓰면 RDB가 좋지
document의 스키마 유연성
JSON은 문서의 데이터에 어떤 스키마를 강요하지 않는다.
문서형데이터베이스는 종종 스키마리스로 불리지만 오해의 소지가 있다.
- 암묵적인 스키마가 있기는 한데 DB가 이를 강요하지 않음
- 읽기 스키마 : 데이터 구조는 암묵적으로 데이터를 읽을 때에만 해석된다.
- 쓰기 스키마 : RDB의 전통적인 방법이고 DB는 데이터가 스키마를 따르고 있음을 보장
- 그러니까 오브젝트별로 유형이 다르거나, 관계에 의해 변경하는 구조가 아니면 documentDB가 아주 좋음
질의를 위한 데이터 지역성
애플리케이션이 자주 전체 문서에 접근해야 할 때 저장소 지역성을 활용하면 성능 이점이 있다.
- 한번에 많은것을 요구한다면 이게 좋은거지 다가져오니까
구글 스패너, 오라클 다중 테이블 색인 클러스터 테이블, 빅테이블데이터모델의 칼럼 패밀리개념 등등
- 이거 신기하다... 데이터를 저장할 때에 아예 부모 및에 데이터를 저장시키는 식으로 지역성을 확보
RDB와 documentDB의 통합
RDB는 Json지원, document는 관계형 조인 지원
둘은 비슷해지고 있다.
데이터를 위한 질의 언어
SQL : 선언형
IMS, 코다실 : 명령형
프로그래밍언어는 보통 명령형이다.
- 명령형은 보통 순서랑 연산을 수행하도록 컴퓨터에게 지시한다.
SQL은 어떻게 가져와라! 하는 방법이 아니라 그 결과에 필요한 조건과 데이터 변환(정렬, 그룹화, 집계)를 지정하기만 하면 된다. -> 선언하는거니까
- 그러면 최적화는 최적화기가 알아서 해줌^~^
- 이 장점은 명령형보다 간결하고, 특히 중요한것은 상세 구현이 숨겨져있어 질의 변경 없이 성능 향상이 가능하다는것
- 병렬 실행에도 적합하다.
- 얘는 명령의 순서가 있는것도 아니라 그냥 조건대로 가져만 와라 하는거라 병렬에 더 좋음
웹에서의 선언형 질의
CSS같은것도 선언형이다(어디가 어떻게 변경되는걸 원하고 뭐 어찌 되는지는 관심없)
- 그거를 javascipt의 코어DOM 명령형을 쓰면 삭제되거나 태그 변경 등에 따라 코드를 바꾸어 주어야하거나 코드도 굉장히 길고 난해해진다.
맵리듀스 질의
이거 자바에서 스트림할때도 봤지
읽기 전용 질의를 수행할 때에 사용된다.
여기서는 몽고DB모델 사용에 대해서
- 선언형도 아니고 명령형도 아닌 어딘가
- 처리 프레임워크가 반복적으로 호출하는 조각 코드
- map, reduce함수 기반
제약사항이 있는데, 순수함수여야한다(입력으로 전달된 데이터만 사용가능, 추가적인 데이터베이스 질의 수행 불가, 사이드이펙트 없음)
- 요런 제약이 있어서 DB가 임의 순서로 어디서나 이 함수를 실행가능. 또 장애가 있어도 함수 재실행 가능
참고로 이거 좋긴 한데 이것만 쓸수 있는것도 아니고 작성이 어려울수도 있다.
JSON기반을 쓰는 집계 파이프라인이라는것도 있다.
GraphDB
오랜만에 본다...
다대다가 많으면 GraphDB를 쓴다.
그래프디비는 정점(노드 혹은 엔티티)랑 간선(관계 혹은 호)
속성 그래프 모델
- 네오포제이, 타이탄, 인피니티그래프 등
트리플 저장소 모델
- Datomic, 알레그로그래프 등
속성 그래프
정점
- 고유 식별자
- 유출 간선 집합
- 유입 간선 집합
- 속성 컬렉션(키-값 쌍)
간선
- 고유 식별자
- 간선이 시작하는 정점(꼬리정점)
- 간선이 끝나는 정점(머리 정점)
- 두 정점 간 관계 유형 설명하는 레이블
- 속성 컬렉션(키-값 쌍)
정점은 다른 정점과 간선으로 연결된다. 특정 유형과 관련 여부를 제한하는 스키마는 없다.
정점이 주어지면 정점의 유입과 유출 간선을 효율적으로 찾을 수 있고 그래프를 순회할 수 있다. 즉 일련의 정점을 따라 앞뒤 방향으로 순회
다른 유형의 관계에 서로 다른 레이블을 사용하면 단일 그래프에 다른 유형의 정보를 저장하면서도 데이터 모델을 깔끔하게 유지 가능
국가마다 지역 구조가 다른것같은 RDB로 보여주기 힘든것도 얘는 쉽게 보여줄 수 있음
사이퍼 질의 언어
속성 그래프를 위한 선언형 질의 언어
예를 들어
미국에서 유럽으로 이민 온 모든 사람들의 이름 찾기
를 한다면?- person에서 name이 US인 속성을 갖는 location이 될 때 까지 born_in간선을 따라감
- person에서 name이 eurpe인 속성을 갖는 location이 될 때 까지 live_in간선을 따라감
- 이거 두개가 MATCH되면 됨
이런 식으로 하면 수행의 상세한 것을 지시하지 않아도 최적화된 방법을 알아서 찾아간다(선언형)
SQL의 그래프 질의
RDB도 가능하다. 근데 어렵다.
재귀 공통 테이블 식? 을 쓴다고 한다..
트리플 저장소와 스파클
속성 그래프 모델과 거의 동등하다.
이거는 모든 정보를 주어, 서술어, 목적어처럼 간단한 세 부분 구문형식으로 저장한다.
주어
- 정점과 동등
목적어
- 문자열이나 숫자 등의 원시 데이터타입의 값
- 그래프의 다른 정점
시맨틱 웹
이미 사람이 읽을 수 있는 텍스트와 그림으로 정보를 게시하고 있으니 컴퓨터가 읽게끔 기계가 판독 가능한 데이터로도 정보를 게시하는건 어떨까? 하는 개념
자원기술프레임워크(RDF)는 서로 다른 웹사이트가 일관된 형식으로 데이터를 게시하기 위한 방법 제안
일단 지금은 잘 안쓰기는 한데 좋은 작업이 있음.
RDF데이터 모델
이거는 결국 인터넷에 있는 정보 교환을 위해 설계하는 것이다.
그래서 주어, 서술어, 목적어는 주로 URL이다.
스파클 질의 언어
구조적으로 사이퍼랑 비슷
얘는 근데 속성이랑 간선을 따로 구분하지 않고 서술어를 사용하기 떄문에 보기 더 쉽고 동일한 구문 사용 가능
데이터로그
질의 언어의 기반이 되는 초석을 제공하는 오래된 녀석
얘는 (주어, 서술어, 목적어) 형태의 트리플과는 다르게
서술어(주어, 목적어) 로 작성한다.
정리
요구사항에 맞춰서 어떤걸 쓸지 찾아보는게 중요
NoSQL
- 문서형 : 서로 연관은 없고 데이터가 문서 자체인 경우 좋음
- 그래프 : 서로 연관이 있을거라고 잠재적으로 생각하고 ㄱㄱ
### 3색 정리
- 이거는 다른사람도 꼭 알아야 한다.(아주 중요)
- ID는 아무런 의미가 없기 때문에 변경할 필요가 없다(34p)
- 예전에 공부했던 내용중 자연키vs인조키 관련인데 이거 은근 중요한 내용이라 생각해서 적었다.
- 선언형 / 명령형 언어에 대해(43p~)
- java stream에 대해 처음 배울 때에도 선언형에 대해 배웠는데, 실제로 장점을 알 수 있었다.
- 그래서 인덱스 생성이랑 질의가 달라도 옵티마이저가 알아서 최적화를 잘 해주는걸까? 싶은 느낌
- 근데 약간의 블랙박스 너낌
- 이거는 알면 좋을 것 같다.(빨간거 다음으로 중요)
- 문서형 데이터베이스와 관계형 데이터베이스의 통합(42p)
- 둘이 점점 비슷해지는게 있어보인다.
- RDB에 json같은거 넣을 수 있는게 기억난다
- 그리고 RDB에서도 join이 많은것을 지양해서 집계테이블을 만들고 있는데, 두개를 합치면 되게 좋아보임
- 예를 들어 책(좋아요한사람-json, 댓글상위몇명-json, 댓글갯수총합-int 등)
- 이거는 내가 개인적으로 흥미로웠다.(마음에 들었다)
- 데이터 지역성(41p ~)
- 아예 저장할때 부모 밑에 넣어버리는 방식인게 신기했다.
- 근데 이거는 좀 궁금한게 몇개 있는데
1. 여러 부모에게 소속되는 경우(예를들어 악어가죽 → 가방, 지갑 등에서 사용 등..)
1. 이런거는 가장 많이 사용되는 부모 아래에 일단 두는게 맞을것같기도 한데 모르겠다.
2. 만약 변경된다면??
1. 내가 이직을 하면 현대차→류찬 에서 카카오→류찬 이렇게 바뀔텐데 RDB의 업데이트는 주소를 그대로 두고 변경하지 않나 싶어서 지역성이 깨지지는 않을까? 싶었다.
3장
DB는 이제 데이터를 저장하고, 보여주는 역할을 수행하는게 기본 골자이다.
데이터 구조
많은 데이터베이스가 내부적으로 추가 전용 데이터 파일인 로그를 사용한다. (append-only)
근데 이 로그를 찾는 방법은 데이터를 찾기 위해 전체를 다 둘러봐야 한다. (O(n))
- 이거를 해결하기 위해 도입된 것이 바로 색인이다.
- 질의 성능을 높이기 위해 데이터를 찾아가는 메타데이터
- 참고로 이거를 만드는게 뭐 DB동작방식을 바꾸는건 아니다. 근데 데이터 저장시 성능을 늦추기는 한다(메타데이터를 만들어야 하므로)
- 즉, 저장 성능을 낮추지만 검색 성능을 놓임.
- 이 색인도 종류가 많으니까 내 상황에 맞춰 선택을 잘 해야 할 것이다.
- 즉, 저장 성능을 낮추지만 검색 성능을 놓임.
해시 색인
- 이거를 해결하기 위해 도입된 것이 바로 색인이다.
키-값
디스크 상 데이터 색인을 위해 인메모리 데이터 구조를 사용
- 해시 자체는 이미 인메모리에 있으므로
간단하게 말하면 키를 데이터파일 바이트오프셋에 매핑하는것.
- 그래서 새로운 데이터가 추가되면 이것도 갱신해야한다.
- 검색은 여기 키를 통해 간단히 검색 가능
비트캐스트(리악의 기본 저장소엔진)에서 기본적으로 이걸 쓰는데 해시맵을 전부 메모리에 유짛서 RAM에 모든 키가 저장된다는 조건을 전재로 고성능 읽기, 쓰기를 보장함.
- 이런거는 키값이 자주 갱신되는 상황에 유리하다.
- 즉, 새로운 데이터가 추가된다기 보다는 기존에 있는 데이터가 갱신되는 상황에 유리한것.
- 이런거는 키값이 자주 갱신되는 상황에 유리하다.
계속해서 새로운게 추가된다면? 인메모리에 저장하는 경우 크기가 부족해질 것이다.
- 이를 해결하기 위해 세그먼트를 도입한다.
- 세그먼트별로 저장하는거 -> 꽉차면 새로운 세그먼트를 파서 거기다가 저장함
- 컴팩션을 통해 세그먼트 병합하고 그게 끝나면 이전꺼를 버리면서 새로 만들어진 세그먼트를 쓰도록 한다.
- 그러면 이거는 모든 데이터에 대해 이루어져야겠네? 동시성 문제에서는 안전할까?
- 컴팩션을 통해 세그먼트 병합하고 그게 끝나면 이전꺼를 버리면서 새로 만들어진 세그먼트를 쓰도록 한다.
- 세그먼트별로 저장하는거 -> 꽉차면 새로운 세그먼트를 파서 거기다가 저장함
- 이를 해결하기 위해 세그먼트를 도입한다.
근데 해시를 쓰면 고려해야 할 것이 많음
- CSV아니고 원시문자열을 부호화하는 바이너리 형식이 빠름
- 레코드가 삭제된다면? 해시에서 삭제 표시를 적용해야한다.
- 이렇게 해야 이전 값을 무시하고 진행가능.
- 고장복구
- 해시는 인메모리값에 있는데 재시작되면?
- 다시 전체 세그먼트 확인하면서 해시맵 만드는건 말안되니까 다른 방법을 씀
- 각 세그먼트 해시맵 스냅숏을 디스크에 만들어두고 이를 통해 해시맵 복구
- 이렇게 하면 그냥 그 해시맵으로 만든는거라 그나마 간단
- 각 세그먼트 해시맵 스냅숏을 디스크에 만들어두고 이를 통해 해시맵 복구
- 부분적으로 레코드 쓰기
- 로그에 데이터 쓰던 도중에 DB가 죽어버리면?
- 체크섬을 포함하여 로그의 손상된 부분 탐지 무시 가능
- 송신자
- 모든 데이터 단위를 1의보수 연산(모든 비트 뒤집기)으로 합을 구함
- 다시 그 합의 1의보수 연산으로 checksum 생성. 요걸 같이 전송
- 수신자
- 수신된 메세지그램을 데이터로 나눔(여기에는 체크섬도 포함)
- 그리고 고거를 1의 보수 연산으로 더해서 합을 구함
- 합이 0이면 성공적으로 수신된거임
- 여기서 합이 0이 아니면 뭔가 문제가 있는거
- 송신자
- 체크섬을 포함하여 로그의 손상된 부분 탐지 무시 가능
- 로그에 데이터 쓰던 도중에 DB가 죽어버리면?
- 동시성 제어
- 데이터 파일 세그먼트는 추가 전용이거나 불변이라 다중 스레드로 동시 읽기 가능
- 쓰기는 하나의 쓰기 스레드만 사용
이렇게 해시맵을 추가해가면서 추가전용을 쓰는 이유는 장점이 있는데
- 당연히 속도가 빠름 -> 1515619874861651 이렇게 숫자 아무거나 쓰면 뇌빼고 쓰면 되는데 써가면서 혹시 앞에 있나? 있으면 그거 바꿔서 써야지 하면 느려지잖어
- 세그먼트 파일이 쓰기전용이거나 불변이면 동시성, 고장 복구 측면에서 훨씬 간단
- 값을 덮어쓰는 과정에서 DB가 죽는다 하면 그 뒤부터 다시 하면 되니까
- 데이터 조각화 회피 가능(이거는 계속 추가하고 이전꺼를 지우면 되니까)
당연히 단점도 있다.
- 결국 메모리에 저장하니까 키가 너무 많으면 문제가된다.
- 디스크에 저장하면 속도가 느려지니까 어지간하면 메모리에 저장하는거
- 범위해시에 비효율적
- 어차피 범위로 가져오면 값이 무엇이든 걔들은 append-only라 다른 위치에 저장된다.
- 각자 가져와서 각자 찾아야함
SS테이블과 LSM트리
개념 및 읽기 장점
- 결국 메모리에 저장하니까 키가 너무 많으면 문제가된다.
위의 저 데이터 세그먼트를 한번 키로 정렬해보자.
이런 식으로 정렬된 애들을 SS테이블 - Sorted String Table이라고 한다.
각 키는 병합된 세그먼트 파일 내에 한번만 나타나야 한다.
- 위에서 배운 컴팩션이 이를 이미 보장
이게 그냥 해시 색인에 비해 가지는 장점들은
- 세그먼트 병합은 메모리가 커도 간단하고 효율적이다.
- 일단은 이거는 세그먼트 자체가 이미 키값을 통해 정렬되어 있다는 것을 전재로 생각하자.
- 병합정렬이랑 유사하게
- 입력 파일을 읽고
- 각 파일의 첫번째 키를 확인(정렬 순서에 따라서 확인)
- 그리고 순서대로 확인하면서 값을 저장
- 여기서 만약 같은 데이터를 가진 경우 있는거 걍 씀(최신거를 유지 예전꺼 버림)
- 특정 키를 찾기 위해 모든 키의 색인을 유지할 필요가 없음.
- 이미 정렬이 되어있으니까 모두 가질 필요는 없고 드문드문 색인이 있으면 그 사이를 찾아가면 됨(이것도 충분히 빠름)
- 읽기 요청은 요청 범위 내에서 여러 키-값 쌍을 스캔해야한다.
- 레코드들을 블록으로 그룹화하고 디스크 쓰기 전에 압축 -> 희소 인메모리 색인의 각 항목은 압축된 블록의 시작을 가리킨다.
- 이거는 잘 이해가 않는데... 해시 색인이 있는 애들을 기준으로 그 내부를 압축한다는 것일까?
데이터 정렬은?
- 세그먼트 병합은 메모리가 커도 간단하고 효율적이다.
정렬 방식
- 레드블랙트리같은거 이용하면 쉽게 가능
- 값이 들어오면 이런 트리형태(멤테이블)로 하나씩 데이터를 추가하다가
- 임계값보다 커지면 SS테이블 파일로 디스크에 저장 -> 요게 최신 세그먼트가 된다.
- 이거 디스크에 기록하는 동안 새로운 맴테이블 인스턴스에 쓰기 기록하는거임.
- 읽기 요청이 들어오면
- 지금 기록중인 맴테이블
- 최신 세그먼트
- 점점 뒤로 가면서..
- 찾는다.
- 가끔 백그라운드에서 컴팩션
잘 동작하기는 한데... 한가지 문제가 있다.
- DB가 고장난다면 디스크로 저장되지 않은 맴테이블 최신 쓰기가 손실된다는것!
- 그래서 이를 해결하기 위해 매번 쓰기를 즉시 추가할 수 있게 분리된 로그를 디스크 상에 유지해야 한 다.
- 참고로 이 로그는 복원할 때에만 필요해서 딱히 순서 정렬은 필요없다.
- 그래서 맴테이블이 디스크로 저장되면 로그 버리기 가능
- 참고로 이 로그는 복원할 때에만 필요해서 딱히 순서 정렬은 필요없다.
- 그래서 이를 해결하기 위해 매번 쓰기를 즉시 추가할 수 있게 분리된 로그를 디스크 상에 유지해야 한 다.
SS테이블에서 LSM트리 만들기
- DB가 고장난다면 디스크로 저장되지 않은 맴테이블 최신 쓰기가 손실된다는것!
LSM(log-Structured Merge-Tree)
정렬된 파일 병합과 컴팩션 원리를 기반으로 하는 저장소 엔진
전문 검색 색인 엔진 -> 참고로 전문성 그게 아니라 ㄹㅇ전문이다. 여기있는거랑 같음
검색 질의로 단어가 들어오면 언급된 모든 문서(웹페이지, 제품 설명 등)에서 찾는다.
- 키를 단어(용어)로, 값은 단어를 포함한 모든 문서의 ID목록으로 하는 키-값 구조로 표현
- 이게 혹시 그 인덱스에 있던 불용어처리(가치없는거 필터링)이랑 어근 분석을 통해 찾는걸까?
- 아니면 한글에서는 n-gram인가 싶은데 아예 문자를 몇글자씩 잘라서 인덱싱하기인가
- 키를 단어(용어)로, 값은 단어를 포함한 모든 문서의 ID목록으로 하는 키-값 구조로 표현
이렇게 만들어진 색인을 SS테이블에 저장하고 보는 느낌인듯
성능 최적화
LSM의 경우 실제로 없는 키를 찾는다면 굉장히 느릴 수 있다.
- 맴테이블 -> 디스크에 있는 가장 오래된 세그먼트까지 가야하므로.
그걸 해결하기 위해 도입된 것이 블룸필터(Bloom filter)
- 집합 내용을 근사하여 키가 DB에 존재하지 않음을 알려주어 불필요한 디스크 읽기 절약 가능
위에서 있던 SS테이블의 압축/병행의 순서와 시기를 결정하는 전략으로는
- 크기 계층 컴팩션
- 상대적으로 좀 더 새롭고 작은 SS테이블을 상대적으로 오래됐고 큰 SS테이블에 연이어 병합
- 레벨 컴팩션
- 키 범위를 더 작은 SS테이블로 나누고 오래된 데이터는 개별 레벨로 이동하기 때문에 컴팩션을 점진적으로 진행해 디스크 공간 덜 사용
- 이게 대체 무슨 뜻일까.. 찾아봤는데 자바의 가비지 컬렉션이랑 비슷한 느낌으로 이해했다. -> 개념적으로 같다보다는, 사용 삔도 등에 따라 나누는 점이
- 쓰임에 따라 레벨로 나누어 두고, 그 레벨이 특정 크기에 도달하면 아래 레벨과 컴팩션하는것
- 이렇게 하면 점진적 컴팩션이 가능하다.
- 키 범위를 더 작은 SS테이블로 나누고 오래된 데이터는 개별 레벨로 이동하기 때문에 컴팩션을 점진적으로 진행해 디스크 공간 덜 사용
- 크기 계층 컴팩션
일단 LSM의 기본 개념은 백그라운드에서 연쇄적으로 SS테이블을 지속적으로 병합하는것.
- 데이터셋이 가능한 메모리보다 훨씬 더 크더라도 효과적이다.
- 데이터가 정렬된 순서로 저장돼있다면 범위 질의 효율적 실행 가능
매우 높은 쓰기 처리량 보장!!
- 디스크 쓰기가 순차적이기 때문 -> 뒤에서 색인 생성 및 병합하니까?
B트리
가장 널리 사용되는 색인 구조
요거 설명은 여기 잘 나와있음
참고로 저장할 때에 페이지가 부족하면 그걸 반쯤 채워진 페이지로 나누고 상위 페이지가 하위 페이지 내용을 알 수 있게 해둠
신뢰할 수 있는 B트리 만들기
이거는 덮어쓰기(변경)할 때에 페이지 위치가 변경되지 않는다고 가정한다.
- 즉 페이지 덮어쓰기를 해도 참조가 온전히 남음
- 요게 LSM같은 친구와의 아주 큰 차이이다.
- 근데 만약에 페이지를 변경할 때에(막 여러 데이터를 변경하는 도중에) DB가 고장난다면?
- 색인이 훼손될 수 있다.
- 이거를 스스로 복구할 수 있게 하려면 디스크 상에 쓰기 전 로그(WAL - 재실행 로그)라는 데이터 구조를 추가해 구현한다.
- 재실행 로그란 트리 페이지에 변경된 내용을 적용하기 전에 모든 B로그 트리의 변경사항을 기록하는 추가 전용 파일
- 이걸 통해 고장 이후 복구에서 일관성 있는 상태로의 복원 가능
- 이거를 스스로 복구할 수 있게 하려면 디스크 상에 쓰기 전 로그(WAL - 재실행 로그)라는 데이터 구조를 추가해 구현한다.
- 색인이 훼손될 수 있다.
- 즉 페이지 덮어쓰기를 해도 참조가 온전히 남음
그럼 만약에 하나의 데이터에 여러 스레드에서 동시에 접근한다면?
- 동시성 제어를 위해 latch를 사용하여 데이터 구조 보호
B트리 최적화
페이지 덮어쓰기와 고장 복구를 위해 쓰기 전 로그가 아니라 쓰기 시 복사를 채택한다.
- 변경된 페이지는 다른 위치에 기록하고 상위 페이지의 새로운 버전을 만들어 새로운 위치를 가리키게 함.
- 동시성 제어에 유용한 이유는? -> 기존에 데이터를 변경하지 않고 그걸 읽은 후에 새로운걸로 만드니까 어떻게 접근해도 가장 최신꺼를 가져오면 기존이 최신으로 변경된 것일거다.
- 변경된 페이지는 다른 위치에 기록하고 상위 페이지의 새로운 버전을 만들어 새로운 위치를 가리키게 함.
페이지에 전체 키 저장이 아니라 키를 축약해서 쓰면 공간 절약이 가능 -> B+트리가 이렇다고 한다.
- 키 범위 사이의 경계를 하게끔만 저장하면 된다.
- 참고로 페이지 하나에 키를 더 많이 채우면 더 높은 분기 계수를 갖고, 트리 깊이 수준을 낮출 수 있음.
페이지는 디스크 상 어디에나 위치 가능.
- 굳이 키 범위가 가까운 애들끼리 있을 필요는 없다는것.
- 다만 키 범위의 상당 부분을 스캔해야하면 모든 페이지에 대해 디스크 찾기가 필요
- 너무 막 디스크 단위로 하는건 비효율적이다.
- 그래서 일단은 연속된 순서로 나타나게 트리를 배치하려고 한다.
- 트리가 커지면 순서 유지가 어렵다. 이게 LSM이랑은 다른점인거다. LSM은 병합 과정에서 저장소의 큰 세그먼트를 한번에 다시 쓰므로 디스크 상에서 연속된 키를 유지하기 쉬움
- 그래서 일단은 연속된 순서로 나타나게 트리를 배치하려고 한다.
- 너무 막 디스크 단위로 하는건 비효율적이다.
트리에 포인터 추가.
- 각 리프 페이지가 양쪽 형제 페이지에 대한 참조를 가지면 상위페이지를 가지 않고 이동 가능.
프랙탈 트리같은 B트리 병합은 디스크 찾기를 줄위기 위해 로그 구조화 개념을 일부 빌림 -> 뭐여 이게
B트리와 LSM트리 비교
B트리가 더 오래돼서 성숙됨. 그래도 LSM도 관심을 받고있다.
LSM은 보통 쓰기에서 더 빠르구 B트리는 읽기에서 더 빠르다고 여겨진다.
- LSM이 읽기에서 느린 이유는 각 컴팩션 단계에 있는 여러 데이터 구조와 SS케이블 확인이 필요해서
LSM의 장점
B트리 색인은 단점
- 데이터 조각을 최소 2번 기록
- 쓰기전로그 한번
- 트리 페이지에 한번
- 장애 발생을 대비해 동일한 페이지를 두번 덮어쓰는 경우도 존재
- 해당 페이지 내 몇 바이트만 바껴도 한 번에 전체 페이지를 기록해야 하는 오버헤드(이건 왜????)
- 데이터 조각을 최소 2번 기록
LSM도 SS의 반복된 컴팩션과 병합으로 여러번 데이터를 다시씀.
- 이런 한번의 쓰기가 DB수명동안 디스크에 여러번의 쓰기를 야기하는걸 쓰기증폭이라 한다.
- 쓰기가 많은 애플리케이션에서 성능 병목은 데이터베이스가 디스크에 쓰는 속도일 수 있다.
- 쓰기 증폭이 바로 성능 비용인데, 저장소 엔진이 디스크에 기록할수록 디스크 대역폭 내 처리 가능한 초당 쓰기가 점점 줄어듬
- LSM은 B트리에 비해 쓰기 증폭이 낮고 순차적으로 컴팩션된 SS테이블 파일을 써서 B트리보다 빠르다(순차적으로 컴팩션되면 임의쓰기보다 빠를테니)
또 LSM은 B트리보다 압축률이 더 좋다.
- 그래서 B트리보다 디스크에 더 적은 파일을 생성한다.
- B트리는 파편화로 인해 사용하지 않는 디스크 공간이 남는다.
- LSM은 지속적인 SS테이블 재기록으로 저장소 오버헤드가 더 낮다.
- 특히 레벨 컴팩션을 사용하면 (level순서로 새로 쓰인 친구들부터 컴팩션을 진행하고, 이러면 일정 크기까지는 최신애들이 순차를 유지할테니)
SSD에서 이런 낮은 쓰기 증폭과 파편화 감소는 훨씬 유리하다.
- 데이터를 더 밀집해 표현하면 가능한 I/O대역폭 내에서 더 많은 읽기와 쓰기 요청 가능
LSM의 단점
LSM의 단점
- 컴팩션 과정이 진행중인 읽기와 쓰기 성능에 영향을 줄 수 있다.
- B트리는 이거를 예측하기 쉬움
- 또 다른 문제는 높은 쓰기 처리량에서 발생한다.
- 디스크의 쓰기 대역폭은 유한한데 초기 쓰기[ 로깅과 맴테이블을 디스크로 방출하는 일련의 흐름 ]와 백그라운드에서 수행되는 컴팩션 스레드가 이 대역폭을 공유해야 한다.
- 즉 DB에 데이터가 많아질수록 -> 데이터베이스가 커질수록 컴팩션을 위한 디스크 대역폭 필요
- SS기반 테이블은 이런 경우에도 유입 쓰기 속도를 조절하지 않아서 모니터링이 필요하다.
- 즉 DB에 데이터가 많아질수록 -> 데이터베이스가 커질수록 컴팩션을 위한 디스크 대역폭 필요
- 디스크의 쓰기 대역폭은 유한한데 초기 쓰기[ 로깅과 맴테이블을 디스크로 방출하는 일련의 흐름 ]와 백그라운드에서 수행되는 컴팩션 스레드가 이 대역폭을 공유해야 한다.
- 컴팩션 과정이 진행중인 읽기와 쓰기 성능에 영향을 줄 수 있다.
여기서 B트리의 장점은
- 각 키가 색인의 한 곳에만 정확하게 존재한다는 것.
- 트랜잭션 시맨틱 제공 DB는 B트리가 훨씬 매력적이다.
- B트리 색인에서는 트리에 직접 잠금 포함(지금은 이해X)
기타 색인 구조
세컨더리 인덱스
- 얘는 기본키 색인과 달리 키가 고유하지 않음. 즉 같은 키를 가진 많은 로우가 있을 수 있다는 것이다.
- 해결 방법은
- 각 값에 일치하는 로우 식별자 목록을 만들기
- 로우 식별자를 추가해 각 키를 고유하게 만드는 방법
- 해결 방법은 무엇이 되었든 B트리, LSM모두에서 사용 가능
색인 안에 값 저장
색인에서
- 키 : 질의가 검색하는 대상
- 값 : 질문의 실제 row일수도, 다른 곳에 저장된 row일수도 있다.
- 여기서 다른 곳에 저장된 row에의 값인 경우 로우가 저장된 곳을 heap file이라 하고 특정 순서 없이 데이터 저장
- heap 영역은 어디서든 접근이 가능하고 저걸로 위치를 참고하게 한다면 중복도 피할 수 있기 때문
- 이거는 키를 변경하지 않고 값을 변경할 떄에 효율적이다.
- 참고로 많은 공간을 필요로 하는 경우 힙에서(여기는 파편화가 있으니까) 다른 곳으로 찾아가야해서 곤란해진다.
- 그래서 그냥 인덱스 자체에서 색인된 로우를 저장하는것이 좋을때가 있다.
- MySQL에서 클러스터링 인덱스가 기본으로 존재하는것도 이와 비슷한 것.
- 그래서 MySQL에서는 secondary index가 기본키를 참조한다.
- 참고로 클러스터드인덱스(색인 안에 모든 로우 데이터 저장)이랑 비클러스터드인덱스(데이터 참조만 저장) 사이의 인덱스를 커버링 색인이나 포괄열이 있는 색인이라고 한다.
- 색인 안에 테이블 컬럼 일부 저장.
- 이렇게 하면 색인만 사용해 일부 질의 응답 가능(그래서 커버한거라 커버링)
- 색인 안에 테이블 컬럼 일부 저장.
- 클러스터드 색인이랑 커버링 색인은 읽기 성능을 높일 수 있지만 추가적인 저장소가 필요하고 쓰기 과정 오버헤드가 발생한다.
- 참고로 클러스터드인덱스(색인 안에 모든 로우 데이터 저장)이랑 비클러스터드인덱스(데이터 참조만 저장) 사이의 인덱스를 커버링 색인이나 포괄열이 있는 색인이라고 한다.
- heap 영역은 어디서든 접근이 가능하고 저걸로 위치를 참고하게 한다면 중복도 피할 수 있기 때문
- 여기서 다른 곳에 저장된 row에의 값인 경우 로우가 저장된 곳을 heap file이라 하고 특정 순서 없이 데이터 저장
다중 칼럼 색인
결합 색인
- 하나의 키에 여러 필드를 단순히 결합.
다차원 색인
- 한 번에 여러 칼럼에 질의하는 조금 더 일반적인 방법
- B트리, LSM트리 모두 여기에 효율적 응답 불가.
- R트리같은거 쓰면 됨
전문 검색과 퍼지 색인
지금까지의 색인은 정확한 데이터 대상으로 키의 정확한 값이나, 정렬된 키의 값의 범위를 질의할 수 있다고 가정한다.
근데 철자가 틀린 등의 유사한 것은?
- 보통 전문검색은 동의어로 질의를 확장한다.
- 요런거는 보통 작은 인메모리 색인이 필요함.
모든 것을 메모리에 보관
- 보통 전문검색은 동의어로 질의를 확장한다.
여기서 설명한 것들은 디스크 한계에 대한 해결책이었다.
디스크는 메인메모리와 비교해 다루기 어렵다.
다만 디스크의 장점은
- 데이터의 지속성(전원이 꺼져도 데이터 유지)
- 가격이 쌈
근데 램이 점점 저렴해져서 인메모리 데이터베이스도 개발됐다.
memcached같은거는 장비 재시작시 데이터 손실을 허용하는 캐시로 사용
근데 그렇지 않은 인메모리 DB들이 많음.
- 그 방법은 특수 하드웨어 사용, 디스크에 변경사항 로그 기록, 디스크에 주기적 스냅숏 기록, 다른 장비에 인메모리 상태 복제 등등이 있음.
인메모리DB의 장점은 디스크에서 읽지 않아도 되기 때문에 빠른것만은 아님(뭐 디스크도 그냥 메모리에 두고 쓰면 된다고는 하는데, 이건 좀..)
- 레디스의 우선순위 큐와 셋같은 데이터 구조를 제공
안티 캐싱
- 메모리가 충분하지 않을 때 가장 최근에 사용하지 않은 데이터를 메모리에서 디스크로 내보내고 나중에 다시 접근할 때에 가져오는 방식
- 이것도 근데 어쨌든 전체 색인이 메모리에 있어야 한다.
트랜잭션 처리나 분석
데이터베이스가 많은 종류의 데이터를 사용하기 시작했지만 기본적인 접근 패턴은 비즈니스 트랜잭션 처리와 유사하다.
- 애플리케이션은 색인을 사용해 일부 키에 대한 적은 수의 레코드를 찾는다.
- 레코드는 사용자 입력을 기반으로 삽입/갱신된다.
- 이런거는 대화식으로 온라인 트랜잭션(OLTP)라고 한다.
데이터 분석에도 DB를 많이 쓰는데, 이거는 많은 레코드를 스캔해 일부 칼럼만 읽어 집계통계(합, 카운트, 평균 등)를 계산해야 한다.
- 이런거를 보통 온라인 분석 처리(OLAP)이라고 한다.
OLTP랑 OLAP는 처음에는 동일한 방법으로 쓰이다가 나중에는 OLTP를 분석 목적으로는 쓰지 않았다.
- 분석용으로 쓰는 개별 데이터베이스는 데이터 웨어하우스라고 불림
데이터 웨어하우스
간단하게 말하면 OLTP는 높은 가용성과 낮은 지연시간을 갖기를 원하므로, 여기 방해되지 않게 읽기 전용 공간에서 마음껏 질의할 수 있게 해둔게 데이터 웨어하우스임.
데이터 웨어하우스와 OLTP데이터베이스 차이점
데이터 웨어하우스의 데이터 모델은 가장 일반적인 관계형 모델을 사용한다.
표면적으로는 둘다 SQL질의를 지원해서 비슷해 보인다.
- 근데 이거는 질의 패턴이 분석에 맞춰있어서 내부가 완전 다름
분석용 스키마: 별 모양 스키마와 눈꽃송이 모양 스키마
별 모양 스키마
- 차원 모델링이라고도 함
- 많은 데이터 웨어하우스에서 사용
- 각 로우는 이벤트를 의미하고
- 누가, 언제, 어디서, 무엇을, 어떻게, 왜 라는 이벤트 속성을 각 로우에서 나타냄.
- 그래서 가운데에 사실테이블이 있고 주변에 별처럼 차원테이블로 둘러쌓여 있어서 별모양임
눈꽃송이 모양 스키마
- 차원이 하위차원으로 더 세분화된다.
칼럼 지향 저장소
사실 테이블은 보통 칼럼이 100개 이상이지만 일반적인 데이터 웨어하우스 질의는 한번에 4개 또는 5개 칼럼만 접근함.
- 이유는 아마 분석을 위해서는 필요한 정보만 계산해서 가져오면 되니까 다른 정보는 불필요해서
대부분의 OLTP데이터베이스는 로우 지향 방식으로 데이터를 배치한다.
- 즉 한 로우의 모든 값은 서로 인접하게 저장되는것(documentDB와 유사)
칼럼 지향 저장소의 기본 개념은 간단한다.
- 모든 값을 하나의 로우에 저장하지 않는 대신 각 칼럼별로 모든 값을 함께 저장하는것.
- 각 칼럼을 개별 파일에 저장하면 질의에 사용되는 칼럼만 읽고 구분 분석하면 된다.
칼럼 압축
압축하면 디스크 처리량 줄일 수 있다.
비트맵 부호화
- 보통 고유값의 갯수는 로우 수보다 적다(판매 갯수는 수십억이어도 제품수는 그만큼 안되는)
- 그러면 n개의 고유값을 가진 칼럼을 n개의 비트맵으로 변환 가능
- 1번이3번, 2번이10번, 3번이1번 판매 ....
근데 이거 조건이 여러개로 검색하면 어찌되는겨
메모리 대역폭과 벡터화 처리
이거 보면 수백만 로우를 스캔해야 하는데, 이러면 디스크에서 메모리로 가져오는 대역폭이 큰 병목이다.
솔직히 이해 못하겠음...
칼럼 저장소의 순서 정렬
로우가 저장되는 순서가 반드시 중요하지는 않다.
- 삽입된 순서로 저장하는게 가장 쉽다.
다만 이전의 SS테이블처럼 순서를 도입해 이를 색인 메커니즘으로 사용할 수 있다.
- 칼럼별로 저장해도 데이터는 한번에 전체 로우를 정렬
- 예를 들어 질의가 지난달 같은걸 한다면 1차 정렬키를 date로 하는게 맞는것처럼
- 질의 확인 속도에도 도움됨
- 예를 들어 질의가 지난달 같은걸 한다면 1차 정렬키를 date로 하는게 맞는것처럼
- 칼럼별로 저장해도 데이터는 한번에 전체 로우를 정렬
이거는 압축에도 도움이 된다.
- 기본 정렬 컬럼에 고유값을 많이 포함하지 않는다면 보통은 같은 값이 연속해서 길게 반복된다.
- 그러면 압축이 쉬움(비트맵 보면)
- 기본 정렬 컬럼에 고유값을 많이 포함하지 않는다면 보통은 같은 값이 연속해서 길게 반복된다.
첫 번쨰 정렬 키에서 가장 강력하다(두번째, 세번째는 아무래도 반복된 값이 적으므로)
다양한 순서 정렬
다양한 질의는 서로 다른 정렬 순서의 도움을 받는다.
- 그럼 같은 데이터를 다양한 방식으로 정렬한다면??
- 칼럼 지향 저장에서 여러 정렬 순서를 갖는건 로우 지향 저장에서 여러 2차 색인을 갖는거랑 비슷함.
- 차이는 칼럼저장에서는 데이터를 가리키는 포인터가 없고 값을 포함한 칼럼만 존재한다는것.
- 칼럼 지향 저장에서 여러 정렬 순서를 갖는건 로우 지향 저장에서 여러 2차 색인을 갖는거랑 비슷함.
칼럼 지향 저장소에 쓰기
- 그럼 같은 데이터를 다양한 방식으로 정렬한다면??
데이터 웨어하우스의 대부분 작업은 분석가가 수행한다.
칼럼 지향 저장소, 압축, 정렬은 읽기를 더 빠르게하지만 쓰기를 어렵게 하는 단점이 있다.
압축된 상태에서 B트리의 제자리 갱신은 불가능
- 정렬된 테이블의 중간에 삽입하면 모든 칼럼 파일 재작성
LSM트리라는 해결책이 존재
- 먼저 인메모리 저장소로 이동해 정렬된 구조에 추가.
- 이후 디스크에 쓴다.
- 이 떄 인메모리 저장소가 로우지향인지 칼럼지향인지는 중요하지 않음.
- 충분히 쓰면 디스크의 칼럼 파일에 병합하고 대량으로 새로운 파일에 기록
- 이 떄 인메모리 저장소가 로우지향인지 칼럼지향인지는 중요하지 않음.
- 이후 디스크에 쓴다.
집계 : 데이터 큐브와 구체화 뷰
- 먼저 인메모리 저장소로 이동해 정렬된 구조에 추가.
칼럼 저장소는 즉석 분석 질의에 대해 상당히 빨라서 급속하게 인기를 얻고 있다.
구체화 집계
- 보통 데이터 웨어하우스 질의는 집계함수를 포함한다.
- 동일한 집계를 다양한 질의에서 사용하면 캐싱하는것이 좋다.
- 보통 데이터 웨어하우스 질의는 집계함수를 포함한다.
구체화 뷰
- RDB모델에서 이런 캐시를 대개 표준 (가상) 뷰로 정의한다.
- 테이블같은 객체로 일부 질의 결과 저장.
- 그래서 원본 데이터 변경시 구체화 뷰의 변경이 필요하다.
- 이거 딱 회사에서 RDB에서 쓰는 집계테이블이랑 비슷하네. 다만 그게 즉시갱신되는.
- 테이블같은 객체로 일부 질의 결과 저장.
- RDB모델에서 이런 캐시를 대개 표준 (가상) 뷰로 정의한다.
데이터 큐브
- OLAP큐브라고도 함
- 큐브라는거에서 알다시피, 보통은 사실이 2차원 이상인데(서로 연관된것들이 많은) 요거를 잘 계산해서 저장하고 쓰는거임!
- 단점은 유연성이 없는것
- 예를 들어 10달러 기준, 11달러 기준, 12달러 기준... 요렇게 한다면 여기서 찾기는 불가능하지.
정리
DB저장 시 발생하는 것. 그리고 데이터 질의에서 DB가 수행하는 작업
저장소 엔진
- 트랜잭션 처리 최적화(OLTP)
- 사용자 대면이라 대량 요청 받기 가능.
- 보통은 작은 수의 레코드를 다루는게 좋다(부하문제)
- LSM : 파일 추가와 오래된 파일의 삭제만 허용. 한번 쓰면 갱신없음.
- B트리 : 제자리 갱신 관점에서 겊어쓰기 가능한 고정 크기 페이지 셋으로 디스크를 나눔.
- 분석 최적화(OLAP)
- 비즈니스 분석가가 주로 사용
- OLTP에 비해 적은 수의 질의를 다루지만 다루기 까다롭고 레코드를 많이 타고있는 것을 가져오는것.
- 트랜잭션 처리 최적화(OLTP)
어떤 상황에서 어떤걸 쓰고, 무엇이 이득인지를 잘 파악하자.
3색 정리
이거는 다른사람도 꼭 알아야 한다.(아주 중요)
- 색인에서 힙 파일로 다시 이동하는 일은 읽기 성능에 불이익이 너무 많기 때문에 어떤 상황에서는 색인 안에 바로 색인된 로우를 저장하는 편이 바람직하다. 이를 클러스터드 색인이라고 한다.
- 결국 이것도 읽기의 성능을 위해 도입된 느낌
- 그리고 여러 인덱스가 존재할 때에 이를 바라보게 하는 것이 클러스터드 색인인지 힙인지도 차이가 큰 느낌이 든다.
- 개인적으로는 힙을 쓰는 장점을 잘 모르겠기는 한데…? 클러스터드를 쓰면 갱신 문제나 확인 문제가 적지 않을까 싶다.
- 그리고 여러 인덱스가 존재할 때에 이를 바라보게 하는 것이 클러스터드 색인인지 힙인지도 차이가 큰 느낌이 든다.
- 결국 이것도 읽기의 성능을 위해 도입된 느낌
- 색인에서 힙 파일로 다시 이동하는 일은 읽기 성능에 불이익이 너무 많기 때문에 어떤 상황에서는 색인 안에 바로 색인된 로우를 저장하는 편이 바람직하다. 이를 클러스터드 색인이라고 한다.
이거는 알면 좋을 것 같다.(빨간거 다음으로 중요)
- 레벨 컴팩션은 개별 레밸로 이동하기 때문에 디스크 공간을 덜 사용한다(p81)
- 이렇게 하면 최근에 정렬된 애들이 순차성을 보장할 수 있다는 장점도 있는데, 그 덕분에 이후에 성능에도 영향을 끼친다는 점에서 중요한 것 같았다.
- 다중 스레드의 접근에서의 레치 p84~85
- java에서도 레치가 있는데, 여기서 어떤 식으로 이걸 통해 동시성을 제어할까 생각해 보았다.
- 결국은 한번에 하나의 데이터에만 접근할 수 있도록 처리해둔것
- 그렇다면 삭제-후-재기입 이전까지 다른 스레드에서는 데이터의 검색 자체도 불가능하지 않을까?
- 아 그래서 LSM의 쓰기가 B트리보다 좋은 거구나!! 하는 느낌이 들었다.
- 걔는 그냥 계속 써가면서 작성 시간에 따라 데이터를 보면 되므로.
- 아 그래서 LSM의 쓰기가 B트리보다 좋은 거구나!! 하는 느낌이 들었다.
- 그렇다면 삭제-후-재기입 이전까지 다른 스레드에서는 데이터의 검색 자체도 불가능하지 않을까?
- 근데 DB에서 그냥 여러 쓰레드로 동시접근하면 여러 변환이 되던데 그건 뭐지?
- 결국은 한번에 하나의 데이터에만 접근할 수 있도록 처리해둔것
- java에서도 레치가 있는데, 여기서 어떤 식으로 이걸 통해 동시성을 제어할까 생각해 보았다.
- 레벨 컴팩션은 개별 레밸로 이동하기 때문에 디스크 공간을 덜 사용한다(p81)
이거는 내가 개인적으로 흥미로웠다.(마음에 들었다)
- 블룸 필터 을 쓰면서 해시의 문제를 해결한것 p81 (결국 존재하는지를 확인하는것)
- 뭔가 로그 → 해싱 → 해시정렬 → 디스크저장 → 블룸필터 이렇게 흐름적으로 문제를 해결해 나가는게 굉장히 흥미롭고 재밌었다.
- 인메모리 관련 p91
- 진짜 persistence가 가능해지면 엄청나게 좋을것같은 느낌이 든다.
- 사실 근데 문제가 없다는 가정하에 그냥 캐싱만 해도 상관없기도 하고 암튼 그럼
- 진짜 persistence가 가능해지면 엄청나게 좋을것같은 느낌이 든다.
- 블룸 필터 을 쓰면서 해시의 문제를 해결한것 p81 (결국 존재하는지를 확인하는것)
궁금한 점…
- p86에서 왜 B트리는 몇 바이트만 바뀌어도 한번에 전체 페이지를 기록해야 하는거지??
- 그냥 페이지 분할을 말하는걸까?
- 데이터 웨어하우징 p94는 결국 기존DB가 아닌 새로운 곳에서 데이터를 통해 분석하는 것이라는 생각.
- 근데 master - slave를 봐도 둘간 데이터 불일치는 무조건 발생할 것 같은데 이를 어떻게 해결했을까?
- master - slave는 결국 중요한 데이터를 볼때 master를 보도록 한다고 듣긴했는데
- 5장에 있던 그 파티셔닝일까? → 그런데 이건 결국 실제 서비스용이 아니라 분석용인듯
- 근데 master - slave를 봐도 둘간 데이터 불일치는 무조건 발생할 것 같은데 이를 어떻게 해결했을까?
- p86에서 왜 B트리는 몇 바이트만 바뀌어도 한번에 전체 페이지를 기록해야 하는거지??