1. B-Tree 소개
1.1 B-Tree의 정의와 역사
- B-Tree는 1972년 루돌프 바이어(Rudolf Bayer)와 에드워드 맥크레이트(Edward M. McCreight)가 개발한 자료구조입니다.
- 대용량 데이터의 효율적인 처리를 위해 설계되었으며, 현대 데이터베이스 시스템의 근간이 되는 자료구조입니다.
- 'B'의 정확한 의미는 명시되지 않았지만, Balanced(균형), Boeing(개발 당시 근무처), Bayer(개발자) 등으로 추측됩니다.
1.2 B-Tree의 특징
- 자가 균형(Self-balancing) 트리 구조입니다.
- 모든 리프 노드가 같은 레벨에 위치하여 검색 성능이 일관적입니다.
- 하나의 노드가 여러 개의 키와 자식을 가질 수 있습니다.
- 이진 트리와 달리 차수(degree)가 2보다 큰 트리입니다.
- 디스크 기반 자료구조에 최적화되어 있습니다.
- 노드 크기를 디스크 블록 크기에 맞춰 I/O 효율성을 극대화합니다.
2. B-Tree의 구조와 규칙
2.1 B-Tree의 기본 구성 요소
- 노드(Node): B-Tree의 기본 구성 단위
- 키(Key): 노드 내에 정렬된 상태로 저장되는 데이터
- 포인터(Pointer): 자식 노드를 가리키는 참조값
- 노드의 종류
- 루트 노드(Root Node): 트리의 최상위 노드
- 내부 노드(Internal Node): 루트와 리프 사이의 노드
- 리프 노드(Leaf Node): 자식이 없는 말단 노드
2.2 B-Tree의 핵심 규칙
차수(order)의 이해
B-Tree의 차수 n은 노드가 가질 수 있는 최대 자식 수를 의미합니다. 이를 기준으로 다음 규칙들이 정해집니다.
- 노드의 키 개수 규칙:
- 최소 키 개수: ⌈n/2⌉ - 1 (루트 노드 제외)
- 최대 키 개수: n - 1
- 노드의 자식 개수 규칙:
- 최소 자식 개수: ⌈n/2⌉ (루트 노드와 리프 노드 제외)
- 최대 자식 개수: n
- 키와 자식 수의 관계:
- 자식 수 = 키의 수 + 1
- 정렬 규칙:
- 노드 내의 키들은 오름차순으로 정렬
- 각 키의 왼쪽 서브트리의 모든 키 < 현재 키 < 오른쪽 서브트리의 모든 키
2.3 실제 예시: 3차 B-Tree의 제약 조건
3차 B-Tree 특성
3차 B-Tree는 가장 단순한 형태의 B-Tree로, 학습과 이해에 좋은 예시입니다.
- 최대 자식 수: 3개
- 최대 키 수: 2개
- 최소 자식 수: 2개
- 최소 키 수: 1개
- 가능한 노드 구성:
- [K1] : 키가 1개인 경우
- [K1|K2] : 키가 2개인 경우
3. B-Tree의 연산
3.1 검색(Search) 연산
- 검색 과정은 루트에서 시작하여 리프까지 진행됩니다:
- 현재 노드에서 검색 키와 노드 내 키들을 비교
- 적절한 자식 노드로 이동
- 키를 찾거나 리프에 도달할 때까지 반복
def search(root, key):
current = root
while current:
i = 0
# 현재 노드에서 키 찾기
while i < len(current.keys) and key > current.keys[i]:
i += 1
if i < len(current.keys) and key == current.keys[i]:
return (current, i) # 키를 찾음
if current.is_leaf:
return None # 키가 없음
current = current.children[i] # 다음 노드로 이동
3.2 삽입(Insertion) 연산
- 삽입은 항상 리프 노드에서 이루어집니다.
- 삽입 과정의 주요 단계:
- 삽입할 위치 검색
- 리프 노드에 키 삽입
- 필요시 노드 분할
3.2.1 노드 분할(Split) 과정
분할 시 주의사항
노드 분할은 상향식(bottom-up)으로 이루어지며, 트리의 높이가 증가할 수 있습니다.
- 중간 키(median) 선정
- 중간 키를 부모 노드로 이동
- 나머지 키들을 두 노드로 분배
- 필요시 부모 노드도 분할
3.3 삭제(Deletion) 연산
- 삭제는 크게 두 가지 경우로 나뉩니다:
- 리프 노드에서의 삭제
- 내부 노드에서의 삭제
3.3.1 리프 노드 삭제
- 키 제거 후 노드가 최소 키 개수를 만족하면 종료
- 불만족시 다음 단계 진행:
- 형제 노드에서 키 빌리기(재분배)
- 형제 노드와 병합(merge)
3.3.2 내부 노드 삭제
- 선행자(predecessor) 또는 후행자(successor) 찾기
- 해당 키와 위치 교환
- 리프 노드에서 삭제 수행
4. B-Tree의 활용
4.1 데이터베이스 시스템
- 인덱싱(Indexing)
- 테이블의 컬럼에 대한 빠른 검색 지원
- 범위 검색(Range Query) 효율적 처리
- 파일 시스템
- 디렉토리 구조 관리
- 파일 접근 효율성 향상
4.2 성능 특성
- 시간 복잡도
- 검색: O(log n)
- 삽입: O(log n)
- 삭제: O(log n)
- 공간 효율성
- 노드 활용도: 최소 50%
- 균형 유지로 일관된 성능 보장
5. B-Tree의 확장
5.1 B+Tree
- B-Tree의 변형으로, 모든 데이터를 리프 노드에 저장
- 리프 노드들을 연결 리스트로 구성
- 범위 검색에 더욱 효율적
5.2 B*Tree
- 노드 분할을 최소화하기 위해 2/3 이상 채워지도록 설계
- 형제 노드와의 재분배를 우선적으로 시도
- 공간 활용도가 더 높음
6. 실제 구현 시 고려사항
6.1 디스크 I/O 최적화
- 노드 크기를 디스크 블록 크기에 맞춤
- 캐시 활용으로 빈번한 I/O 감소
- 순차적 접근 패턴 고려
6.2 동시성 제어
- 락(Lock) 관리
- 트랜잭션 처리
- 복구(Recovery) 방안
7. 결론
- B-Tree는 대용량 데이터 처리에 최적화된 자료구조입니다.
- 균형 잡힌 구조와 효율적인 연산으로 데이터베이스 시스템의 핵심 요소입니다.
- 다양한 확장과 최적화를 통해 현대 컴퓨팅의 근간을 이루고 있습니다.