B Tree & B+ Tree
2-3 Tree
- 이전 글에서 다뤘던 Binary Tree 와 Binary Search Tree 는 자식 노드를 최대 2개 밖에 갖지 못한다. 하지만 자식 노드를 3개 갖도록 한 Tree 가 2-3 tree 라고 부른다. 2-3 tree의 특징은 아래와 같다. 왜 2-3 tree 라고 부르냐면, degree (child node의 수)가 2 또는 3이기 때문이다. 즉, 최소 child 의 개수는 2개라는 의미이다. 2-3 Tree는 다음과 같은 특징을 갖는다.
- 하나의 노드는 최대 2개의 key (3개의 자식 노드)를 갖는다.
- 2-3 tree는 self-balancing tree 다.
- 모든 leaf node 는 같은 레벨을 갖는다.
- 모든 internal node는 항상 2개 이상의 자식 노드를 갖고 있어야 한다. 그렇지 않으면 자식 노드와 merge 가 되어 버린다.
- 2-4 이유 때문에 balance 가 깨지면 부모로부터 key 를 빌려오는 행위를 한다.
Insert
- 삽입은 다음과 같은 과정을 거친다.
- 기본적으로 leaf node 까지 간 후 삽입하면서 rebalancing 을 진행한다.
- 삽입을 할 때는 leaf node에서 부모로 타고 올라가는 방식을 취하는데, 이 방법을 상향식 이라고 한다.
- [분할이 발생하지 않는 경우] 노드의 키가 1개 밖에 없으면, 그냥 키를 추가한다.
- [분할이 발생하는 경우]) 노드의 키가 2개 있으면 (overflow), split 을 진행한다.
- split 을 하는 과정은 3개의 키 중 중간 키를 부모로 올리고 왼쪽 그 부모의 오른쪽 왼쪽 자식 노드로 만든다. 이 말은 즉, 부모가 없는 경우 새로운 부모를 만들거나, 부모가 있는 경우 그 노드에 하나의 key 를 추가하고 왼쪽 오른쪽 자식 노드로 만든다.
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
- Insert 70을 하는 경우 overflow 가 발생했기 때문에 중간값이 60을 부모로 올린다. 그리고 60의 child 는 50, 70이 된다.
- 부모를 올렸을 때, 60은 20, 40, 60 이렇게 또 overflow 가 된다. 위와 같은 방법으로 40이 부모가 되고, 20, 60이 left, right child 가 된다.
- 그 결과 아래와 같이 된다.
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Delete
- 삭제는 다음과 같은 과정을 거친다
- 삭제는 자식 노드의 key 값으로 대체하고, 자식 노드를 업데이트하는 방식으로 진행되기 때문에 하향식이라고 불린다.
- 삭제시키는 노드의 leaf node 인 경우
- 나 최소보다 큼: 그냥 지운다
- 나 최소보다 작고, 형제 최소보다 큼: 부모한테 빌리고, 형제는 부모에게 빌려준다.
- 나 최소보다 작고, 형제, 최소보다 작고, 부모 최소보다 큼: 부모가 빌려주고, 형제랑 merge 한다
- 나, 형제, 부모 모두 최소: 트리의 재구조화를 통한 높이 조절 발생. merge 한 후 internal node 삭제 로직으로 처리한다.
- 삭제시키는 노드가 internal node 인 경우
- 용어: 왼쪽 child 에서는 가장 큰 노드를 (inorder predecessor), 오른쪽 child 에서는 가장 작은 노드 (inorder successor)
- 나 최소보다 크거나, 내 자식이 최소보다 큼: 현재 노드의 inorder predecessor 또는 inorder success 를 가져와서 replace 함
- 나, 내 자식 모두 최소: 트리의 재구조화를 통한 높이 조절 발생. 자식들은 merge 를 진행. 키를 지우면 부모랑 형제를 merge 함. 자식 노드를 삭제된 키의 병합된 자식 노드로 설정. 이 때, 삭제된 키의 부모 노드의 개수에 따라 또 다르게 대응한다.
-
- 키의 부모와 형제가 병합되면서 overflow 가 발생하면 분할을 진행.
-
- 키의 부모가 최소 키의 개수가 안되는 경우가 발생하면 그 부모 (조부모) 를 따라가서 동일한 로직으로 부모와 형제를 병합시킴.
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
Delete 90을 하면 80을 내리고 (70, 80) 이 하나의 노드가 된다.
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
Delete 70을 하면, 60이 아래로 내려오고, 이 때, 60 자리는 다시 underflow가 됐기 때문에 부모로 부터 빌려온다. 이 때, 빌려온 부모가 Root 이고, 이 Root 가 비었으므로, (20, 40) 이 하나의 노드가 되고 최종 결과는 아래와 같이 된다.
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
위 시뮬레이션은 leaf node 만 해당되었는데, 사실 leaf node 보다 internal node를 처리하는게 로직이 더 복잡하다. 설명은 다음 링크에 잘 나와있으니까 까먹으면 매번 다시 업데이트를 하자. https://velog.io/@emplam27/자료구조-그림으로-알아보는-B-Tree
simulator:
https://people.ksp.sk/~kuko/gnarley-trees/23tree.html
B Tree
- B Tree는 2-3 tree의 확장된 Tree로 child node 의 개수가 M개 이다. 여기서 M을
degree
라고 부른다.
- B Tree의 장점에는 여러가지가 있는데, 먼저 Binary Search Tree의 height를 낮출 수 있다. Tree 의 height 를 낮춰야 하는 이유가 있을까? 매우 큰 크기의 데이터를 저장할 때 Disk 에 저장을 하는 경우가 있다. 따라서 노드의 크기를 Disk의 Block size 로 한 후 block 을 메모리에 로드해서 탐색을 한 후, 데이터를 찾지 못한 경우 다시 disk 에서 불러오도록 한다. height 가 disk access 횟수라고 했을 때, B Tree 구조는 disk access 횟수를 줄일 수 있는 자료구조이다.
- 또다른 장점으로는 데이터가 정렬된 상태로 저장되어있다는 것이다. 하나의 노드 (또는 블록)안에 저장된 데이터는 정렬된 상태로 저장하기 때문이다.
- B Tree 의 조건은 2-3 Tree 와 상당 부분 같다. 다만, 2개의 key, 3개의 child라는 조건이 M-1개의 key, M개의 child 라는 조건으로 변경되었다는 것 뿐이다.
- 여기서 underflow 와 overflow 조건이 중요해지는데, overflow 의 조건은 노드가 가질 수 있는 max key 개수인 M-1개가 꽉찰 경우 overflow 라고 판단한다.
- underflow 인 경우는 노드가 가지는 child 의 개수가 인 경우이다. 즉, 2-3 Tree의 경우 이기 때문에 최소로 가져야 하는 child의 개수는 이다. 따라서 child 의 개수가 2가 안되는 경우에는 child 와 merge 해버리는 상황이 발생한다.
B+ Tree
- B+ Tree 는 Database의 index를 구성할 때 많이 사용된다. B+ Tree가 B Tree 보다 가지는 이점은, leaf node에만 데이터가 저장되기 때문에 메모리 공간을 적게 사용한다는 것이다. 따라서 하나의 노드에 더 많은 키를 저장할 수 있다는 장점이 있다. 이게 무슨 말인가 하면, B Tree 에서는 노드에 데이터도 포함될 수 있지만, B+ Tree의 경우에는 노드에 데이터가 포함될 수 없다. 대신 B+ Tree는 block pointer를 갖고 있다 .
- 또한 Full scan 을 하는 경우 B Tree의 경우 모든 노드를 방문해야하는 반면, B+ Tree의 경우 linear 하게 leaf 노드들만 방문하면 되기 때문에 속도가 더 빠르다고 한다. leaf 노드들은 서로 Linked List로 연결되어 있기 때문에 Tree를 탐색할 필요없이 Linked List처럼 탐색할 수 있고, 이로 인해 Range Query 에서도 유용하게 쓰일 수 있다.
- B+ Tree의 단점이라고 하면, Worst case, Best case 모두 O(h) 라는 것이다. B Tree 의 경우 빠르면 O(1) 에도 찾을 수 있는 반면, B+ Tree는 데이터가 항상 leaf node 에 있기 때문에 항상 O(h)이다. 여기서 h는 height를 의미한다.
DB Index 와 B Tree & B+Tree
- Index 는 DB 의 Full Scan 을 방지하고 빠르고 적은 시스템 부하로 데이터를 찾을 수 있게 함. Index 의 장점은 데이터를 정렬해놓기 때문에 조건에 맞는 데이터를 빠르게 찾을 수 있음.
- DB 에 Index를 사용하면 좋은 경우와 좋지 않은 경우
- 좋은 경우
- 테이블의 규모가 큰 경우
- 컬럼에 insert, update, delete 가 자주 발생하지 않은 경우
- Where 나 order by, join 등이 자주 사용되는 컬럼
- 데이터의 중복도가 낮은 컬럼
- 나쁜 경우
- 컬럼에 insert, update, delete 가 자주 발생하는 경우
- 데이터의 10~15% 이상의 많은 양의 데이터를 처리하는 경우
- Range 가 적은 컬럼
- Index 를 구현하는 두 가지 방법
- Hash table
- best case 인 경우, 중간노드에서 데이터를 찾으면 검색 속도가 빠르다.
- 등호 연산 처리는 빠르지만, range query 에는 빠른 시간 내 처리가 어려움. 따라서 잘 사용하지 않음.
- 모든 데이터를 순회하는데 트리의 모든 노드를 방문해야하므로 비효율적 (재방문이 있음).
- B+ Tree
- B+는 오직 데이터를 leaf 노드에만 저장하고, leaf 노드는 linked list 로 연결되어 있기 때문에 range query 방식에 유리함.
- Leaf 노드말고 중간 노드에서는 데이터를 담아두지 않기 때문에 메모리를 더 확보해서 더 많은 key 를 저장할 수 있음. 이는 cache hit 을 높일 수 있다는 말임.