1. B+Tree 소개
1.1 B+Tree의 정의
- B+Tree는 B-Tree의 변형으로, 데이터베이스와 파일 시스템에서 가장 널리 사용되는 인덱싱 자료구조입니다.
- 모든 데이터를 리프 노드에 저장하고, 내부 노드는 인덱스 역할만 수행하는 구조입니다.
- 리프 노드들은 연결 리스트로 연결되어 순차적 접근이 용이합니다.
1.2 B+Tree vs B-Tree
주요 차이점
B+Tree는 B-Tree를 개선하여 데이터베이스 시스템에 더 적합하도록 설계되었습니다.
- 데이터 저장 위치
- B-Tree: 모든 노드가 데이터를 저장할 수 있음
- B+Tree: 오직 리프 노드만 데이터를 저장
- 키 중복
- B-Tree: 키가 중복되지 않음
- B+Tree: 내부 노드의 키가 리프 노드에 중복되어 나타남
- 리프 노드 연결
- B-Tree: 리프 노드 간 연결 없음
- B+Tree: 리프 노드가 연결 리스트로 연결됨
2. B+Tree의 구조
2.1 노드 구성
- 내부 노드(Internal Node)
- 키(Key): 자식 노드로의 분기를 위한 인덱스 값
- 포인터(Pointer): 자식 노드를 가리키는 참조
- 리프 노드(Leaf Node)
- 키(Key): 실제 데이터 레코드의 키 값
- 데이터(Data): 실제 데이터 또는 데이터에 대한 참조
- 다음 리프 노드 포인터: 순차적 접근을 위한 링크
2.2 구조적 특징
2.2.1 차수(Order)에 따른 제약
- n차 B+Tree의 경우:
- 내부 노드
- 최대 n개의 자식을 가질 수 있음
- 최소 ⌈n/2⌉개의 자식을 가져야 함
- 키의 수는 자식 수보다 1개 적음
- 리프 노드
- 최대 n-1개의 키를 가질 수 있음
- 최소 ⌈(n-1)/2⌉개의 키를 가져야 함
- 내부 노드
2.2.2 정렬과 링크
- 모든 키는 정렬된 상태로 유지
- 리프 노드는 순차적 접근을 위해 양방향 또는 단방향으로 연결
- 모든 리프 노드는 같은 레벨에 위치
3. B+Tree 연산
3.1 검색(Search) 연산
3.1.1 단일 키 검색
def search(root, key):
current = root
# 리프 노드까지 이동
while not current.is_leaf:
i = 0
while i < len(current.keys) and key >= current.keys[i]:
i += 1
current = current.children[i]
# 리프 노드에서 키 검색
for i, k in enumerate(current.keys):
if k == key:
return current.data[i]
return None
3.1.2 범위 검색
def range_search(root, start_key, end_key):
result = []
# 시작 리프 노드 찾기
current = find_leaf(root, start_key)
# 범위 내의 모든 키 수집
while current:
for i, key in enumerate(current.keys):
if start_key <= key <= end_key:
result.append(current.data[i])
elif key > end_key:
return result
current = current.next_leaf
return result