Lezione 6-7
Dynamic Indexing with B-Index and B+-Index
Sources:
- Lecture
- Fundamentals of Database Systems - Chapter 17
Search Tree
Let’s consider a range of values:
1,3,5,7,9,10,11,13,15,15

If i consider a binary search tree (each node has at most two childrens) i have a tree that is built upon a threshold that is the same value of the root. If i consider the root value of this tree as (9). then i would get something like this:
9
5 13
3 7 10 15
1 11
This is an unbalanced tree. But this is not the only possible tree, i may change the root value to 3 and get something like this:
3
1 5
7
10
11
13
15
On the first tree, at most i may pay
B-Tree stands for Balanced Tree.
N-Ary Search Tree
It’s a generalization of the binary search tree. While in the binary search tree, each node as at most two childs. In the N-ary Search Tree, each node has N childs. For example, if N=4 it’s usually called Quad Tree.
To implement an N-Ary Search Tree, i need
1,3,5,7,9,10,11,13,15,15
For example, our root values will be (7,10,13). The tree would be like this:
(7,10,13)
/ | \ \
(1,3,5) (9) (11) (15)
- The children values in the node at the left of 7 must have a value
- The children values in node at the right of 7 and at left of 10 must have value of
- Thie children immediately at the right of the previous children would have values between
- The children at the far right of this node would have a value of
.
So i consider three thresholds.
In average, an N-ary search tree has a cost of
Balanced Tree and Balanced Index.
The problem of the N-ary search tree is that, with insertion we get overflows in the nodes and we need to reorganize the tree, even adding another level if needed.
To have this structure stable to insertion and deletion, we consider some free spaces in the nodes of the three, say for example atleast 50%. In this way, adding values will not immediatly create an overflow but the structure is somehow more “resilient” to changes.
B-Index are equivalent to B-Trees, they’re the same structure. The difference is that N is called the fan-out of the index. (See DST Lezione 4-5). Also, in a B-Index we have pages instead of nodes.
Balanced Tree:
A tree is balanced if all the leaves are at the same level.
This is the only constraint required. It doesn’t matter if two nodes doesn’t have the same number of childs.
On average, the costs to retrieve a page is
Definition of a B-Tree Node
Each node in the B-tree is of the form:
Warning
For this section you must do exercises and be able to solve them to pass the exam. Here will be just explained the theory with some examples.
Order of the tree
Let
Why B/2
By considering 1/2 we are leaving half pages empty to leave free space. This is desiderable to avoid degradation in performance when writing the page (insertion, update, deletion)
Let’s break down each part:
- First giving a general look, we see that the equation is a sum of two values which must be less than B/2.
because as we saw in the previous section, every node has a key. and pointer to a record. Also from definition we got that it got at most keys. because we have pointers to internal nodes at most.
Why
and not We defined a node as:
Note that we have more pointers than key, because we also need to consider the last Pointer
Property: The bigger
, the better the index This because the bigger is
, the shorter is the tree. The cost of finding a record in a B-Tree is
Calculating order of tree in an heap file, key is unique
How many pointers do i need to address each record? NT → Number of Tuples. My index must be a dense index.
How many pages do i need to address each index? →
Height of the tree
Calculating height of the tree in an heap file, key is unique
Size of the tree
This value is the sum of all the nodes from all the levels of the tree.
You cannot simple calculate this with series of powers
Because doing so would be considering that all the nodes have the maximum number of children. This is a very niche and rare case. Also, if you follow this approach you will be wrong in order of magnitudes, it’s not just a small error.
Advantages over static multi level index
As we saw the cost is h/2, so it’s a good situation. Let’s consider the advantage with respect to multi level indexes. In Balanced Trees, the main advantage comes from free space.
For example, say i have to insert a new value in the tree. Since i computed
To summarize, with Balanced Trees we are getting a tremendous speed up in searches and a very small overhead in writes. We get the best of both searching and writing, thanks to local reorganization of data.
Nota
Devi fare gli esercizi su questa parte
Balanced plus Trees Indexing
It’s a variation of the B-index, called
In a balanced tree, the average cost is h/2, we can be lucky or unlikely, the cost is not costant for all searches.
A
- All pointers to records are in the leaves
- The node of each leaf is different from the internal nodes: a pointer to the next (left to right) brother leaf is present in the node.
Definition of a B+ -Tree node

Internal node:
Order of the tree
- Internal node:
- Leaf node:
Where is the order of the leaves.
Height of the tree
First, let’s compute the number of leaves.
Then apply the logarithmic formula:
Size of the tree
Da integrare con il libro
(NL/order of internal nodes) = (NP_first level above the leaves)
In real life use cases, the number of leaves is a good approximation of the tree size.
Implication of the B+-Tree and comparison with a B-Tree
In a B+-Tree, the order is bigger, because internal nodes use much less space than the nodes in B-Tree. In fact, in a B-Tree internal nodes have also a pointer to records, while in B+-Tree nodes, only the leaves have these pointers.
In a B+-Tree, the cost to find a value is costant and is
Another thing to consider is that if you want to search consecutive values, the
In real life systems,
-Tree indexes are the most used
(FACT TO VERIFY)
Also, in real system they sometime break the constraint of all the leaves at the same level just to reduce the I/O operations. But always in a such of way the level of the tree is always three or four
Why not using hashing?
For finding values in consecutive values, the
Others Types of Indexes
Bitmap Indexes
The bitmap index is another popular data structure that facilitates querying on multiple keys. Bitmap indexing is used for relations that contain a large number of rows. It creates an index for one or more columns, and each value or value range in those columns is indexed
A bitmap index is built on one particular value of a particular field. For example, say i have a table of students and one of the fields is “Sex”, which can be usually Male or Female or Others.
Then i create an index based on the ‘M’ value of this field. I would have NT bits, whoose value are one if the correspondent row is a male student, otherwise it’s 0.
The index for every value of the fiels will be:
M: 10010011...NT
F: 01100010...NT
O: 00000000...NT
Cardinality of the bitmap:
After i have keys, i need another data structure whose record are ordered that points to data inside the table.
If i want to retrieve all males, what i should do is:
- Read the bit map to find the records which are males
- Do a full scan of the auxiliary file to get the pointer to the actual data in the table So the performance depends also con selectivity. for example, If half the students are males, it is not convenient because there is virtually no difference from a linear scan.
Extreme example: Bitmap of an unique key, like the matricola
With an unique key, i would get a cardinality of
Advantages
- Count operations are very convenient because i don’t need to read the data, i just count the
s. Alike operations that doesn’t require to access the auxiliary file structure and/or the actual data are convenient. - Composite query with logical operators: since these operations can be done at the bitmap level, i just load the bitmap and do complex operation to get only the pointers to the records that matches the condition.
Compression
Another advantage of these bitmaps is that data can be compressed. One very efficient way to do this is to use the Run Length compression, where it is stored the count of subsequent bits that repeats themselves.
- See more on Run Length Compression on Wikipedia
In the case of matricola, data is compressed in a very efficient way, the first row of the bitmap would be
. The second row would be and so on.
Disadvantages in updating
- Data in the same column of the bitmap is DEPENDENT from each other. So if i update a value like on tuple, then i must also update the values in the same column in the bitmap. At least 2 values must be updated with each update.
M: [1]0010011...NT
F: [0]1100010...NT
O: [0]0000000...NT
If for absurd, student sex of the first student goes for example from M to O, then i have to update both the M bitmap and the O bitmap.
- If i speed up writing operations with a GPU, it’s easy to get in a deadlock.
The General use case for bitmaps
- When cardinality is low and you have non unique fields.
- When you do mostly read operation and update is rare or done in batch. This is the case for example of data analytics, where you never update real time and just want to read.
Logical Indexes
Logical indexes are a special index where the index is composed of a key and the primary key of the data.
For example, in the case of students, if i want a logical index by region i would have:
Cost of searching:
Size of the index: Is calculated as
BFR of the index
Cost of retrieving a record: Suppose we have this situation: a logical index auxiliary file, which is sorted points to a field and his primary key. Then say i have another B+-Tree index by matricola. The cost would be calculated as:
- Linear scan of the logical index:
- Scan of the tree:
So the total cost would be
Advantages
- If data moves often in the physical layer, at the pages level, then i have to completely rebuilt the index. The logical index is unsensitive to this change in memory allocation changes. It doesn’t change
Function based indexes
The idea is to create an index such that the value that results from applying some function on a field or collection becomes the key of the index.
For example, say i have a table of students with birthday, but i want the age. I could create my own age function and using the result from
<f(k),p>
The query will exploit the function and i will get a pointer from the age using an existent value and field.
Advantages
- If i have a complex function that require 1 minute on a field, and i have say 1000 tuples. It would require me 1000 minute each times i want to do this operation. By using this index i would only need to do this one time. And in a reasonable way, rebuild the index periodically.
Inverted indexes
The idea is to have an index that goes from a value to a key. For example, say i have a list of documents, and each one contains a list of words. Say ISBN is the identifier of the documents
D1 -> w1,w2,w3...
D2 -> w7,w1,w4...
D3 -> w9,w2,w1...
What i could do is this: a pointer that for each words lists all the documents ISBNs that contains that word.
Some real life examples:
- Analytical Indexes in the books: at the end of the books there are a list of words/topics and the page in which they are are mentioned.
- A search engine: we search words and we get a list of websites that contains that word.
These use cases works too for some kind of structured data, for example in VAR CHAR of variable length field. If our student table has a field “Curriculum” and i want to look for students that have “Java” in their curriculum, using the “LIKE” operator the cost is huge. I have to linear scan the student table and then linear scan all the field looking for the word “Java”. What i could do instead is to build once an index.
Disadvantages
- With this approach, the problem is if i update the tables, then the index is outdated. Google or any search engine is a well known example of this.
A little note on BLOBs
There is no way to speed up Blob’s retrieval with indexes. Because from a database perspective, it’s just a block of bits that has no meaning. You either retrieve it fully or you don’t retrieve it. It’s not possible for example to search inside the BLOB.
Usually, the primary key of the table is associated to the BLOB.