Chapter 13 · Denormalization, Caching, and Derived Data

Duplicated Attributes and Consistency Ownership

Design duplicated attributes safely by naming the authoritative source, defining synchronization rules, and separating historical snapshots from accidental redundancy.

Beginner65–95 minutesDuplication + ownershipLast reviewed: August 2026

Learning outcomes

Duplicating an attribute is safe only when the system can answer one question clearly: which copy is authoritative? Without that rule, denormalized fields drift and different consumers see different truths.

01

Assign authoritative ownership to every duplicated fact.

02

Separate mutable copies from historical snapshots.

03

Choose synchronous or asynchronous synchronization deliberately.

04

Design reconciliation rules for duplicated attributes.

One fact, one owner

model · example
Customer.legal_name           -- authoritativeWorkOrderProjection.customer_name  -- derivedInvoice.customer_name_snapshot     -- historical fact

The projection copy should not become independently editable. The invoice snapshot may intentionally remain unchanged forever.

Current copy versus historical snapshot

CopyMeaningRefresh?
Projection.customer_nameCurrent Customer nameYes
Invoice.customer_name_snapshotName at invoice issuanceNo
PartUsage.charged_unit_pricePrice charged at usage timeNo
Snapshot rule

Equal-looking values can have different owners because their time semantics differ.

Synchronous duplication

sql · example
BEGIN;UPDATE customer ...;UPDATE customer_read_projection ...;COMMIT;

Strong consistency, but greater transaction cost and coupling.

Asynchronous duplication

Lower source-write coupling, but temporary staleness must be accepted and monitored.

Versioned synchronization

model · example
customer_id = 17source_version = 42

If version 44 has already been applied, a late version-43 event must not overwrite the newer projection state.

Idempotent projection updates

Duplicate event delivery should be harmless. Store processed event IDs, source versions, or design the update as a deterministic overwrite rather than an unconditional increment.

Ownership across services

Prefer:

model · example
Customer Service owns legal_nameOther services consume CustomerUpdated

Avoid two services both “owning” and independently editing the same field.

Derived totals

model · example
WorkOrder.parts_total

If PartUsage rows are authoritative, the total is derived and requires maintenance for every relevant insert, update, delete, reversal, or correction.

Counter drift

  • lost event;
  • duplicate event;
  • manual database update;
  • migration that bypasses normal logic;
  • failed consumer;
  • out-of-order event.

Reconciliation query

sql · example
SELECT wo.work_order_idFROM work_order woWHERE wo.parts_total <> (  SELECT COALESCE(SUM(quantity * charged_unit_price), 0)  FROM part_usage pu  WHERE pu.work_order_id = wo.work_order_id);

A reconciliation path turns hidden drift into detectable drift.

Copying identifiers

Stable identifiers such as tenant_id or customer_id are frequently copied into projections for efficient filtering. Their ownership still needs to be documented, especially if the identifier can be reassigned or scoped.

Copying reference labels

Status display names may change. Decide whether a projection should show the latest label or preserve the label as it appeared historically.

All write paths matter

Synchronization must account for API commands, admin tools, imports, migrations, support scripts, and repair jobs. A denormalized design is only as reliable as its least-governed write path.

WorkshopHub duplication registry

ValueOwnerRefresh
Projection.customer_nameCustomerCustomerUpdated
Invoice customer snapshotInvoice eventNever
WorkOrder.parts_totalPartUsage setTransactional or async aggregate
Search status labelStatus referenceReindex/update

Practice: define ownership

Asset display name

Asset has a calculated display name copied into a search index. What should be documented?

Review answer

Authoritative source fields, calculation rule, update trigger/event, freshness target, idempotency/version behavior, reconciliation method, rebuild procedure, and the rule that the search copy is not independently editable.

Summary and next lesson

Safe duplication requires one authoritative owner, explicit temporal meaning, and deterministic synchronization. Current copies refresh; historical snapshots often do not. The next lesson applies these principles to aggregated structures such as summary tables and materialized views.

References

  • Martin Kleppmann, Designing Data-Intensive Applications.
  • Pat Helland, writings on data ownership and distributed systems.
  • Martin Fowler, material on CQRS and event-driven projections.

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only assets compatible with the Ethereum/ERC-20 network. Do not send TRC-20/TRON assets.