openskills.info

Document Databases

itDatabases and data storage

Document Databases

A document database stores each record as a document: a self-contained group of named fields and values. A document can contain strings, numbers, Boolean values, null values, nested objects, and arrays. Many products use JSON or a JSON-like format. MongoDB, for example, stores BSON documents, which extend the JSON model with additional data types.

The useful idea is not "JSON instead of tables." It is the aggregate: data that your application reads and changes together can live together. An order document can contain its delivery address and line items. One read can retrieve the order as a complete unit. One single-document write can change several fields atomically in systems that provide document-level atomicity.

That shape can reduce joins and let related fields evolve together. It also moves important design decisions into the document boundary. You still design a schema, even when the database does not require every document to have identical fields.

Why document databases exist

Relational databases organize data into tables and use relationships between rows. That model is strong when shared facts must stay normalized and queries combine data in many ways. It can be awkward when an application usually loads one nested object and must reconstruct it from several tables.

A document database makes the stored record resemble the object or message used by the application. This can help when:

  • one entity owns a bounded set of nested data;
  • records of the same broad type have optional or varying fields;
  • the application usually reads an entire aggregate by its identifier;
  • development requires controlled schema evolution;
  • data must distribute across partitions for horizontal scale.

These are tendencies, not guarantees. Products differ in query languages, index types, transaction scope, validation, replication, and consistency. Verify the behavior of the product and deployment you select.

The document mental model

Consider an order:

{
  "orderId": "A-1042",
  "customerId": "C-88",
  "status": "packed",
  "shippingAddress": {
    "city": "Rome",
    "country": "IT"
  },
  "items": [
    { "sku": "P-17", "quantity": 2, "unitPrice": 12.50 },
    { "sku": "P-31", "quantity": 1, "unitPrice": 8.00 }
  ]
}

The outer object is the document. shippingAddress is an embedded object. items is an array of embedded objects. customerId is a reference to data that probably belongs to a separate customer aggregate.

The document has a stable identity, such as orderId. A collection or container groups documents. Applications query fields, nested paths, and array contents. Indexes create faster access paths for selected queries.

JSON itself is a text interchange format. RFC 8259 defines objects as unordered name-and-value pairs and arrays as ordered values. A database may store another representation internally, impose size limits, or support types beyond JSON. Do not assume that every document database accepts the same values or preserves the same details.

Flexible schema does not mean no schema

Two documents in one collection may have different fields. That flexibility helps during migrations and supports genuinely varied records. It can also let accidental differences accumulate:

createdAt: timestamp
created_at: string
created: missing

The application now has three cases to handle. The database accepted the records, but the data model is inconsistent.

Treat the schema as an explicit contract. Define required fields, data types, allowed values, ownership, and versioning rules. Use database validation where it fits. MongoDB can reject writes that violate validation rules or allow them while logging a warning. Application validation remains useful because it can give users domain-specific errors before a write reaches the database.

Embed or reference

The central modeling choice is whether related data belongs inside one document or in separate documents connected by identifiers.

Embed data when it is owned by the parent, remains bounded, and is usually read with the parent. Embedding can retrieve related data in one operation. In MongoDB, a write to one document is atomic even when it changes multiple embedded fields.

Reference data when it has an independent lifecycle, changes frequently in one canonical place, participates in many-to-many relationships, or must be queried on its own. References reduce duplication, but the application or database may need extra work to assemble related data.

An order usually embeds the delivery address as it was at purchase time. If it referenced only the customer's current address, a later profile update could rewrite history. The order can still reference the customer by identifier because the customer remains an independent entity.

Avoid unbounded embedding. A customer document that accumulates every order forever grows without a natural limit. Large documents cost more to move and update, and products impose different document-size and transaction limits. Store the orders separately and query them by customer identifier.

Design from access patterns

Start with the work the application must perform:

  1. List the important reads and writes.
  2. Identify which fields change together.
  3. Define the document boundary.
  4. Decide which facts can be duplicated and how they stay current.
  5. Choose indexes for frequent filters and sort orders.
  6. Choose a partition key if the system distributes data.
  7. Test realistic sizes, skew, concurrency, and failure behavior.

This process is query-driven modeling. It does not mean building one document for every screen. It means the stored shape and indexes should serve known operations without creating uncontrolled duplication or growth.

Indexes are deliberate access paths

Without a suitable index, a database may scan many documents to answer a query. An index stores selected field values in a structure that supports faster lookup or ordering. Document databases may offer indexes for single fields, compound field sequences, arrays, text, geography, or other product-specific needs.

Indexes have costs. They consume storage and memory. Every relevant write must maintain them. A compound index also depends on field order. MongoDB documents that a compound index supports its leading field or leading field sequence, not an arbitrary suffix.

Create indexes from observed query patterns. Inspect query plans. Remove redundant indexes only after confirming that important queries have another suitable path.

Distribution changes the design

Some document databases partition a collection across machines. A partition key chooses the logical group that stores a document. A good key spreads storage and traffic while allowing common operations to target a small number of partitions.

Azure Cosmos DB hashes partition-key values to map logical partitions onto physical partitions. Items with the same partition-key value share a logical partition. A low-cardinality or heavily skewed key can create a hot partition. A query that lacks the partition key may need to contact many partitions.

Choose the partition key from the workload, not from an attractive field name. Check value cardinality, traffic skew, growth, read routing, and transaction boundaries. Distribution can increase capacity, but it does not repair a concentrated access pattern.

Atomicity, consistency, and conflicts

Do not infer guarantees from the phrase "document database." MongoDB makes single-document writes atomic and supports multi-document transactions, while warning that distributed transactions cost more than single-document writes. CouchDB uses revision identifiers and multi-version concurrency control. On one node, a stale revision can cause a conflict response. Replication can produce conflicting revision branches that the application must resolve.

Ask precise questions:

  • What is the atomic write boundary?
  • Which isolation level applies?
  • When is a committed write visible to readers and replicas?
  • How does the client detect and retry a concurrent update?
  • Can one transaction span documents, collections, or partitions?
  • What happens during network partitions and replication conflicts?

The answers belong to the chosen product, configuration, and operation.

Good fits and warning signs

A document database is often a good fit for content records, product catalogs with varied attributes, user profiles, event envelopes, and application aggregates. The strongest cases have a clear identity, a bounded nested structure, and known access patterns.

Pause when the workload depends on broad ad hoc joins, strict cross-aggregate constraints, or frequent transactions over many unrelated records. Also pause when documents grow without bounds or one key receives most traffic. A relational, graph, search, time-series, or other specialized database may serve those needs better. Many systems use more than one data model, but every additional store adds operational and consistency work.

A path toward competence

First, learn the JSON object and array model. Then practice drawing aggregate boundaries and explaining each embed-or-reference choice. Next, study indexes and query plans in one product. Add validation and a migration strategy. After that, test concurrency, transactions, partitioning, replication, backup, restore, and failure recovery. Production competence comes from measuring the real workload and verifying product-specific guarantees.