CS지식/데이터베이스 (Database)

(데이터베이스) B-Tree : 구조, 작동 원리, DB에서의 활용

불광동 물주먹 2025. 5. 31. 02:09

 B-Tree : 구조, 작동 원리, DB에서의 활용

1. B-Tree란?

B-Tree는 **Binary Search Tree(이진 탐색 트리)**를 일반화한 트리 자료구조입니다. 데이터베이스와 파일 시스템 등, 디스크 기반의 저장 시스템에서 대량의 데이터를 효율적으로 검색, 삽입, 삭제할 수 있도록 설계된 구조입니다.

왜 B-Tree가 필요한가?

  • 일반 이진 탐색 트리는 삽입 순서에 따라 한쪽으로 치우칠 수 있어 최악의 경우 O(n) 시간복잡도를 가집니다.
  • 반면 B-Tree는 항상 균형을 유지하며, 트리의 높이를 제한해 모든 연산이 O(log n) 시간에 수행됩니다.
  • 특히 디스크 I/O 비용이 큰 환경에서 적은 횟수의 블록 접근으로 원하는 데이터를 찾을 수 있도록 설계되었습니다.

2. B-Tree의 구조

기본 구성

  • M차 B-Tree: 하나의 노드가 최대 M개의 자식 노드를 가질 수 있는 트리
  • 각 노드는 최대 M-1개의 key를 가짐 (key는 오름차순으로 정렬)
  • 자식 노드 수는 항상 key 수 + 1
  • 루트 노드를 제외한 모든 노드는 최소 ⌈M/2⌉개의 자식을 가져야 함

내부(internal) 노드 vs 리프(leaf) 노드

  • 내부 노드: key와 자식 포인터 모두 가짐
  • 리프 노드: key만 가지고 자식 포인터는 없음
  • 모든 리프 노드는 같은 깊이에 위치하여 균형 트리를 유지함

Key와 자식의 관계

만약 어떤 노드가 key [K1, K2, K3]를 가진다면 자식 포인터는 [C0, C1, C2, C3]이며:

  • C0: key < K1
  • C1: K1 ≤ key < K2
  • C2: K2 ≤ key < K3
  • C3: K3 ≤ key

3. B-Tree 삽입 동작 (Insertion)

삽입 원칙

  1. 항상 리프 노드에 삽입
  2. 노드가 key 수 제한(M-1)을 넘으면 분할(split) 수행
  3. 가운데 key를 부모로 올려 보내고 승격(promote)
  4. 필요한 경우 재귀적으로 루트까지 분할

삽입 과정 예시 (3차 B-Tree)

삽입 순서: 10 → 20 → 5 → 6 → 12 → 30 → 7

1. 삽입 10      → [10]
2. 삽입 20      → [10, 20]
3. 삽입 5       → [5, 10, 20] → overflow
4. 분할         → 10 승격 → 루트 [10]
                   /      \
               [5]        [20]
5. 삽입 6       → [5,6], [20]
6. 삽입 12      → [5,6], [12, 20]
7. 삽입 30      → [5,6], [12, 20, 30] → overflow
   → 20 승격    → 루트 [10, 20]
                   /   |     \
              [5,6] [12]   [30]

 

아래 3차 Btree 

 

사진 출처 - 유튜브 쉬운코드

 

아래 링크 Btree 삽입에 대한 예제를 아주 쉽고 자세히 다뤄주신 영상이 있어 링크를 걸어 뒀습니다.

영상 보시면 도움 많이 되실거라 확신합니다.

 

https://youtu.be/bqkcoSm_rCs?si=sW3-FFLHkS0btmpY

 

*출처 유튜브 쉬운코드


4. B-Tree 삭제 동작 (Deletion)

리프 노드 삭제

  1. 항상 리프에서 삭제
  2. 삭제 후 최소 key 수 미만이면 재조정 필요

재조정 방식

  • 형제 노드에서 차용 (Redistribute)
    → 부모 키 하나 내려주고, 형제의 키 하나 올림
  • 형제 노드와 병합 (Merge)
    → 형제 + 부모의 key와 병합 → 하나의 노드로 합쳐짐
    → 부모 노드도 key 수 감소 → 재귀적 조정

Internal 노드 삭제

  • Internal 노드의 key는 바로 삭제할 수 없음
  • 반드시 leaf 노드로 위치를 바꾼 후 삭제

방법

  • 삭제할 key의 전임자(predecessor) 또는 **후임자(successor)**를 찾아 위치를 교환
  • leaf에서 삭제한 후 필요 시 재조정

 

아래는 Btree 삭제 예제 영상입니다.

https://youtu.be/H_u28u0usjA?si=fout_w1jeiT3OavS

 

*출처 유튜브 - 쉬운코드

 


5. B-Tree의 성능


연산 시간복잡도
탐색 O(log N)
삽입 O(log N)
삭제 O(log N)
 

→ 왜? 트리의 높이가 log N 수준으로 유지되기 때문
→ 디스크 기반 환경에서는 한 노드 = 한 디스크 블록 → I/O 횟수 최소화


6. 데이터베이스에서 B-Tree가 중요한 이유

디스크 친화적 구조

  • B-Tree의 노드는 보통 하나의 디스크 페이지에 맞도록 구성됨
  • 트리 높이를 낮게 유지하므로 **디스크 접근 횟수(I/O)**가 적음

정렬된 Key 유지

  • 키가 항상 오름차순으로 유지되므로, **범위 검색(RANGE SCAN)**이 매우 효율적
  • 예:
SELECT * FROM users WHERE age BETWEEN 20 AND 30;

CRUD 연산의 성능 보장

  • 대용량 테이블에서도 검색, 삽입, 삭제 모두 안정적으로 빠름
  • 트랜잭션이 많은 OLTP 환경에 최적

7. B-Tree vs B+Tree

항목 B-Tree B+Tree
키 저장 위치 Internal 노드 + Leaf 노드 Leaf 노드에만 저장
범위 검색 성능 Internal → Leaf 순회 필요 Leaf 노드 간 연결 리스트로 빠르게 순차 탐색
데이터 저장 위치 노드마다 저장 가능 Leaf 노드에만 실제 데이터 저장
대부분의 DB에서 사용 ❌ 일부 옛날 DB ✅ 대부분의 RDBMS 인덱스 구조
 

✅ B+트리를 많이 쓰는 이유 (요약)

 

이유 설명
1. 범위 조회에 최적화 리프 노드가 순차 연결되어 있어 BETWEEN, ORDER BY, LIKE 등에서 효율적
2. 구조가 단순함 모든 데이터가 리프 노드에만 있어 삽입/삭제 로직이 일관되고 단순
3. 디스크 I/O 최적화 내부 노드는 인덱스 역할만 하므로 한 블록에 더 많은 키를 저장 → 높이 작고 빠름

 

8. 결론 및 요약

  • B-Tree는 대용량 데이터 환경에서 빠른 검색과 수정을 지원하는 균형 트리 구조
  • 모든 노드는 자식 수 제한을 지키면서 트리 전체 균형을 유지
  • 삽입과 삭제 시 재조정 로직이 복잡하지만 그 덕분에 트리 높이가 낮게 유지
  • 디스크 기반 시스템, 특히 RDBMS의 인덱스 구현에 기초가 되는 자료구조
  • 실제 RDBMS는 대부분 B-Tree를 변형한 B+Tree를 사용함

 

추후엔 B+Tree에 대해 다뤄보겠습니다.