Key-value, document or wide-column?
| Dimension | Key-value stores | Document databases | Wide-column stores |
|---|---|---|---|
| In one line | A value under a key | A JSON document the database can look inside | Partitions of rows, kept sorted, built for heavy writes |
| What the database sees | A key and a value it never parses | Every field, including nested objects and arrays | Rows with a partition key, clustering columns and other columns |
| How you read | Get by key; some add ranges (DynamoDB sort keys) or data structures (Redis lists, sets, counters) | Filter, sort and aggregate on any field; fetch by ID | One partition, or a sorted slice of it; little else without another table |
| Secondary indexes | Usually none; DynamoDB has global secondary indexes | On any field, including nested ones and arrays | Limited: Cassandra has Storage Attached Indexes since 5.0; Bigtable indexes only the row key |
| Schema | None | Per document, with optional validation | Declared columns in CQL; just column families in Bigtable and HBase |
| Updates | Replace the whole value, or atomic operations like INCR | Change single fields in place with operators like $set | Write individual columns; every write is appended, and deletes leave tombstones |
| How it scales | Hash the key across partitions | Shard by a chosen key; queries without it go to every shard | Partitions spread by hash or key range, with replicas that take writes |
| Reach for it for | Sessions, carts, counters, feature flags, cluster configuration | Product catalogs, user profiles, content | Time series, event logs, messaging, IoT |
| Examples | Valkey, Redis, DynamoDB, etcd | MongoDB, Firestore, DocumentDB, Cosmos DB | Cassandra, ScyllaDB, Bigtable, HBase, Keyspaces |
Rule of thumb
All three hash or range-split a key to spread data across machines, which is why they get lumped together as NoSQL. The difference is how much of your data the database understands. If you only ever fetch by ID, a key-value store is enough; if you search by fields inside records, use documents; if you write a lot and read back ranges within a partition, use wide-column. Some products span two: DynamoDB is both key-value and document, and Redis has a JSON type.
Sources
- DB-Engines: Key-value stores
- DB-Engines: Document stores
- DB-Engines: Wide column stores
- DynamoDB Developer Guide: What is Amazon DynamoDB? (key-value and document models)
- DynamoDB Developer Guide: Improving data access with secondary indexes
- Redis docs: Data types (including JSON)
- Valkey docs: INCR
- MongoDB manual: Query on embedded documents
- MongoDB manual: Multikey indexes
- MongoDB manual: $set
- MongoDB manual: Schema validation
- MongoDB manual: Sharded cluster query routing
- Cassandra docs: CQL data definition
- Cassandra docs: Storage engine
- Cassandra docs: Tombstones
- Apache Cassandra blog: Announcing Apache Cassandra 5.0 (Storage Attached Indexes)
- Google Cloud: Bigtable overview
- Bigtable: A Distributed Storage System for Structured Data (OSDI 2006)