2026-10-26·by Sijie Wang#fundamentals#storage#nosql

nosql

NoSQL, contrasted against the relational set: four shapes, WAL family, version models, replica consistency.

NoSQL, contrasted against the relational set

What it is. "NoSQL" does not mean "no SQL". It means non-relational data models: the engine does not store rows in tables with JOINs, and each shape below trades relational generality for one workload.

The four shapes.

  • Key-value: Redis, DynamoDB. One key maps to one opaque value. Fastest lookup, no query inside the value.
  • Document: MongoDB, CouchDB, Cloud Datastore. JSON-like documents with queryable fields and flexible schema.
  • Wide-column: Cassandra, HBase, Bigtable. See below.
  • Graph: Neo4j. See below.

Wide-column: column families fixed, columns free. A table has a row key and a few column families, fixed at creation. Columns inside a family are added any time, and a row can be extremely wide: one row per user, one column per message. Missing columns cost nothing (sparse), and a read touches one family only. Typical: event logs, message inboxes.

Graph: relations are the data. Nodes are entities, edges are relations carrying properties. Built for relation-chain queries: friends of friends, also-bought, fund paths. The engine walks pointers instead of repeating JOINs.

The WAL family: same job, different names. Any engine that must not lose an acknowledged write keeps a write-ahead log; only the name changes: Cassandra commitlog, MongoDB journal, Redis AOF (see wal).

Cassandra write path. A write goes to the coordinator, lands in the commitlog on disk (append-only) and in the memtable in memory, and only then is acknowledged. When the memtable fills, it flushes to an immutable SSTable on disk.

Commitlog segments have a fixed size (32 MB by default) and roll: a full segment closes, a new one opens. Reclaim granularity is the whole segment: a segment is deletable only when everything in it has flushed. And a down replica's writes never reached it, so its commitlog cannot restore them: the commitlog is local crash recovery, not replica catch-up.

Version models, contrasted.

  • Cassandra/HBase: timestamp multi-version. SSTables are immutable, so writes append and never overwrite in place. The same key written twice lives in several places (memtable plus older SSTables). A read merges them and picks by timestamp: last-write-wins. It reads like a hash map (one visible value) but stores many.
  • MongoDB (WiredTiger): snapshot mvcc. A B-tree with logically in-place updates: one current copy on disk. Multi-version lives in memory update chains, giving concurrent reads a snapshot; old versions are cleaned after readers and checkpoints. Multi-document transactions (4.0+) rest on this: a transaction reads the snapshot as of its start, sees its own writes, and aborts with WriteConflict if someone else changed a document it writes; the client retries the whole transaction. Snapshot isolation, not serializable.
  • Deletes in LSM land are writes too: a tombstone carrying a timestamp wins reads until compaction drops it after gc_grace_seconds.

Replica consistency versus isolation: two different axes. The relational side has one primary deciding, and concurrency is governed by isolation-levels. Cassandra has no leader at all (Dynamo-style quorum, NOT Raft): all nodes are equal.

  • Replication factor is set at keyspace creation: RF=3 means three machines each hold a copy.
  • Consistency level is chosen per operation: ONE (one acknowledgement), QUORUM (majority), ALL (every copy).
  • R + W > N guarantees a read meets the new value: any two majorities of three overlap in at least one node.

Catch-up when a replica is down. Hinted handoff: the coordinator stores the write as a hint and replays it when the replica returns (default 3-hour window; past it, hints are dropped). Read repair: a later read finds a stale replica and the coordinator pushes the new version. Anti-entropy repair (nodetool repair, Merkle trees) is the backstop. Boundary: the only consensus inside Cassandra is lightweight transactions (IF NOT EXISTS, CAS) via Paxos, not Raft, and not on the daily read/write path.

Why it is rarely seen in small-team circles. Heavy operations (compaction, tombstones, repair, JVM tuning); a constrained query model (partition-key-first design, no JOINs, ALLOW FILTERING scans); no cross-partition transactions or strong consistency; and its home ground (massive write-heavy, multi-datacenter workloads) has been split by specialized systems. It is not dead: it is still used at scale where that workload exists (Netflix, Apple, Discord have talked about theirs publicly). It is just not a general-purpose default.

about this entry

One of sijie's wiki entries. The AI on this site is grounded in the same corpus and answers in sijie's voice, with citations back to entries like this one — answering costs sijie money, so it waits behind a code: enter an access code →

nosql — Sijie Wang