에듀테크 프로젝트 대시보드
B-Tree (다진 균형 탐색 트리)
이진 탐색 트리는 노드마다 자식이 2개뿐이라 데이터가 많아지면 깊이가 깊어진다. 디스크는 한 번 읽을 때 블록 단위(4KB, 16KB…)로 읽으므로, 노드 하나에 여러 개의 키를 욱여넣어 자식을 수십~수백 갈래로 늘리면 훨씬 얕은 트리로 같은 데이터를 담을 수 있다. 그게 B-Tree다. 실제 DB 인덱스, 파일시스템은 대부분 이 구조(정확히는 변형인 B+Tree)를 쓴다.
루트가 아닌 노드는 키를 t-1 ~ 2t-1개 갖는다. 너무 비지도, 너무 차지도 않게 유지.
내부 노드의 자식 수는 키 개수 + 1개. 키가 많을수록 자식(분기)도 많아진다.
모든 리프는 항상 같은 깊이에 있다 — 회전 없이도 트리가 저절로 완벽 균형을 이룬다.
노드가 꽉 차서(2t-1개) 하나 더 들어오면, 가운데 키를 부모로 올리고 둘로 쪼갠다.
💡 파란 굵은 테두리는 방금 분할이 일어난 노드, 초록 테두리는 탐색 경로다.
차수 t를 올리면(예: 4) 노드 하나가 키를 최대 7개까지 담아 분할이 훨씬 뜸하게 일어나고
트리가 더 얕아지는 것을 확인할 수 있다. 차수를 바꾸면 트리는 초기화된다.
분할 전 — 꽉 찬 노드(t=2, 최대 3키)
[ 10 | 20 | 30 ] ← 4번째 키 25 도착
분할 후 — 가운데 키가 부모로 승격, 나머지는 반씩
[ 20 ] ← 부모로 승격
/ \
[ 10 ] [ 25 | 30 ] ← 왼쪽 / 오른쪽 절반
분할은 자식 개수만 하나 늘릴 뿐 모든 리프의 깊이를 똑같이 유지한다. AVL 트리처럼 "기울어짐"을 측정해 회전하는 게 아니라, 노드가 넘치면 그 자리에서 즉시 쪼개는 것만으로 균형이 저절로 맞춰진다.
메모리에서는 된다. 하지만 데이터가 디스크에 있으면 얘기가 다르다.
노드 하나 읽는 데 디스크 접근 1번(수 ms)이 걸리는데, 이진 트리는 자식이 2개뿐이라
100만 개를 담으려면 깊이가 log₂ 1,000,000 ≈ 20단계나 된다.
B-Tree는 노드 하나에 수백 개의 키를 담아 자식을 수백 갈래로 늘려서, 같은 데이터를
3~4단계만에 도달하게 만든다. "느린 디스크 접근 횟수"를 최소화하는 게 핵심이다.
정확히는 B+Tree 변형을 쓴다. 차이는: (1) 실제 데이터는 리프에만 저장하고
내부 노드는 리프로 가는 이정표(키)만 들고 있다. (2) 모든 리프 노드끼리 연결 리스트로 연결돼 있어서,
범위 검색(WHERE age BETWEEN 20 AND 30)을 할 때 트리를 다시 안 타고 리프를 옆으로
쭉 훑을 수 있다. 이 데모의 B-Tree는 개념 이해용 원형이고, B+Tree는 여기서 한 걸음 더 나아간 실전형이다.
삽입의 반대 원리다. 노드의 키가 최소 개수(t-1개) 아래로 내려가려 하면,
이웃 형제한테서 키를 하나 빌려오거나(rotate), 그것도 안 되면 형제와 합쳐버린다(merge).
분할이 "위로 올라가며 쪼개는" 연산이라면, 병합은 "위에서 내려오며 합치는" 연산이라고 볼 수 있다.
이 데모는 개념을 보여주는 데 집중해 삽입·탐색만 지원한다.