← Back to Database and Storage

Database Type Selection

Database selection through workload shape, consistency needs, and access patterns.

Database and StorageDatabase SelectionDatabase Types

Choosing a database is mostly an exercise in matching workload shape to storage guarantees. Teams often start by naming products, but the better question is what the system needs the database to be good at: transactions, flexible documents, low-latency lookups, analytics scans, relationship traversal, time-based ingestion, or cheap blob storage.

For many business systems, a relational database is the default starting point. PostgreSQL, MySQL, and similar systems handle transactions, constraints, joins, indexes, and operational tooling well. If the data has strong relationships, the writes need atomicity, and correctness matters more than raw write throughput, a relational database is usually the least risky choice. People often underestimate how far a good relational design can scale before a more specialised store is necessary.

An in-memory key-value store such as Redis is useful when the main requirement is very low latency for small pieces of data: sessions, rate limits, distributed locks, hot counters, and cache entries. The tradeoff is durability and memory cost. If losing the dataset or rebuilding it from another source would be unacceptable, Redis should not quietly become the only source of truth.

Document stores fit data that is naturally aggregated into self-contained records and changes shape over time, such as product catalogues, user preferences, or content management objects. They reduce friction when the schema is not rigid and the application usually reads or writes whole documents. The tradeoff is weaker support for complex joins and cross-document constraints. Teams sometimes choose a document store to avoid modelling, then rediscover the need for relational consistency later.

Wide-column and distributed key-value stores are designed for very large write volumes, horizontal scaling, and predictable access by partition key. They are good for event ingestion, large denormalised datasets, and globally distributed workloads where availability and throughput matter more than ad hoc querying. The price is that query flexibility is limited. Data models need to be built around known access paths, and changing those paths later can be expensive.

Time-series databases are specialised for timestamped measurements, metrics, and logs. They usually offer compression, retention policies, downsampling, and efficient range queries over time windows. They are a strong fit when data arrives continuously and most reads ask for recent values or aggregates across time. They are a poor fit when the workload needs complex relational transactions.

Graph databases are useful when relationship traversal is the core problem, such as fraud rings, social graphs, network topology, or recommendation paths. If the primary query is many hops across connected entities, a graph model can be clearer and faster than forcing the same problem into repeated relational joins. But graph databases add operational and modelling complexity, so they are rarely the right first database for a standard product application.

Columnar analytical stores excel at scanning large volumes of data for aggregates, trends, and reporting. Systems like ClickHouse are built for OLAP workloads, not high-churn transactional writes. They complement operational databases rather than replacing them.

Object storage is also part of the database decision landscape. Large immutable files, backups, media, and archived exports belong in systems like S3, not in hot relational tables as giant blobs.

A practical rule is to choose the simplest database that satisfies the hardest requirement. Start with relational unless a clear workload characteristic pushes you elsewhere. Add specialised stores for cache, search, analytics, or graph traversal when the need is concrete. Every extra database buys one capability and introduces another operational surface to own.