Skip to main content
Knowledge Hub

Database Fundamentals

Understanding storage engines, indexing, transactions, and query optimization

Last updated: December 5, 2025

Databases are fundamental to most backend applications. Understanding how they work internally helps you use them effectively, design better schemas, and optimize performance.

This article explores storage engines, indexing strategies, transactions, query optimization, and how databases handle data at scale.

How Storage Engines Work

Storage engines are the components responsible for storing and retrieving data. Different engines use different data structures and algorithms, each with trade-offs.

B-tree based engines organize data in balanced tree structures, providing good performance for both reads and writes. They maintain sorted order, making range queries efficient.

LSM-tree based engines use log-structured merge trees, which batch writes and merge them periodically. This provides excellent write performance but can have slower reads.

Write-ahead logging ensures durability by writing changes to a log before applying them to the main data structures. This allows recovery after crashes.

Understanding your database’s storage engine helps you make informed decisions about schema design, indexing, and performance tuning.

B-Trees Internals

B-trees are self-balancing tree data structures that maintain sorted data and allow efficient insertion, deletion, and search operations.

Each node contains multiple keys and pointers. Keys are sorted, and pointers lead to child nodes or data. The tree remains balanced, ensuring all operations are logarithmic in time complexity.

B-Tree Structure:
                    [50]
                   /    \
            [20, 30]    [70, 80]
            /  |  \      /  |  \
        [10] [25] [40] [60] [75] [90]

B-trees are optimized for disk access. Nodes are sized to match disk pages, minimizing I/O operations. This makes them efficient for databases that store data on disk.

Range queries are efficient because data is stored in sorted order. Traversing the tree to find the start of a range, then following pointers, retrieves all matching records efficiently.

B-Tree Operations

Search: Start at root, compare key, follow appropriate pointer

  • Time complexity: O(log n)
  • Disk I/O: O(log n) page reads

Insert: Find position, insert key, split node if full

  • Maintains balance automatically
  • Worst case: O(log n) disk writes

Range Query: Find start key, traverse in-order

  • Efficient for sequential access
  • Better than hash indexes for ranges

LSM Tree Internals

Log-Structured Merge trees are designed for write-heavy workloads. They batch writes in memory, then flush them to disk as sorted files.

LSM Tree Structure:

Memory (MemTable)
    ↓ (flush when full)
Disk Level 0: [File1] [File2] [File3]
    ↓ (merge)
Disk Level 1: [File4] [File5]
    ↓ (merge)
Disk Level 2: [File6]

When reads occur, the system checks in-memory data first, then searches through on-disk files from newest to oldest. This can require checking multiple files, but write performance is excellent.

Periodic compaction merges files, removing duplicates and deleted records. This maintains read performance as the database grows.

LSM trees trade read performance for write performance, making them suitable for applications with many writes and fewer reads, or where writes need to be fast.

LSM Tree Operations

Write: Append to in-memory MemTable

  • Very fast: O(1) in memory
  • Periodic flush to disk as sorted file

Read: Check MemTable, then Level 0, Level 1, etc.

  • May need to check multiple levels
  • Bloom filters can reduce unnecessary reads

Compaction: Merge sorted files, remove duplicates

  • Maintains read performance
  • Reduces storage space

Write-Ahead Logging and Durability

Write-ahead logging ensures data durability by writing changes to a log file before applying them to the main data structures.

When a transaction commits, its changes are written to the WAL. Even if the system crashes before changes are applied to main storage, the log can replay changes during recovery.

fsync operations force the operating system to write buffered data to disk. This ensures durability but adds latency. The frequency of fsync operations is a trade-off between performance and durability guarantees.

Different durability levels are available: some databases allow you to configure how often fsync occurs, balancing performance and safety based on your application’s requirements.

Indexing Strategies

Indexes are data structures that speed up queries by providing fast lookup paths to data. Choosing the right indexes is crucial for performance.

Single-column indexes speed up queries that filter or sort by that column. Composite indexes support queries that filter or sort by multiple columns. The order of columns in composite indexes matters.

Unique indexes enforce uniqueness constraints and can speed up lookups. Partial indexes include only a subset of rows, reducing index size for selective queries.

Covering indexes include all columns needed for a query, allowing the database to answer queries from the index without accessing the main table.

Too many indexes slow down writes because each write must update multiple indexes. Understanding query patterns helps you create the right indexes without over-indexing.

Transactions and Isolation Levels

Transactions group multiple operations into atomic units. They provide ACID properties: atomicity, consistency, isolation, and durability.

Isolation levels control how transactions interact with each other. Read uncommitted allows dirty reads. Read committed prevents dirty reads but allows non-repeatable reads. Repeatable read prevents non-repeatable reads but may allow phantom reads. Serializable prevents all anomalies but can reduce concurrency.

Understanding isolation levels helps you choose the right balance between consistency and performance for your application.

Query Planners and Optimizers

Query planners analyze queries and choose execution plans. They consider available indexes, table statistics, and cost estimates to find efficient execution strategies.

Understanding how your database’s query planner works helps you write queries that it can optimize effectively. Sometimes restructuring a query or adding an index can dramatically improve performance.

Execution plans show how queries will be executed. Analyzing these plans helps identify bottlenecks and optimization opportunities.

Distributed Databases and Latency Budgets

Distributed databases store data across multiple machines, providing scalability and fault tolerance. However, distribution introduces complexity and latency.

Consistency models determine how updates propagate and when all nodes see the same data. Strong consistency ensures all nodes see updates immediately but can increase latency. Eventual consistency allows temporary inconsistencies but improves availability and performance.

Latency budgets help you understand where time is spent in distributed systems. Network latency, serialization, processing time, and storage I/O all contribute. Understanding these components helps optimize performance.

Replication strategies determine how data is copied across nodes. Synchronous replication ensures consistency but adds latency. Asynchronous replication improves performance but risks data loss.

Summary

Database fundamentals encompass storage engines, indexing, transactions, query optimization, and distributed systems. Understanding these concepts helps you design schemas, write efficient queries, and optimize performance.

The key is to understand your application’s access patterns, choose appropriate data structures and indexes, and balance consistency, availability, and performance based on your requirements.