Key-value and document stores
Key-value and document stores are the most widely used NoSQL families. Their speed comes from designing data around how it will be read.
Key-value stores
A key-value store is essentially a giant distributed hash map: put(key, value), get(key), delete(key). Values are opaque to the database, so lookups by key are extremely fast, but you cannot query by what is inside the value. Examples include Redis, Amazon DynamoDB (which also supports richer items), Riak, and etcd for configuration.
Redis
Redis, first released by Salvatore Sanfilippo in 2009, keeps data in memory for sub-millisecond access and supports rich value types: strings, lists, sets, sorted sets, hashes, streams, and more. It is widely used for caching, session storage, rate limiting, leaderboards (with sorted sets), and message queues. Persistence options snapshot data or log every write to disk.
Caching patterns
With cache-aside, the application checks the cache, and on a miss reads the database and stores the result with a time-to-live (TTL). Write-through updates the cache whenever the database is written. Caches must be invalidated when data changes; stale caches are a classic source of bugs. Eviction policies such as least recently used make room when memory fills.
Document stores
Document databases store self-describing documents, usually JSON or a binary form such as MongoDB's BSON, grouped into collections. A document can nest objects and arrays, such as an order with its line items embedded. Queries can filter on any field, including nested ones, and secondary indexes make such queries fast. MongoDB, Couchbase, and Firestore are examples.
Embedding versus referencing
Document design asks whether related data should be embedded in one document or stored separately and referenced by ID. Embed data that is read together and owned by the parent, such as an order's line items, for single-read access. Reference data that is shared, large, or unbounded, such as a user's millions of activity events, since documents have size limits (16 MB in MongoDB) and duplicated data must be kept in sync.
Querying and aggregation
Document stores offer query languages for filtering and projecting fields, such as MongoDB's find({status: 'shipped', 'items.sku': 'A12'}). Aggregation pipelines chain stages such as $match, $group, $sort, and $lookup, which performs a join-like operation. These are powerful, but complex multi-collection queries remain more natural in SQL.
Design by access pattern
In many NoSQL systems, especially DynamoDB, schemas are designed from the queries backwards: list each access pattern, such as 'get a customer's recent orders', then choose partition keys, sort keys, and indexes so each pattern is a single efficient request. Single-table designs may store several entity types together. This is efficient but less flexible when new, unforeseen queries appear.
Worked example
A blog stored as documents: each post document contains title, body, tags as an array, and the first 20 comments embedded for fast page loads, while older comments live in a separate comments collection referencing the post's ID. Rendering a post page is one read. An index on tags makes 'all posts tagged databases' fast. Changing an author's display name, however, means updating it wherever it was copied, unless posts store only the author's ID.
Key takeaways
Key-value stores offer very fast get, put, and delete by key, with opaque values: Redis, DynamoDB, etcd. Redis (2009) keeps rich data types in memory for caching, sessions, leaderboards, and queues. Cache-aside with TTLs and careful invalidation is the common caching pattern. Document stores keep nested JSON-like documents in collections with field queries and secondary indexes: MongoDB, Couchbase, Firestore. Embed data read together and owned by the parent; reference shared or unbounded data. Aggregation pipelines transform data. Many NoSQL schemas are designed from access patterns backwards.
Flashcard
Distributed map from keys to opaque values
Check your understanding
In a document database, why store a user's millions of activity events in a separate collection rather than embedding them in the user document?
