Introduction

A static multilevel index from Indexing must be rebuilt as the file grows. B-trees and B+ trees are multilevel indexes that stay balanced under inserts and deletes: every leaf is at the same depth, and every node except the root is at least half full. One node is one disk block, so the number of levels (edge height plus 1) is the number of index block accesses for a search.

The standard calculations are the order of a node from the block, key and pointer sizes, the minimum and maximum number of keys or levels, and the tree after a sequence of insertions or deletions.

Prerequisites

Core concepts

Order. The order pp of a node is its maximum number of child pointers; a node then holds at most p−1p - 1 keys. This is the convention of Elmasri and Navathe (pp) and of Korth, Silberschatz and Sudarshan (nn). Other sources define order as the maximum number of keys, or use a minimum degree tt; read the question's definition before computing.

B-tree of order pp.

  • An internal node is ⟨P1,⟨K1,Pr1⟩,P2,…,⟨Kq−1,Prq−1⟩,Pq⟩\langle P_1, \langle K_1, \text{Pr}_1 \rangle, P_2, \ldots, \langle K_{q-1}, \text{Pr}_{q-1} \rangle, P_q \rangle with q≤pq \le p: tree pointers PiP_i, keys KiK_i in increasing order, and a data (record) pointer Pri\text{Pr}_i with every key.
  • Every key appears exactly once in the tree, in an internal node or a leaf.
  • Each non-root internal node has at least ⌈p/2⌉\lceil p/2\rceil children; every non-root B-tree node, including leaves, has at least ⌈p/2⌉−1\lceil p/2\rceil-1 keys; the root has at least 2 children unless it is the only node. All leaves are at the same level.

B+ tree of order pp (internal) and pleafp_{\text{leaf}} (leaf).

  • Internal nodes hold up to pp tree pointers and p−1p - 1 keys, with no data pointers; they only guide the search.
  • Leaves hold up to pleafp_{\text{leaf}} pairs ⟨Ki,Pri⟩\langle K_i, \text{Pr}_i \rangle and one next-leaf pointer, so the leaves form a sorted linked list.
  • Every key appears in a leaf; some keys are repeated in internal nodes as separators.
  • Each internal node except the root has at least ⌈p/2⌉\lceil p/2 \rceil children; each leaf (when the root is not a leaf) has at least ⌈pleaf/2⌉\lceil p_{\text{leaf}}/2 \rceil keys.
A B+ tree of order 4 holding fifteen keys: root 20, 30; internal nodes 10, 15 then 26 then 40; seven leaves 5 7, 10 13, 15 18, 20 22, 26 27, 30 35, 40 42 46 linked left to right; above it the layouts of an internal node and of a leaf node with its next-leaf pointer
Figure 1. Node layouts and a three-level B+ tree of order p=4p = 4 built by inserting 20, 40, 10, 30, 15, 35, 7, 26, 18, 22, 5, 42, 13, 46, 27.

How it works

Search. From the root, follow the pointer between the two keys that bracket the search key (in a B+ tree, go right on equality, since keys equal to a separator are stored in its right subtree). A B-tree search may stop at an internal node; a B+ tree search always reaches a leaf. Cost: one block per level, plus one data block.

Range search in a B+ tree: find the first key, then walk the leaf chain. A B-tree has no leaf chain and needs an in-order traversal.

Insertion into a B+ tree (the convention used in the traces and in the checks):

  1. Insert the key in its leaf in sorted order. If the leaf now has pleaf+1p_{\text{leaf}} + 1 keys, split it: the left leaf keeps the first ⌈(pleaf+1)/2⌉\lceil (p_{\text{leaf}}+1)/2 \rceil keys, the right leaf gets the rest, and the first key of the right leaf is copied into the parent.
  2. If an internal node now has pp keys (p+1p + 1 pointers), split it: the left node keeps the first ⌈(p+1)/2⌉\lceil (p+1)/2 \rceil pointers, the next key moves up (it is not kept below), and the right node gets the rest.
  3. A split of the root creates a new root with one key, so the tree grows at the top and all leaves stay at the same depth.

In a B-tree a full node splits around its median key, which moves up together with its data pointer; no key is copied. Some books put the extra key in the right half instead of the left; both give valid trees, so a problem that wants one exact tree must fix the rule.

Deletion removes the key from its leaf; if the leaf falls below the minimum it borrows from a sibling (redistribution) or merges with it, and the parent loses a separator, which can propagate up and shrink the root. One fixed rule is used, since books differ:

  1. A node that falls below its minimum looks at its left sibling under the same parent, or its right sibling if it is the leftmost child.
  2. If the two nodes fit in one node, merge them. Merging two leaves deletes the separator between them from the parent; merging two internal nodes pulls that separator down into the merged node.
  3. Otherwise borrow one entry. For leaves, move the nearest key across and set the parent's separator to the first key of the right leaf. For internal nodes, rotate: the parent's separator comes down into the short node, together with the nearest child pointer of the sibling, and the sibling's nearest key goes up to the parent.
  4. If the root is left with one child, that child becomes the root and the tree loses a level.

Mathematical explanation

Order from sizes. Block size BB, key VV, block (tree) pointer PP, record pointer PrP_r:

B-tree: p⋅P+(p−1)(V+Pr)≤B,B+ internal: p⋅P+(p−1)V≤B,B+ leaf: pleaf(V+Pr)+P≤B.\text{B-tree: } p \cdot P + (p - 1)(V + P_r) \le B, \qquad \text{B+ internal: } p \cdot P + (p-1) V \le B, \qquad \text{B+ leaf: } p_{\text{leaf}} (V + P_r) + P \le B.

Take the largest integer satisfying each. A B+ internal node has no record pointers, so its order is larger than the B-tree order for the same block: the larger internal fan-out can reduce the number of levels, but need not do so in every instance.

Height bounds for a B+ tree with NN keys and hh levels (the root is level 1, leaves are level hh, h≥2h \ge 2):

max keys=p h−1 pleaf,min keys=2⌈p2⌉h−2⌈pleaf2⌉.\text{max keys} = p^{\,h-1} \, p_{\text{leaf}}, \qquad \text{min keys} = 2 \left\lceil \tfrac{p}{2} \right\rceil^{h-2} \left\lceil \tfrac{p_{\text{leaf}}}{2} \right\rceil .

The minimum uses a root with 2 children, minimum fan-out below it, and minimum leaves. So NN keys need at least the smallest hh with ph−1pleaf≥Np^{h-1} p_{\text{leaf}} \ge N levels and at most the largest hh whose minimum does not exceed NN.

B-tree maximum. A B-tree of order pp and hh levels holds at most (p−1)(1+p+⋯+ph−1)=ph−1(p - 1)(1 + p + \cdots + p^{h-1}) = p^h - 1 keys.

B-tree minimum. Let k=⌈p/2⌉k = \lceil p/2 \rceil. The sparsest tree has a root with 1 key and 2 children, and every other internal node with kk children and k−1k-1 keys, and every leaf with k−1k-1 keys. Level i≥2i \ge 2 then has 2ki−22k^{i-2} nodes, so

min keys=1+2(k−1)(1+k+⋯+kh−2)=2k h−1−1.\text{min keys} = 1 + 2(k - 1)(1 + k + \cdots + k^{h-2}) = 2k^{\,h-1} - 1 .

Unlike the B+ minimum, every level contributes keys, because B-tree internal nodes hold keys of their own.

Worked examples

Example 1: orders. B=1024B = 1024, V=10V = 10, P=8P = 8, Pr=8P_r = 8.

  • B-tree: 8p+18(p−1)≤1024⇒26p≤1042⇒p=408p + 18(p - 1) \le 1024 \Rightarrow 26p \le 1042 \Rightarrow p = 40.
  • B+ internal: 8p+10(p−1)≤1024⇒18p≤1034⇒p=578p + 10(p - 1) \le 1024 \Rightarrow 18p \le 1034 \Rightarrow p = 57.
  • B+ leaf: 18pleaf+8≤1024⇒pleaf=5618 p_{\text{leaf}} + 8 \le 1024 \Rightarrow p_{\text{leaf}} = 56.

Example 2: levels for one million keys. With p=57p = 57, pleaf=56p_{\text{leaf}} = 56 and N=1000000N = 1000000:

  • Three levels hold at most 572⋅56=181944<N57^2 \cdot 56 = 181944 < N, so at least 4 levels.
  • Five levels need at least 2⋅293⋅28=1365784>N2 \cdot 29^3 \cdot 28 = 1365784 > N keys, so at most 4 levels.
  • The tree has exactly 4 levels however full its nodes are. Packed full it has ⌈106/56⌉=17858\lceil 10^6/56 \rceil = 17858 leaves, then 314314, 66 and 11 nodes above them. A search reads 4 index blocks and 1 data block.
  • A B-tree of order 40 with 3 levels holds at most 403−1=6399940^3 - 1 = 63999 keys; with 4 levels at most 404−1=255999940^4 - 1 = 2559999, so a B-tree of order 40 also needs at least 4 levels here.
  • The B-tree height is not fixed, though. With k=20k = 20 the minimum is 2⋅203−1=159992 \cdot 20^3 - 1 = 15999 keys for 4 levels, 2⋅204−1=3199992 \cdot 20^4 - 1 = 319999 for 5 and 2⋅205−1=63999992 \cdot 20^5 - 1 = 6399999 for 6. One million keys fit a sparse 5-level tree but not a 6-level one, so the B-tree has 4 or 5 levels depending on how full its nodes are.
  • For small numbers the same formulas give, for the B+ tree of Example 3 (p=4p = 4, pleaf=3p_{\text{leaf}} = 3) with 3 levels, between 2⋅2⋅2=82 \cdot 2 \cdot 2 = 8 and 42⋅3=484^2 \cdot 3 = 48 keys.

Example 3: inserting into a B+ tree of order 4 (p=4p = 4, pleaf=3p_{\text{leaf}} = 3: at most 3 keys per node). Insert 20, 40, 10, 30, 15, 35, 7, 26, 18, 22, 5:

  • 20, 40, 10 fill the root leaf (10,20,40)(10, 20, 40). Inserting 30 splits it into (10,20)(10, 20) and (30,40)(30, 40); 30 is copied up into a new root.
  • 15 and 35 fit. 7 splits (7,10,15,20)(7, 10, 15, 20) into (7,10)(7, 10) and (15,20)(15, 20); 15 goes up: root (15,30)(15, 30).
  • 26 fits in (15,20,26)(15, 20, 26); 18 splits it into (15,18)(15, 18) and (20,26)(20, 26), and 20 goes up: root (15,20,30)(15, 20, 30). 22 and 5 fit.

The tree is now root (15,20,30)(15, 20, 30) over leaves (5,7,10)(5, 7, 10), (15,18)(15, 18), (20,22,26)(20, 22, 26), (30,35,40)(30, 35, 40).

Example 4: a split that reaches the root (Figure 2). Insert 42 into that tree. The leaf (30,35,40,42)(30, 35, 40, 42) splits into (30,35)(30, 35) and (40,42)(40, 42) and copies 40 up. The root becomes (15,20,30,40)(15, 20, 30, 40), four keys, so it splits: (15,20)(15, 20) stays left, 30 moves up into a new root, (40)(40) goes right. The tree now has 3 levels: root (30)(30), internal nodes (15,20)(15, 20) and (40)(40), leaves (5,7,10)(5, 7, 10), (15,18)(15, 18), (20,22,26)(20, 22, 26), (30,35)(30, 35), (40,42)(40, 42).

Before: root 15, 20, 30 over leaves 5 7 10, 15 18, 20 22 26, 30 35 40. After inserting 42: root 30; internal nodes 15, 20 and 40; leaves 5 7 10, 15 18, 20 22 26, 30 35, 40 42
Figure 2. Inserting 42 splits a leaf, copies 40 up, then splits the root and moves 30 up, so the B+ tree grows from 2 to 3 levels.

Continuing with 13, 46 and 27 gives the tree of Figure 1: 13 splits (5,7,10,13)(5, 7, 10, 13) and copies 10 up; 46 fits; 27 splits (20,22,26,27)(20, 22, 26, 27), copies 26 up, and the internal node (10,15,20,26)(10, 15, 20, 26) splits with 20 moving up to the root.

Example 5: B-tree insertion. B-tree of order 5 (at most 4 keys per node), inserting 10, 20, ..., 90 in order:

  • 10 to 40 fill the root (10,20,30,40)(10, 20, 30, 40). 50 makes 5 keys; the median 30 moves up: root (30)(30) over (10,20)(10, 20) and (40,50)(40, 50).
  • 60 and 70 fill (40,50,60,70)(40, 50, 60, 70); 80 overflows it, and its median 60 moves up: root (30,60)(30, 60) over (10,20)(10, 20), (40,50)(40, 50), (70,80)(70, 80).
  • 90 fits: the final tree is root (30,60)(30, 60) over (10,20)(10, 20), (40,50)(40, 50), (70,80,90)(70, 80, 90), after 2 splits.

Unlike a B+ tree, 30 and 60 are stored only in the root; no leaf repeats them. Here the sorted input leaves every node except the rightmost at the minimum of ⌈5/2⌉−1=2\lceil 5/2 \rceil - 1 = 2 keys.

Example 6: B+ deletion with the rule above. Start from the tree of Figure 1 (order 4: leaves need at least 2 keys, internal nodes at least 2 children). Delete 30, then 22, then 42.

  1. Delete 30. Leaf (30,35)(30, 35) becomes (35)(35), too small. It is the leftmost child of (40)(40), so its sibling is (40,42,46)(40, 42, 46); together they have 4 keys, too many to merge, so it borrows 40: leaves (35,40)(35, 40) and (42,46)(42, 46), and the parent's separator becomes 42. The root still holds 30, a key no longer in the tree. That is allowed: a separator only has to route searches correctly, and every key below 30 is still on its left.
  2. Delete 22. Leaf (20,22)(20, 22) becomes (20)(20); it merges with its right sibling (26,27)(26, 27) into (20,26,27)(20, 26, 27), and the parent (26)(26) loses its only separator, leaving one child. That internal node merges with its left sibling (10,15)(10, 15), pulling the root separator 20 down: internal node (10,15,20)(10, 15, 20) with 4 children. Root: (30)(30) over (10,15,20)(10, 15, 20) and (42)(42).
  3. Delete 42. Leaf (42,46)(42, 46) becomes (46)(46) and merges with its left sibling into (35,40,46)(35, 40, 46); the parent (42)(42) is left with one child. Its left sibling (10,15,20)(10, 15, 20) has 4 children, too many to merge, so it borrows by rotation: 30 comes down from the root, the child (20,26,27)(20, 26, 27) moves across, and 20 goes up. Result: root (20)(20); internal nodes (10,15)(10, 15) and (30)(30); leaves (5,7)(5, 7), (10,13)(10, 13), (15,18)(15, 18), (20,26,27)(20, 26, 27), (35,40,46)(35, 40, 46).

The tree keeps 3 levels throughout. The sibling rule matters: with the right sibling tried first, step 2 merges the short internal node with (42)(42) instead, pulling 30 down, and gives root (20)(20) over (10,15)(10, 15) and (30,42)(30, 42), a different valid tree. (After step 3 the two rules happen to meet again.) A question that wants one exact tree must state the rule.

Important properties and observations

  • One node is one block, so levels equal index block accesses; edge height is levels minus 1.
  • B+ trees have larger fan-out than B-trees for the same block, because internal nodes carry no record pointers.
  • Leaf split copies the separator up; internal split moves it up.
  • All leaves are at one level; the tree grows and shrinks only at the root.
  • Nodes are at least half full (except the root), which bounds the height by about log⁡⌈p/2⌉N\log_{\lceil p/2 \rceil} N.
  • Range queries use the B+ leaf chain.

Common misconceptions.

  • "Order means maximum keys." Under the pointer convention of Korth and Elmasri, order is maximum pointers; check the question.
  • "A B+ tree stores data pointers in internal nodes." Only leaves have record pointers.
  • "Every insert grows the height." Only a split that reaches the root does.

GATE examination perspective

  • Order calculations. Apply this to B-tree, B+ internal and B+ leaf nodes.
  • Minimum and maximum keys or nodes. Apply this to a given height, and the height range for NN keys.
  • Insertion sequences. The final root, number of splits, or number of nodes.
  • B-tree versus B+ tree. Where keys and data pointers live, and the leaf chain.
  • Block accesses. Apply this to a search: levels plus one data block.

Summary

Sources

  1. A. Silberschatz, H. F. Korth, S. Sudarshan, Database System Concepts, 7th ed., McGraw-Hill, 2019 (2020 copyright), 14.3 B+-Tree Index Files, 14.4 B+-Tree Extensions.
  2. R. Elmasri, S. B. Navathe, Fundamentals of Database Systems, 7th ed., Pearson, 17.3 Dynamic Multilevel Indexes Using B-Trees and B+-Trees.

Next steps