NoSQL Vocabulary

26 NoSQL terms in plain English — what each one means, an example, and the gotcha worth knowing. Covers document, key-value, wide-column, and graph databases.

Last reviewed:

Sections

Core concepts

NoSQL

"Not only SQL" — an umbrella term for databases that don't use the traditional relational, table-and-JOIN model.

# document (MongoDB), key-value (Redis), wide-column (Cassandra), graph (Neo4j)

💡 Not a single technology — the different NoSQL families solve genuinely different problems, not one problem four ways.

schema-less

Records don't need to follow a predefined, fixed structure — different documents in the same collection can have different fields.

{ "name": "Alice", "role": "admin" }
{ "name": "Bob", "role": "user", "team": "infra" }  // extra field, no problem

💡 Flexibility shifts validation responsibility to the application layer — the database won't stop you from writing inconsistent data.

CAP theorem

A distributed system can only guarantee two of three properties at once: Consistency, Availability, and Partition tolerance.

# during a network partition, a system must choose:
# stay consistent (reject some requests) or stay available (risk stale reads)

💡 Since network partitions are unavoidable in practice, the real-world choice is almost always CP vs. AP.

eventual consistency

A guarantee that all replicas will converge to the same value eventually, but reads immediately after a write may return stale data.

# write to replica A succeeds instantly;
# a read from replica B a moment later might still return the old value

💡 A deliberate trade-off for higher availability and lower write latency — not a bug, a design choice.

horizontal scaling

Handling more load by adding more machines (nodes) to a cluster, rather than making one machine bigger.

# 3 nodes not enough? add a 4th — no downtime, no bigger single server needed

💡 The main reason many NoSQL databases exist — they're designed from the ground up to scale this way, unlike most traditional RDBMSs.

Document stores

document

A single self-contained record, usually stored as JSON/BSON, that can nest arrays and objects instead of splitting data across tables.

{
  "_id": "u123",
  "name": "Alice",
  "addresses": [{ "city": "Kyiv" }, { "city": "Lviv" }]
}

💡 The nested addresses array would require a separate table and a JOIN in a relational model.

collection

A group of related documents — the document-database rough equivalent of a table, but without an enforced shared schema.

db.users.insertOne({ name: "Alice" })

💡 Documents within one collection commonly represent the same kind of entity, even without a schema forcing it.

embedding

Nesting related data directly inside a parent document instead of storing it in a separate collection and referencing it.

{ "order_id": "o1", "items": [{ "sku": "abc", "qty": 2 }] }

💡 Great for data that's always read together; bad for data that grows unbounded or is shared across many parents.

referencing

Storing an ID that points to a document in another collection, instead of embedding the full related data.

{ "order_id": "o1", "customer_id": "c42" }

💡 The document-database analogue of a foreign key — but there's no enforced referential integrity by default.

aggregation pipeline

A sequence of processing stages (filter, group, sort, reshape) applied to documents to compute a result — the document-store answer to complex SQL queries.

db.orders.aggregate([
  { $match: { status: "paid" } },
  { $group: { _id: "$customer_id", total: { $sum: "$amount" } } }
])

💡 Each stage passes its output to the next, similar in spirit to piping shell commands together.

Key-value stores

key-value store

The simplest NoSQL model — every piece of data is a value retrieved by a unique key, with no query language beyond "get this key".

SET session:abc123 "user_id=42"
GET session:abc123

💡 Extremely fast lookups by design, at the cost of no complex queries — you can't ask "find all sessions for user 42" without a secondary index.

TTL (key expiry)

Setting a key to automatically delete itself after a specified duration — built into most key-value stores.

SET session:abc123 "..." EX 3600   # expires in 1 hour

💡 The standard mechanism behind session storage, rate-limit counters, and cache entries.

in-memory store

A database that keeps all (or most) data in RAM rather than on disk, trading durability for extreme speed.

# Redis, Memcached — sub-millisecond reads

💡 Many in-memory stores offer optional persistence (periodic snapshots or a write-ahead log) so a restart doesn't lose everything.

cache-aside pattern

The application checks the cache first; on a miss, it reads from the primary database and writes the result into the cache for next time.

value = cache.get(key)
if value is None:
    value = db.query(key)
    cache.set(key, value, ttl=300)

💡 The most common way key-value stores get used alongside a "real" database, rather than replacing it.

Wide-column stores

wide-column store

A model where each row can have a different, dynamic set of columns, grouped into column families — built for massive write throughput.

# Cassandra, HBase, Bigtable

💡 Designed for write-heavy workloads at huge scale — think time-series and event-logging use cases.

partition key

The field that determines which physical node in the cluster stores a given row — the single most important design decision in a wide-column schema.

# rows partitioned by user_id land on the same node, making per-user queries fast

💡 A poorly chosen partition key causes a "hot partition" — one node overloaded while others sit idle.

column family

A grouping of related columns stored together on disk — designed around how the data is queried, not just how it's logically related.

# a "profile" column family and a separate "activity" column family for the same entity

💡 Schema design here is query-first: you model the table around the questions you'll ask it, not the entity relationships.

tombstone

A marker written in place of a deleted value, since distributed wide-column stores can't just erase data across every replica instantly.

# a delete doesn't remove data immediately -- it writes a tombstone that gets cleaned up later

💡 Too many tombstones accumulating (from frequent deletes) is a well-known Cassandra performance problem.

Graph databases

graph database

Stores data as nodes (entities) and edges (relationships) explicitly, optimized for traversing connections rather than joining tables.

# Neo4j, Amazon Neptune

💡 Shines when the interesting question is about relationships themselves — "friends of friends", fraud rings, recommendation paths.

node (graph)

A single entity in a graph database — a person, product, or place — that can carry its own properties.

CREATE (a:Person { name: "Alice" })

💡 Conceptually similar to a row, but relationships to other nodes are first-class, not a separate join table.

edge / relationship

A directed, typed connection between two nodes, which can itself carry properties (e.g. "since 2020").

MATCH (a:Person), (b:Person)
WHERE a.name = "Alice" AND b.name = "Bob"
CREATE (a)-[:FOLLOWS { since: 2020 }]->(b)

💡 Traversing edges is typically O(1) per hop in a graph database, versus an expensive JOIN in a relational one.

traversal

Walking from node to node along edges to answer a query — the graph-database equivalent of a JOIN-heavy relational query.

MATCH (a:Person)-[:FOLLOWS*1..2]->(b:Person)
RETURN b

💡 A multi-hop traversal that would require several expensive JOINs relationally is often a single fast query in a graph database.

Distributed operations

sharding

Splitting a large dataset across multiple servers (shards), each holding a subset of the data.

# users A-M on shard 1, users N-Z on shard 2

💡 Distinct from replication — sharding splits data for scale; replication copies data for redundancy. Many systems do both.

replica set

A group of database nodes holding copies of the same data, for redundancy and read scaling — one primary, the rest secondaries.

# MongoDB replica set: 1 primary (handles writes) + 2 secondaries (replicate + serve reads)

💡 If the primary fails, the replica set automatically elects a new one — this is what "automatic failover" means in practice.

quorum

The minimum number of nodes that must acknowledge a read or write for it to be considered successful.

# write quorum of 2 out of 3 replicas = tolerates 1 node being down

💡 Tuning read/write quorum is how you trade off consistency, availability, and latency in practice.

denormalization

Deliberately duplicating data across documents/rows to avoid expensive joins at read time — the opposite of relational normalization.

{ "order_id": "o1", "customer_name": "Alice" }
// customer_name duplicated here instead of joined from a customers table

💡 A core NoSQL design principle: optimize for how data is read, and accept the cost of keeping duplicates in sync on writes.

English phrases engineers use

  • "We're getting a hot partition — that key is way too popular."
  • "That read might be eventually consistent — don't rely on it right after the write."
  • "We denormalized the customer name onto the order so we don't have to join at read time."
  • "This is a graph problem — let's just traverse it instead of writing five JOINs."
  • "Bump the write quorum to 2 — we can't afford to lose that data."
  • "Should we embed this or just reference it by ID?"