Section 5: Furniture to Fit the Contents - Data Modeling
Executive Summary: This section designs the record that stores a user's color and conducts the full storage deliberation: relational, in-memory, and managed key-value/document contenders are each steel-manned, then measured against the requirements of Sections 2 and 3, producing a justified selection with a comparison verdict table. We field-by-field justify a ~300-byte record, wire the conditional-write mechanism that backs Section 4's concurrency contract, walk the record's lifecycle, and price the entire storage layer. The section closes with the extensibility doors deliberately left unlocked for Section 10.
The interviewer taps the whiteboard where your API contract ends: "And underneath — what's the schema, and where does it live?" Most candidates answer the second question first, and answer it by reflex: relational, because it's familiar. The Staff-level order is inverted and non-negotiable — access patterns first, then the record's shape, then the store. So begin where Section 4 left the evidence. The entire storage workload is:
- Fetch one record by user ID — the
GETpath. - Replace one record by user ID, optionally guarded by a version — the
PUTpath.
No joins. No range scans. No secondary lookups. No cross-user queries of any kind — even a future "most popular colors" analytics job would read an export, never the live table. Two operations, one key. Hold that workload in mind; it is about to make the storage decision for us.
The Record: Three Hundred Bytes, Every Field Under Oath
{
"userId": "auth0|64f1c2...",
"color": "#2E8B57",
"format": "hex",
"createdAt": "2026-08-11T09:14:02Z",
"updatedAt": "2026-08-18T14:03:21Z",
"version": 8
}
- userId: The partition key — taken verbatim from the verified token, never from client input. The drawer label that makes every lookup O(1).
- color: The seven bytes the entire service exists to protect.
- format: Looks redundant — Section 1 standardized on HEX. It is a schema escape hatch: when RGBA or HSL arrives someday, it changes a field value instead of forcing a migration.
- createdAt / updatedAt: Fifty bytes that answer the support tickets you will actually receive ("since when has it been green?") and power Section 9's debugging scenario.
- version: The integer behind Section 4's
ETag— incremented on every write, compared on every conditional write.
Critical Insight: Resist decorating this record. The instinct to stash user-agent strings and IP addresses in a metadata blob converts a trivial preference into personal data with GDPR obligations. Store what the feature needs; put forensics in logs, with a retention policy, where forensics belong. Data minimization is an architectural decision, not a legal afterthought.
Sign in to continue reading
The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.
Sign in to read the full lesson