When would you choose a key-value store over a relational database, given how each one stores and queries data?
answer
- what questions each store can answer
- opaque value versus typed columns
- one key touches one partition
- sessions, carts, flags, cached results
- joins and multi-row transactions stay relational
basics
~20 sA relational database stores typed rows and answers flexible SQL queries with joins and multi-row transactions; a key-value store only gets and puts a value by its key. Choose key-value when every access is a lookup by a known key.
solid answer
~40 sA **relational database** keeps data in tables with a fixed schema, enforces constraints, and lets you ask new questions later with SQL: filters on any column, joins, aggregates and transactions that change several rows atomically. A **key-value store** treats the value as an opaque blob addressed by a key; it answers `get(key)`, `put(key, value)` and `delete(key)` very fast and partitions easily across machines because every operation touches one key. So I pick key-value when the access pattern is 'fetch or overwrite this one thing by its ID' at high volume and low latency, such as sessions, carts, feature flags or cached results. I stay relational when I need ad-hoc queries, relationships between entities, or several rows changing together, because a plain key-value store would push that work into application code.
go deeper
Recall the two contracts: typed rows queried with SQL, joins and transactions, versus opaque values fetched by key. Name two workloads that fit each.
Explain why single-key operations partition easily and why that same property removes ad-hoc queries, and show how key design fixes the access pattern in advance.
Show you check durability, expiry and consistency guarantees before treating a key-value store as a system of record, and that you keep a relational source of truth when relationships matter.
Frame the choice as flexibility now versus predictable latency at scale, and explain when a team should defer specialisation until real access patterns are measured.
## Two different contracts A datastore is a promise about **what questions you may ask** and **what guarantees you get back**. Relational databases and key-value stores make very different promises, and choosing between them starts with the questions your feature will ask. - A **relational database** stores data as **rows** in **tables**. Each column has a type, and the engine can enforce **constraints** such as uniqueness and foreign keys. You query it with **SQL**, which lets you filter on any column, **join** tables, group and aggregate, and wrap several changes in one **transaction** that either fully commits or fully rolls back. - A **key-value store** stores **pairs**: a key and a value. The store usually does not interpret the value; to it, the value is just bytes. The core operations are `get(key)`, `put(key, value)` and `delete(key)`, often with an optional **expiry** (a time-to-live) per key. ## What each one is good at | Property | Relational database | Key-value store | |---|---|---| | Query shape | Any filter, join or aggregate, decided later | Lookup by exact key, decided up front | | Schema | Declared and enforced by the engine | Opaque value; the application owns the shape | | Transactions | Multi-row, multi-table | Usually single-key; some offer small batches | | Horizontal partitioning | Possible but joins and transactions get harder | Natural: each key lives on one partition | | Typical latency | Low, depends on query and indexes | Very low and predictable for single-key reads | Because every key-value operation touches exactly one key, the store can spread keys across many machines with a hash of the key and never needs to coordinate a query across them. That is where its predictable latency and easy scale-out come from. The price is **query flexibility**: if you later need 'all carts that contain product 17', a plain key-value store has no way to answer except scanning every key or maintaining a second index that you build and keep in sync yourself. ## Workloads that fit a key-value store 1. **Session state**: read on every request by session ID, overwritten often, expired after inactivity. 2. **Shopping carts and user preferences**: always loaded and saved as a whole for one user. 3. **Feature flags and configuration**: tiny values read constantly by a known name. 4. **Cached results**: a computed response stored under a key derived from the request. 5. **Idempotency keys and rate-limit counters**: a small value per client or request ID. In each case the application already knows the key before it asks, and it never needs to search by what is inside the value. ## Workloads that should stay relational - **Business records with relationships**, such as customers, orders and invoices that are queried together. - **Money and inventory**, where several rows must change atomically and constraints must never be violated. - **Reporting and back-office screens**, where people keep inventing new filters. - **Early-stage products**, where you do not yet know the access patterns and flexibility is worth more than raw speed. ## Common misunderstandings - Key-value stores are not automatically 'faster databases'. A relational lookup on an indexed primary key is also fast; the key-value advantage is predictable latency at very high volume and simple partitioning. - A key-value store is not only an in-memory cache. Some key-value stores are durable systems of record, while others are volatile caches; you must check which durability model you are getting. - Choosing key-value does not remove the need for a data model. You still decide how keys are built, for example `user:42:cart`, and that key design *is* your access pattern, fixed in advance. - Many real systems use both: the relational database is the **system of record**, and a key-value store holds sessions or cached views derived from it. ## How to answer in an interview Start from the access pattern: 'Do we always know the key? Do we ever need to search inside the value? Do several records have to change together?' If the answers are yes, no and no, a key-value store is a strong fit. If you need joins, ad-hoc filters or multi-row transactions, the relational database is the safer choice, and you can still add a key-value store beside it later for the hot, key-shaped paths.
- How do you design keys in a key-value store so the application can find related values?You encode the access path into the key, for example `user:42:cart` or `session:<id>`, so the application can build the key from what it already knows. Related values share a prefix or an ID. Because the store cannot search inside values, any lookup you will need later must be anticipated in the key design or served by a separate index that you maintain yourself.
- If a key-value store later needs a lookup by a field inside the value, what are your options?You can maintain a second key that maps the field value to the primary keys, updating both on every write, which adds consistency work. Some key-value stores offer built-in secondary indexes with their own limits, and systems differ here. Or you can accept that the need has outgrown key-value access and serve that query from a store that supports it, fed from the same source of truth.
A key-value store is a coat check: hand over a ticket and you get exactly one coat back, instantly. A relational database is a library catalogue: slower to set up, but you can search by author, subject or year whenever a new question comes up.
saying these in an interview costs you the question
- Key-value stores are simply faster databases, so use one for everything
- A key-value store can filter by any field inside the stored value
- Key-value stores are always in-memory and therefore never durable
- Relational databases cannot handle high read volumes at all
- Picking key-value means you no longer need to design a data model