NoSQL Databases
The CAP Theorem
Section titled “The CAP Theorem”The CAP theorem, formalised by Gilbert and Lynch in 2002 based on Brewer’s 2000 conjecture, states That a distributed data store can provide at most two of three guarantees:
- Consistency (C): every read receives the most recent write or an error
- Availability (A): every request receives a non-error response (without guarantee about which data version)
- Partition Tolerance (P): the system continues to operate despite arbitrary message loss or delay between nodes
Why P Is Non-Negotiable
Section titled “Why P Is Non-Negotiable”Network partitions are not theoretical — they happen regularly in production. A switch fails, a DNS Update propagates slowly, a garbage collector pause causes a timeout, a cross-datacenter link Degrades. Any distributed system must tolerate partitions, which means the real choice is between CP and AP:
| Category | Strategy | Example Systems |
|---|---|---|
| CP | Preserve consistency, sacrifice availability during partitions | PostgreSQL (sync replicas), HBase, Redis (with replication) |
| AP | Preserve availability, sacrifice consistency during partitions | MongoDB (default, w:1), Cassandra, DynamoDB, CouchDB, Riak |
The PACELC Theorem
Section titled “The PACELC Theorem”The PACELC theorem (Abadi, 2012) extends CAP: when there is no partition (the EL part), the System must choose between Latency and Consistency:
\mathrm{PA \to \mathrm{EL : \mathrm{when no partition, prefer availability and latency over consistency
\mathrm{PC \to \mathrm{EC : \mathrm{when no partition, prefer consistency, accepting higher latency
This captures a nuance that CAP misses: even during normal operation (no partition), systems make Consistency-latency trade-offs. DynamoDB defaults to eventual consistency for low latency but can be Configured for strong consistency (higher latency). Cassandra defaults to eventual consistency but Supports tunable consistency per operation.
Consistency Models: A Spectrum
Section titled “Consistency Models: A Spectrum”Consistency is not binary. There is a spectrum of consistency models, from strongest to weakest:
| Model | Guarantee | Examples |
|---|---|---|
| Linearizable | Operations appear to execute atomically and in real-time order | Single-node databases, ZooKeeper |
| Sequential | Operations appear in some total order consistent with real time | Google Spanner (external consistency) |
| Serializable | Equivalent to some serial execution of transactions | PostgreSQL SERIALIZABLE |
| Snapshot Isolation | Each transaction reads from a consistent snapshot | PostgreSQL REPEATABLE READ |
| Causal | Causally related operations are seen by all nodes in order | DynamoDB (with consistent reads) |
| Read-your-writes | A reader always sees its own writes | Most systems with sticky sessions |
| Session | Consistency within a single client session | MongoDB (read preference) |
| Eventual | If no new writes, all reads eventually converge to the same value | Cassandra, CouchDB, DynamoDB (default) |
RocksDB (used by MongoDB’s WiredTiger for caching, TiKV, and many other systems) is a popular LSM Tree implementation. It is configurable: you can tune compaction strategy, bloom filter size, Compression, block cache, and write buffer size to optimise for specific workloads.
DynamoDB Deep Dive
Section titled “DynamoDB Deep Dive”Amazon DynamoDB is a fully managed, serverless key-value and document store that implements a Dynamo-style architecture.
Data model:
{ "TableName": "Orders", "KeySchema": [ { "AttributeName": "customer_id", "KeyType": "HASH" }, { "AttributeName": "order_id", "KeyType": "RANGE" } ], "AttributeDefinitions": [ { "AttributeName": "customer_id", "AttributeType": "S" }, { "AttributeName": "order_id", "AttributeType": "S" } ], "BillingMode": "PAY_PER_REQUEST"}Capacity modes:
| Mode | Characteristics |
|---|---|
| Provisioned | Specify read/write capacity units; cheaper for predictable workloads |
| On-Demand | Auto-scales; pay per request; more expensive for steady workloads |
Global Secondary Indexes (GSI):
- Allows querying on non-key attributes
- Eventually consistent by default (can be configured for strong consistency)
- Consumes additional capacity units
- Limited to 20 per table
DynamoDB Streams:
- Time-ordered sequence of item-level changes (insert, modify, delete)
- Enables event-driven architectures (trigger Lambda on change)
- 24-hour retention by default
Elasticsearch as a NoSQL Database
Section titled “Elasticsearch as a NoSQL Database”Elasticsearch is often used alongside a primary database for full-text search. It is a distributed, RESTful search engine built on Apache Lucene.
PUT /products/_doc/1{ "name": "Precision Wrench Set", "category": "Tools", "price": 49.99, "description": "A set of 12 precision wrenches for mechanical work", "tags": ["automotive", "mechanical", "hand-tools"], "in_stock": true}
GET /products/_search{ "query": { "bool": { "must": [ { "match": { "description": "precision wrench" } }, { "term": { "in_stock": true } } ], "filter": [ { "range": { "price": { "lte": 100 } } } ] }, "aggs": { "by_category": { "terms": { "field": "category" } } } }}