Databases Unlocked: Modern Storage, Indexing, and Query Planning - Sample
My Account List Orders

Databases Unlocked: Modern Storage, Indexing, and Query Planning

Table of Contents

  • Introduction
  • Chapter 1 Why Databases Matter: Workloads, SLAs, and Design Goals
  • Chapter 2 Hardware and OS Foundations for Data Systems
  • Chapter 3 Storage Engine Fundamentals: Pages, Records, and Buffer Managers
  • Chapter 4 The B-Tree Family: Structure, Variants, and Tuning
  • Chapter 5 LSM-Tree Storage: Compaction, Bloom Filters, and Write Paths
  • Chapter 6 Columnar Storage and Compression Techniques
  • Chapter 7 Indexing Beyond B-Trees: Hash, GiST/GIN, Inverted, and Spatial
  • Chapter 8 The Query Processing Pipeline: From Parsing to Execution
  • Chapter 9 Join Algorithms and Aggregations at Scale
  • Chapter 10 Cost-Based Optimization and Cardinality Estimation
  • Chapter 11 Transactions and Concurrency Control: 2PL, MVCC, and OCC
  • Chapter 12 Isolation Levels in Practice: Anomalies and Verification
  • Chapter 13 Consistency Models Explained: CAP, PACELC, and Linearizability
  • Chapter 14 Replication and Consensus: Raft, Paxos, and Practical Tuning
  • Chapter 15 Sharding and Partitioning Strategies for Scale
  • Chapter 16 Relational Internals: PostgreSQL and InnoDB Case Studies
  • Chapter 17 NoSQL Architectures: Key-Value, Document, Wide-Column, and Graph
  • Chapter 18 NewSQL Systems: Distributed SQL and HTAP Engines
  • Chapter 19 Query Planning in Distributed and Federated Systems
  • Chapter 20 Observability and Workload Profiling: Metrics, Tracing, and Plans
  • Chapter 21 Performance Tuning Playbook: Latency, Throughput, and Tail Behavior
  • Chapter 22 Reliability Engineering: Backups, Snapshots, and Disaster Recovery
  • Chapter 23 Security and Governance: Authentication, Encryption, and Auditing
  • Chapter 24 Cloud-Native Databases: Serverless, Multi-Tenant, and Cost Models
  • Chapter 25 Benchmarking and Testing: Methodology, Anti-Patterns, and Case Studies

Introduction

Databases sit at the center of modern software, quietly carrying the weight of every click, payment, recommendation, and scientific result. Yet their internal machinery—how bytes become tables, how indexes accelerate queries, how consistency is achieved across machines—often feels opaque. Databases Unlocked: Modern Storage, Indexing, and Query Planning opens that machinery and explains it with a practical lens. This book is designed to help you reason about trade‑offs so you can choose, configure, and tune data stores that meet concrete latency, throughput, and scalability goals.

Our approach is hands-on and systems-oriented. We begin at the bottom with storage engines: how records are laid out on pages, how buffer managers interact with the operating system, and why some systems favor B-Trees while others rely on LSM-Trees or columnar formats. From there we move to indexing—hash, B-Tree variants, GiST/GIN, inverted, and spatial—explaining when each shines and how to tune them. We then trace the path of a query through parsing, planning, and execution, demystifying cost models, statistics, join strategies, and the optimizations that make complex workloads fast.

Performance and correctness depend on concurrency control and consistency, so we devote substantial space to transactions, isolation levels, and anomalies you can actually observe. You will learn how 2PL, MVCC, and optimistic techniques behave under contention; how replication and consensus maintain availability; and how consistency models such as linearizability, eventual, and bounded staleness shape user-visible behavior. Throughout, we use case studies across relational, NoSQL, and NewSQL systems to show these concepts in the wild, highlighting both successes and pitfalls.

This is a book for engineers, SREs, architects, data scientists, and students who want to make principled decisions about data systems. If you have basic familiarity with data structures and SQL, you are ready. Each chapter emphasizes mental models, actionable diagnostics, and checklists you can take back to your production environment. Rather than offering one-size-fits-all prescriptions, we focus on understanding the workload—read/write ratios, access patterns, skew, and failure modes—so that your choices align with business SLAs.

You will also learn how to measure what matters. We discuss profiling queries, interpreting explain plans, tracking tail latency, and designing fair benchmarks that avoid common traps. We pay attention to observability—logs, metrics, tracing—and to reliability practices like backups, snapshots, and disaster recovery testing, because performance without resilience is brittle. Security and governance are treated as first-class concerns, not afterthoughts, with practical guidance on authentication, encryption, and auditing.

Finally, the ecosystem evolves quickly, but the fundamentals endure. By grounding modern architectures—cloud-native services, serverless databases, multi-tenant platforms, and distributed SQL—in core principles, you will be equipped to evaluate new technologies with a critical eye. The goal is not merely to make your queries faster; it is to help you build systems that are understandable, tunable, and dependable. With that, let’s unlock the database.


CHAPTER ONE: Why Databases Matter: Workloads, SLAs, and Design Goals

Data systems are the quiet engine rooms of modern software. They absorb the torrent of events from user clicks, sensor readings, and financial transactions, and later return just the right slice of history to power decisions and experiences. Most engineers do not fall in love with databases; they fall in love with the results that databases make possible. Yet the gap between a product spec and a working, fast, reliable system often lives in the details of storage formats, indexing strategies, and concurrency choices. If those details are ignored, performance and correctness become a matter of luck. If they are embraced, you can reason about trade-offs and tune for outcomes that matter.

A useful first step is to forget that databases are a single thing and think of them as a collection of components working together. There is a storage engine that manages how bytes land on disk or in memory, an indexing layer that speeds up access, and a query planner that chooses how to execute a request. There is a transaction manager responsible for isolation and atomicity, and a replication layer for durability across nodes. When a query is slow or a transaction deadlocks, the cause could be in any of these parts. Understanding which part is responsible requires a mental map of the whole system, which is what this book aims to provide.

Workloads are the primary drivers of design. A workload is more than a list of tables and queries; it is the dynamic combination of read/write ratios, key distributions, request sizes, concurrency levels, and the shape of change over time. Some workloads are write-heavy, like event logging or telemetry ingestion, where the bottleneck is the cost of persisting data reliably. Others are read-heavy, like user profile lookups or product catalogs, where the challenge is serving many concurrent requests with low latency. Mixed workloads, common in transactional systems, require balancing the two without starving either. Mischaracterizing a workload is the fastest route to expensive hardware and disappointed users.

Service level objectives translate business needs into measurable engineering targets. A latency goal might be that the p99 response time for a particular endpoint stays under 100 milliseconds, while availability could target 99.95% uptime per month. Throughput might be defined as orders processed per second or scans per hour. These targets are not arbitrary numbers; they reflect user expectations and business risk. A slow checkout flow loses sales. A data platform that cannot keep up with ingestion will create backlogs and delayed analytics. Getting specific about numbers is essential because the performance characteristics of different storage engines and indexing schemes vary widely, and only a concrete goal gives you a compass.

Choosing a database is a design exercise, not a popularity contest. The same system that excels at high-throughput writes may be clumsy at complex ad hoc analytics. A key-value store might be perfect for caching but poorly suited for joins and aggregations. Some systems prioritize strong consistency, while others favor availability and lower latency. The “best” choice depends on which trade-offs align with your workload and goals. A helpful habit is to ask what the system optimizes for first, then check whether that optimization matches your needs. The answer often reveals whether a technology is a good fit or merely possible.

Storage durability is the foundation everything else rests on. Durability means that once a transaction commits, its effects survive crashes, power loss, and restarts. This is typically achieved by writing ahead to a write-ahead log (WAL) before modifying in-memory structures, then ensuring the log is flushed to stable storage. The durability model influences both reliability and performance. Aggressive flushing improves safety but can reduce throughput. Group commit can amortize the cost of flushes, but it adds coordination overhead. When a system does not meet its durability targets, no amount of indexing or caching will make it trustworthy.

Concurrency control determines how multiple clients read and write concurrently without stepping on each other. Two-phase locking (2PL) prevents conflicts by making readers and writers block each other, while multi-version concurrency control (MVCC) avoids reader/writer contention by keeping multiple versions of rows. Optimistic concurrency control (OCC) allows transactions to proceed and checks for conflicts at commit time. Each approach has different behavior under contention: 2PL can deadlock, MVCC may create version cleanup overhead, and OCC can suffer from high abort rates under heavy conflict. The choice of concurrency model affects throughput, latency, and the anomalies users might see.

Isolation levels define the visible behavior of concurrent transactions. The ANSI SQL standards describe read uncommitted, read committed, repeatable read, and serializable. In practice, databases often implement these levels differently, and vendor extensions add further nuance. Read committed allows non-repeatable reads, where a row can change between two reads in a transaction. Repeatable read may prevent that but still permit write skew or phantoms depending on implementation. Serializable aims to eliminate anomalies but may reduce concurrency and increase aborts. Understanding what your system actually guarantees—and which anomalies it permits—is crucial for building correct applications.

Consistency models describe behavior across replicated nodes. Strong consistency, often called linearizability, ensures that reads reflect the latest write. Eventual consistency allows temporary divergence but promises convergence if writes stop. Bounded staleness provides guarantees that reads will not be older than a defined time or version offset. These choices are tied to replication protocols and consensus algorithms like Raft or Paxos. Strong consistency typically incurs higher latency due to coordination, while eventual consistency can provide lower latency at the cost of application-level conflict resolution. Choosing the right model depends on user expectations and tolerance for staleness.

Indexing accelerates queries but is not free. A B-Tree index provides ordered access to rows and is excellent for range scans and equality lookups. A hash index maps keys directly and can be faster for point lookups but does not support ranges. Inverted indexes power text search, while specialized structures like GiST and GIN support geospatial and array operations. Indexes cost storage, add write amplification because they must be updated on changes, and can fragment over time. Some workloads benefit from covering indexes that include all columns needed for a query, while others benefit from partial indexes that index a subset of rows based on predicates.

Query planning is where strategy meets cost. A planner parses a query, resolves object names, and builds an execution plan. It uses statistics about table sizes, value distributions, and correlation to estimate cardinalities, then chooses join algorithms and access paths accordingly. The plan might select a nested loop join for small inputs, a hash join for medium sets, or a merge join when inputs are sorted. Index availability, filter selectivity, and sort requirements shape decisions. Cardinality estimation errors can lead to poor choices, such as picking a nested loop when a hash join would be far faster, resulting in unexpectedly slow queries.

Execution engines translate plans into actions that read and transform data. Some systems use a volcano-style iterator model, where each operator pulls rows from its children. Others use vectorized execution, processing batches of values to reduce per-row overhead and better exploit CPU caches. Newer engines may compile expressions into machine code to avoid interpretation costs. Memory management during execution is critical: hash aggregations and sorts can spill to disk if memory is insufficient, causing latency spikes. Observability into operator-level metrics can reveal whether a plan is performing as expected or if resource constraints are causing stalls.

Caching layers reduce repeated work. Buffer managers keep frequently used pages in memory to avoid expensive disk I/O. Query result caches can serve identical requests without touching the storage engine. Filesystem or operating system caches also play a role, especially when the database is not the only process using memory. Caching introduces coherence problems: stale data can be served if invalidation is not handled carefully. Write-through caches simplify correctness but add latency; write-back caches improve performance but risk data loss on crashes unless the log is durable. Tuning cache sizes and eviction policies is a regular task in production.

Write amplification occurs when a small logical update causes a large amount of physical I/O. In B-Tree systems, updating a row might cause page splits and index rebalancing. In log-structured systems, updates are written to new files and later compacted, rewriting data multiple times. Write amplification reduces flash device lifetimes and increases latency if compaction falls behind. It can be mitigated by batching writes, tuning compaction strategies, or using larger pages, but each mitigation has trade-offs. Monitoring write amplification helps you understand the cost of your durability and indexing choices and decide whether they are sustainable.

Read amplification is the opposite problem: a single logical read may require multiple physical reads. A query that touches several secondary indexes plus the primary table can issue many random I/O requests. Prefix scans or range queries might read many pages to satisfy the filter. In LSM-based systems, reads may need to check multiple levels of files, and bloom filters help reduce unnecessary checks. Mitigations include covering indexes that avoid table access, prefix compression, and careful schema design that aligns indexes with access patterns. Measuring read amplification helps diagnose why some queries are slow even with indexes present.

Space amplification is the cost of storing more bytes on disk than the raw data would require. Indexes, versioning, and fragmentation all contribute. MVCC keeps multiple versions of rows, which can bloat tables if old versions are not purged. Compaction in log-structured stores can temporarily need extra space, and a failure to reclaim space can cause out-of-disk events. Even unused space in pages due to updates or deletes adds overhead. Space amplification affects cost and also performance, because larger files increase I/O ranges and memory pressure. Periodic maintenance operations like vacuuming or compaction keep space under control.

Tail latency matters more than average latency for user experience. A request that takes 100 ms on average but 2 seconds occasionally will cause visible issues. Sources of tail latency include GC pauses, disk stalls, lock contention, compaction bursts, checkpoint spikes, and network jitter. Mitigations are varied: incremental or concurrent GC, pacing background tasks, isolating critical paths from maintenance, pre-warming caches, and eliminating contention points. Measuring p50, p95, p99, and p99.9 latencies separately helps distinguish typical behavior from outliers. Engineering for the tail often means understanding the worst-case behavior of each subsystem.

Scalability goals drive architectural choices. Vertical scaling increases the power of a single machine; horizontal scaling distributes load across many nodes. Distribution introduces new problems: partitioning, replication, and coordination. Partitioning strategies include hash partitioning, range partitioning, and directory-based schemes. Each has trade-offs in terms of evenness of load, ability to perform scans, and hotspot risk. Replication adds availability and read capacity but introduces consistency and failover concerns. Choosing where to scale—read capacity, write capacity, or both—determines which techniques to apply and what failure modes to prepare for.

Not every system needs to scale to billions of rows to be successful. Smaller systems still benefit from careful design. A dataset that fits entirely in memory can be very fast, but you still need to think about durability and recovery time. A multi-tenant application needs to prevent noisy neighbors from affecting other tenants. Even a simple analytics dashboard can suffer from slow queries if statistics are stale. Good design is fractal: the same concepts apply at different scales. The trick is to tailor your approach to the workload rather than adopting patterns designed for problems you do not have.

Distributed systems bring a new set of trade-offs, summarized by CAP and PACELC. CAP reminds us that under a network partition we must choose between consistency and availability. PACELC extends this to normal operation, noting that even without partitions there is a trade-off between latency and consistency. Choosing strong consistency can mean higher latency due to coordination, while lower latency might require accepting eventual consistency or bounded staleness. Consensus algorithms like Raft or Paxos provide building blocks for consistent replication but add round-trip overhead and failure handling complexity. Aligning these choices with business requirements is part of mature architecture.

Observability is essential to keeping databases healthy and fast. Metrics reveal throughput, error rates, and resource utilization. Tracing shows the lifecycle of a request across components, making it easier to pinpoint bottlenecks. Logs record state changes and decisions, such as compactions, elections, or checkpoint durations. Good observability includes not only database-internal metrics but also client-visible outcomes like end-to-end latency. Dashboards help you spot trends, while alerting ensures you react to problems before they impact users. Importantly, observability must be actionable: metrics without context or known thresholds are noise rather than signal.

Workload profiling connects system behavior to business impact. Profile production traffic with care, capturing not only aggregate rates but distributions and outliers. When possible, run controlled experiments using canary releases or shadow traffic to compare behaviors across versions or configurations. Look for skew: a small number of keys or queries often drive a large fraction of load. Skew can lead to hotspots and unpredictable performance. Identify contention points such as locks, latches, or shared resources. The goal of profiling is to find the highest-leverage interventions—the changes that will move your service level objectives the most.

Schema design remains a high-leverage tool, even in systems that claim “schemaless.” The way you structure data affects indexing, compaction, and query patterns. Denormalization can speed up reads but complicates writes and consistency. Choosing appropriate data types can reduce storage and make comparisons faster. Keys can be designed to avoid monotonic inserts that create hotspots. In document stores, embedding versus referencing has significant implications for access patterns and update costs. In wide-column stores, row key design determines locality. Thoughtful schema design is a first-order performance tool, not just a correctness requirement.

Cloud-native databases introduce elasticity and operational leverage, but also new constraints. They can scale compute and storage independently, and often provide managed backups and failover. However, they share resources in multi-tenant environments, which can cause noisy neighbor effects. Network hops between compute and storage can add latency or variability. Serverless models provide cost efficiency for bursty workloads but may have cold start or resource contention issues. Understanding the cloud provider’s durability guarantees, replication model, and billing metrics is critical. You trade direct control for convenience, and you must adjust your expectations and tuning accordingly.

Cost is a non-trivial design constraint. Storage, compute, network egress, and backups all contribute to total cost of ownership. A system that is cheap to run at small scale may become prohibitively expensive at large scale due to write amplification, index overhead, or replication. Observability into cost is as important as observability into performance. Benchmarking should include cost-per-transaction or cost-per-GB metrics. Tuning for performance often reduces cost, but not always; sometimes the cheapest path requires accepting higher latency or lower availability. Aligning cost with business value is part of the architect’s job.

Benchmarking is how you validate choices, but it is easy to get wrong. Use realistic data distributions and query mixes, not synthetic microbenchmarks that ignore skew or contention. Consider the impact of caching and warm-up, and be transparent about whether results include cold or warm runs. Measure tail latency and failure scenarios, not just averages. Beware of overfitting to a single workload; a system that shines on one pattern may falter on another. The goal is not to find the “fastest” system in the abstract, but to verify that a system meets your specific goals under realistic conditions.

Reliability and security are not side concerns. Backups, snapshots, and disaster recovery testing ensure you can recover from failures without data loss. Encryption at rest and in transit protects sensitive information, and strong authentication and auditing are required for governance. These features sometimes add performance overhead, so they must be included in performance testing. A system that is fast but cannot be restored reliably or is insecure is not production-ready. Treating these features as first-class from the start avoids last-minute surprises and ensures compliance and trust.

A practical approach ties all these pieces together. Start by defining your workload and SLAs clearly. Choose and configure systems to match those goals, accepting trade-offs explicitly. Instrument everything, profile regularly, and iterate. Maintain indexes and storage hygiene to prevent slow degradation. Plan for tail events and test failovers. Align cost with value, and include security and reliability in your definition of quality. The rest of this book dives into each component in detail, providing the mental models and practical techniques you need to make these decisions with confidence.


This is a sample preview. The complete book contains 30 sections.