B-Tree 인덱스는 데이터베이스에서 가장 널리 사용되는 인덱스 구조 중 하나로, 데이터를 정렬된 트리 구조로 관리하여 검색, 삽입, 삭제 등의 연산을 효율적으로 수행할 수 있게 합니다. 실제 데이터를 예로 들어 B-Tree 인덱스의 작동 방식을 설명해 보겠습니다.
### 예시 데이터
다음과 같은 고객 정보가 있는 테이블이 있다고 가정해보겠습니다:
|고객ID (CustomerID)|이름 (Name)|나이 (Age)|
|---|---|---|
|101|Alice|30|
|102|Bob|25|
|103|Charlie|35|
|104|Dave|28|
|105|Eve|40|
여기서 `CustomerID`를 기준으로 B-Tree 인덱스를 생성한다고 가정해보겠습니다.
### B-Tree 인덱스 구조
B-Tree 인덱스는 여러 레벨로 구성된 노드들로 이루어진 트리 구조를 가지며, 다음과 같은 특징을 가지고 있습니다:
1. **루트 노드**: 트리의 최상위 노드입니다.
2. **내부 노드**: 루트 노드와 리프 노드 사이에 위치한 노드들로, 자식 노드로의 경로를 나타냅니다.
3. **리프 노드**: 트리의 최하위 노드들로, 실제 데이터 레코드에 대한 포인터를 가지고 있습니다.
각 노드는 여러 키(Key) 값을 가지며, 각 키는 특정 범위를 나타내고 그 범위 내의 데이터를 자식 노드로 연결합니다.
### B-Tree 인덱스 생성 과정
1. **데이터 삽입**: 처음에 데이터가 삽입되면 B-Tree는 자동으로 정렬된 상태를 유지하며, 적절한 위치에 데이터를 삽입합니다.
예를 들어, 고객 ID가 101, 102, 103, 104, 105인 고객 데이터를 B-Tree 인덱스에 삽입하면, 트리는 다음과 같이 구성될 수 있습니다:
css
Copy code
`[102] / \ [101] [103, 104, 105]`
- 루트 노드 `[102]`는 기준이 되는 키를 가지고 있습니다.
- `[101]`은 102보다 작은 값들을 포함하는 자식 노드입니다.
- `[103, 104, 105]`는 102보다 큰 값들을 포함하는 자식 노드입니다.
2. **데이터 검색**: 특정 데이터를 검색할 때, B-Tree 인덱스는 루트 노드에서 시작하여 해당 데이터를 포함하는 리프 노드까지 경로를 따라갑니다.
예를 들어, `CustomerID = 104`를 검색할 때:
- 먼저 루트 노드 `[102]`를 확인합니다. 104는 102보다 크므로 오른쪽 자식 노드로 이동합니다.
- 오른쪽 자식 노드 `[103, 104, 105]`에서 104를 찾고, 해당 데이터에 대한 포인터를 가져옵니다.
3. **데이터 삽입 및 삭제**: 새로운 데이터가 삽입되거나 기존 데이터가 삭제될 때, B-Tree는 균형을 유지하면서 데이터를 삽입하거나 삭제합니다.
예를 들어, `CustomerID = 106`이 추가되면:
css
Copy code
`[102] / \ [101] [103, 104, 105, 106]`
만약 오른쪽 노드가 가득 차면, 노드가 분할되고 트리가 재구성됩니다.
### B-Tree 인덱스의 장점
1. **빠른 검색**: 데이터가 트리 구조로 정렬되어 있기 때문에, 검색 시간 복잡도가 `O(log n)`으로 매우 빠릅니다.
2. **균형 유지**: 삽입 및 삭제 시 트리가 자동으로 균형을 유지하므로, 모든 노드에서 루트까지의 경로 길이가 거의 동일하게 유지됩니다.
3. **효율적인 범위 검색**: B-Tree는 정렬된 구조를 가지므로, 특정 범위 내의 데이터를 효율적으로 검색할 수 있습니다.
### 예시 시나리오
예를 들어, `CustomerID`가 101에서 105 사이에 있는 고객 데이터를 검색하려고 할 때, B-Tree 인덱스를 사용하면 다음과 같은 절차를 따릅니다:
1. 루트 노드 `[102]`에서 검색을 시작합니다.
2. 왼쪽 자식 노드 `[101]`에서 101을 찾습니다.
3. 오른쪽 자식 노드 `[103, 104, 105]`에서 102~105의 데이터를 모두 검색합니다.
이렇게 B-Tree 인덱스는 데이터베이스에서 효율적인 검색, 삽입, 삭제를 지원하며, 특히 대규모 데이터셋에서 성능 향상에 매우 유용합니다.