Zero to Hero

데이터베이스를 사용해야 하는 이유

1. 대량의 데이터 중에서 필요한 것을 빨리 반환할 수 있다.

2. 대량의 데이터를 메모리 내에서만으로는 취급할 수 없다.

3. 장애가 발생했을 때 빠른 복구가 어렵다.

4. 병렬성 제어가 어렵다.

5. 데이터 무결성을 보장하는 것이 어렵다.

 

인덱스(Index)

1. 전체 검색(Full Scan)은 대량의 데이터에 적합하지 않다.

2. 원하는 위치까지 순식간에 도달하는 방법 생각하기

 

방법 1

사용자 정보를 "고정 길이"로 관리하기

고정 길이 파일로 관리하면 ID에 대해서 파일 위치가 기계적으로 단순히 정해지기 때문에 바로 목표로 하는 데이터에 다다르게 된다. 그러나 불필요하게 소비되는 공간이 너무 많이 실용적이지 않다.

 

구체적인 문제점

1. 고정 길이 파일이 모든 사용자 정보를 담을 수 있다는 보장이 없다.

2. 새로운 데이터를 추가할 때 데이터가 고정 길이만큼인지 체크를 해줘야 한다.

3. 그렇다고 고정 길이를 처음부터 많이 할당하기엔 너무 비효율적이다.

 

구현 방법

1. HashMap을 사용하기

문제점

Key - Value 구조는 Key에 해당하는 Value를 O(1)에 반환할 수 있지만, 범위를 요구하는 쿼리

(e.g. 가격이 10000원 이하의 데이터 찾기, 제목이 "Final"로 시작하는 데이터 찾기, 시간 오름차순으로 정렬하기)

해결법

B+Tree를 사용하기

 

인덱스의 문제점

1. Search 성능을 올릴 수 있지만 Update가 일어날 경우 데이터와, 인덱스 자료구조 또한 변화해야 하고 업데이트 성능이 떨어짐

2. 데이터에 변경이 가해질 경우 B+Tree, 테이블 둘 다 변화해야 함. 모든 데이터는 추가될 때 특정한 Key값 기준으로 오름차순 순으로 데이터가 입력된다는 보장이 없음.

3. 이러한 케이스에는 인덱스의 리프 블록의 이곳저곳이 무작위에 가까운 형태로 업데이트되어 간다. 랜덤 액세스는 느리기 때문에 이 비용을 얼마나 감소시키느냐가 성능에 있어 중요하다.

 

MySQL의 해결법

1. 데이터베이스에서는 무 정지성을 높이기 위해 업데이트된 부분(블록)을 최대한 빨리 디스크에 저장해야 한다.

2. 업데이트된 정보를 메모리나 전용 파일 등에 일시적으로 기록하여 두고 나중에 모아서 단번에 리프 블록을 갱신하는 구조를 채택한다.

3. 이를 Random Write가 아닌 Sequential Write를 사용한다고 한다.

4. 병렬 갱신 성능을 높이기 위해서 B+Tree의 인덱스 리프 블록의 내용을 이동시키는 "리프 분할" 처리가 필요하다.

5. 리프 분할할 때, 즉 인덱스의 재편성 처리가 이루어질 때 MySQL은 참조 및 갱신 처리를 Lock을 통해 막는다.

6. 다른 방법으로 Partition Table을 사용하기도 한다. 사용자에게는 테이블이 1개로 보이지만 내부적으로 복수로 분할 관리되는 것으로, 인덱스도 복수로 구분하고 있기 때문에 병렬 갱신이 가능하다.

 

 

출처 및 참고문헌

데이터베이스를 지탱하는 기술
국내도서
저자 : 마쯔노부 요시노리 / 정인식역
출판 : 제이펍 2012.11.18
상세보기
profile

Zero to Hero

@Doljae

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!