How B+Tree Indexes Are Built In A Database? | by Christopher Tao | Towards Data Science

If you are not a DBA or a Database Developer, you may not know the mechanisms of the database index. But as long as you can write some SQL queries, you must have been heard of database indexes and know that indexes can improve the performance of the SQL queries.
In one of my previous articles, I have introduced the B+Tree index which is still used by most of the database management systems (DBMS). It can improve the SQL query performance on most types of conditions.
towardsdatascience.com
There is a diagram that I used as an example, which is shown as follows.
Are you curious why the B+Tree looks like this? Specifically, why the top-level has its only node with the number 5? Why the leaf-node 7 is alone? In this article, I’ll introduce how the B+Tree index is built from scratch.
Let’s start from an empty table, and ignore what other columns it has, just focusing on the key column having the B+Tree index created on.
Now, suppose we started to use this table. So, a series of entries will be inserted into the table. Because there is a B+Tree index on the key column, the index will need to be built as the data rows are inserted one by one.
Although usually the key field might be inserted in order, of course, that’s not always the case. To demonstrate the mechanism in a general case, let’s assume the keys are inserted randomly. For example, the order is as follows:
5, 7, 8, 1, 4, 6, 2, 3, 9
It needs to be emphasised that, there is not only one way to build a B+Tree index. Therefore, we need to have some assumptions in our example. Don’t worry, the mechanism of all B+Tree indexes is the same.
Assumption 1: Each block of the hard disk drive can be stored with two keys
Of course, in practice, this number is impossibly small. But it will make our example much easier to be understood.
OK. Now, we can insert the first two numbers into the index.
Because of Assumption 1, we don’t need to worry about anything when we insert two values. The values have to be sorted, so 5 is on the left whereas 7 is on the right. Please note that the node is a leaf node because we don’t need any non-leaf node at the moment as there are only two values that can be stored in one leaf node.
When we insert a new number “8”, we firstly assume that we need to insert it into the existing leaf node. However, it will end up with a node with three values “5, 7, 8”. Based on Assumption 1, we need to split the node because the block can only store two values.
Assumption 2: When a node is split, the right value of the left node goes to the higher level
We need to make Assumption 2 to define which value goes to the higher level whenever a node is split. Please note that it is also possible to have the assumption such as the left value of the right node goes up, and we just need to define that and follow.
Therefore, the last value “8” which cannot be stored in this block is split and become a new leaf node. After that, the left node is “5” and “7”, and the rightmost value is “7”, so it will go to the higher level.
Now, we have a non-leaf node. This new node needs to be created with two pointers on both of its left and right. The left pointer points to the node having values smaller, whereas the right pointer points to the larger.
Next, when we insert the number “1”, the leaf node “5, 7” becomes “1, 5, 7” which cause another split. The last value “7” will be separated and become a new leaf node. Please note that the number “7” will not be merged into the other node with the number “8”, this is because B+Tree doesn’t have this feature, as well as this will cause extra overhead to build the index. It is not necessary.
After that, based on Assumption 2, the rightmost value of the left node is the number “5”. It made its way to a higher level. There is already a node with the number “7”, so the number five will be simply inserted on the left of “7”. Don’t forget to make the pointer points to the node less or equal to “5”.
The next value is “4”. It caused a split again, so the number 4 went to the next level based on Assumption 2. However, the first-level non-leaf node “5, 7” has already got two values. Based on Assumption 1, it needs to be split.
It does no doubt that the number “5” should go up to the second-level non-leaf node based on Assumption 1. However, it is very important to know that the number 5 will not exist in the first-level non-leaf node anymore. This is one of the mechanisms of B+Tree, there should not be any duplicated values in non-leaf nodes.
Inserting the number “6” is relatively easy. Because the leaf node “5” still has a space, the number “6” will be inserted in this node without any other effects.
When the number “2” is inserted, the leaf node “1, 2, 4” needs to be split. Based on Assumption 2, the number “2” needs to be lifted. As the non-leaf node “4” still has space, so the number “2” end up there without further effects.
The last two numbers “3” and “9” can find their spots on the leaf nodes. Therefore, no more split is required.
So, all the 9 numbers are inserted into the B+Tree index with this random order.
In this article, I have used graphs to illustrate how a B+Tree is built from scratch. It turns out the assumptions can be different between the implementations of B+Tree indexes. However, the mechanisms are the same.
As the most classic type of index, B+Tree has been utilised for dozens of years and are still using by most of the DBMS. Although it might not be the most advanced index anymore, I believe it is still iconic and a DBA, Data Analyst and Software Developer should know.
medium.com
If you feel my articles are helpful, please consider joining Medium Membership to support me and thousands of other writers! (Click the link above)