![]() |
VOOZH | about |
Hashing in DBMS is a technique to quickly locate a data record in a database irrespective of the size of the database. For larger databases containing thousands and millions of records, the indexing data structure technique becomes very inefficient because searching a specific record through indexing will consume more time. This doesn't align with the goals of DBMS, especially when performance and data retrieval time are minimized. So, to counter this problem hashing technique is used. In this article, we will learn about various hashing techniques.
The hashing technique utilizes an auxiliary hash table to store the data records using a hash function. There are 3 key components in hashing:
A hash function is a mathematical algorithm that computes the index or the location where the current data record is to be stored in the hash table so that it can be accessed efficiently later. This hash function is the most crucial component that determines the speed of fetching data.
The hash function generates a hash index through the primary key of the data record.
Now, there are 2 possibilities:
Example:
There are four primary hashing techniques in DBMS.
In static hashing, the hash function always generates the same bucket's address. For example, if we have a data record for employee_id = 107, the hash function is mod-5 which is - H(x) % 5, where x = id. Then the operation will take place like this:
H(106) % 5 = 1.
This indicates that the data record should be placed or searched in the 1st bucket (or 1st hash index) in the hash table.
Example:
The primary key is used as the input to the hash function and the hash function generates the output as the hash index (bucket's address) which contains the address of the actual data record on the disk block.
To resolve this problem of bucket overflow, techniques such as - chaining and open addressing are used. Here's a brief info on both:
Chaining is a mechanism in which the hash table is implemented using an array of type nodes, where each bucket is of node type and can contain a long chain of linked lists to store the data records. So, even if a hash function generates the same value for any data record it can still be stored in a bucket by adding a new node.
h(key) = key % 5| Key | Hash Index (key % 5) | Inserted At |
|---|---|---|
| 10 | 0 | Bucket 0 → [10] |
| 15 | 0 | Bucket 0 → [10 → 15] |
| 20 | 0 | Bucket 0 → [10 → 15 → 20] |
| 25 | 0 | Bucket 0 → [10 → 15 → 20 → 25] |
| 30 | 0 | Bucket 0 → [10 → 15 → 20 → 25 → 30] |
| 11 | 1 | Bucket 1 → [11] |
| Index | Linked List (Bucket) |
|---|---|
| 0 | 10 → 15 → 20 → 25 → 30 |
| 1 | 11 |
| 2 | -- |
| 3 | -- |
| 4 | -- |
However, this will give rise to the problem bucket skew that is, if the hash function keeps generating the same value again and again then the hashing will become inefficient as the remaining data buckets will stay unoccupied or store minimal data.
This is also called closed hashing this aims to solve the problem of collision by looking out for the next empty slot available which can store data. It uses techniques like linear probing, quadratic probing, double hashing, etc.
h(key) = key % 7| Key | Hash (key % 7) | Insert At | Collision? | Final Position (after probing) |
|---|---|---|---|---|
| 50 | 50 % 7 = 1 | 1 | No | 1 |
| 700 | 700 % 7 = 0 | 0 | No | 0 |
| 76 | 76 % 7 = 6 | 6 | No | 6 |
| 85 | 85 % 7 = 1 | 1 | Yes | 2 (next slot) |
| 92 | 92 % 7 = 1 | 1 | Yes | 3 (after 1 and 2 are filled) |
| 73 | 73 % 7 = 3 | 3 | Yes | 4 (next slot after 3) |
| Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|---|
| Value | 700 | 50 | 85 | 92 | 73 | -- | 76 |
Dynamic hashing is also known as extendible hashing, used to handle database that frequently changes data sets. This method offers us a way to add and remove data buckets on demand dynamically. This way as the number of data records varies, the buckets will also grow and shrink in size periodically whenever a change is made.
Example: If global depth: k = 2, the keys will be mapped accordingly to the hash index. K bits starting from LSB will be taken to map a key to the buckets. That leaves us with the following 4 possibilities: 00, 11, 10, 01.
As we can see in the above image, the k bits from LSBs are taken in the hash index to map to their appropriate buckets through directory IDs. The hash indices point to the directories, and the k bits are taken from the directories' IDs and then mapped to the buckets. Each bucket holds the value corresponding to the IDs converted in binary.