</> MAANG.io
system design · 301

Advanced

Master system design interviews with scalable architecture patterns, distributed systems, and real-world design challenges.

0/480 solved 0% complete

Section 5: The Pantry, the Recipe Card, and the Receipt - Data Modeling

Executive Summary: This section builds the schema that the rest of the design merely operates: ingredients as the atomic entity (D1), recipes as priced compositions with the required-vs-default distinction that makes the 86 cascade computable (D7), immutable published menu versions (D4/D6), the one-row-per-86 availability overlay that is the inventory model (D8), and orders whose lines carry both the delta (intent) and the resolved, priced snapshot (the receipt) in a single row (D2/D4). We write DDL for the four tables where the shape is the argument, run order #1042 and Marco's 12:35 avocado 86 through it, and defend the two choices interviewers always probe: the JSONB snapshot inside a relational order, and the inventory table that deliberately does not exist.

The interviewer caps the API discussion with the question this topic was always heading toward: "Show me the tables." Here is where Section 1's bet — that the ingredient, not the salad, is the atomic entity — either pays out or collapses. The Staff-level move is to let the access patterns from Sections 3 and 4 shape the schema before any CREATE TABLE is typed: menus are read as versioned documents from a CDN, availability changes one bit at a time on a human's clock, orders are written once inside a transaction and reread as receipts forever. Three different rhythms; the schema must honor all three without letting any one of them contaminate the others.

The Pantry: ingredients

CREATE TABLE ingredients (
    id           TEXT PRIMARY KEY,            -- 'avocado'
    name         TEXT NOT NULL,               -- 'Avocado'
    category     TEXT NOT NULL,               -- base | protein | cheese | crunch | fruit_veg | premium | dressing | extras
    price_cents  INTEGER NOT NULL,            -- 200: what an *add* costs; money is integers, never floats
    nutrition    JSONB NOT NULL,              -- {"calories": 234, "fat_g": 21, ...}
    allergens    TEXT[] NOT NULL DEFAULT '{}',-- {'dairy'}, {'tree_nut'} — queryable, not prose
    active       BOOLEAN NOT NULL DEFAULT TRUE
);

Every column earns its place downstream. price_cents is how D3's server-side pricing has something authoritative to compute from. nutrition is JSONB because its shape will grow (sodium today, added sugars after the next labeling law) and nothing ever queries into it at order time — it rolls up. allergens is a real array, not a description string, because Section 7's allergen filter is a query (WHERE NOT allergens && '{tree_nut}'), and a query can be tested; prose cannot. This table is the D1 hill: roughly 60 rows that pricing, availability, nutrition, allergens, and BYO all compute from.

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

Sign in to MAANG.io

Use your Google or Microsoft account — no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.