Retail¶
An omnichannel retail warehouse — customers, orders, returns, loyalty. Customers shop across physical stores and digital channels; loyalty tier evolves via SCD2; orders are variable-grain with child line items (parent/child); returns reference prior orders (cross-fact FK); promotions are eligible per-customer via an M:N bridge. Multi-locale faker output reflects international operations. Q4 holiday, summer slowdown, January dip drive the seasonal channel.
What it produces¶
| Table | Type | Grain | Rows (default) | Notes |
|---|---|---|---|---|
dim_date |
dim | per_period | 24 | 24 monthly periods, Jan 2023 – Dec 2024 |
dim_customer |
dim | per_entity (+ SCD2 + geo) | 100–400 | 100 customers, expanded by SCD2 loyalty-tier moves |
dim_product |
dim | per_reference | 8 | widget, gadget, gizmo, ..., whatsit |
dim_promotion |
dim | per_reference | 10 | seasonal_sale, bogo, clearance, ..., first_order_discount |
fct_customer_activity |
fact | per_entity_per_period | 2,400 | six metrics + per-segment review narrative |
fct_orders |
fact | variable (proportional, CDC) | ~order_vol×1.2 | one row per order; CDC for refund processing |
fct_order_items |
fact | per_parent_row | 1–5× parent | child items per order |
fct_returns |
fact | variable (proportional) | ~0.6× return_rate | cross-fact FK to fct_orders |
evt_session |
event | variable (proportional) | ~25,000 | scaled 12× conversion_rate |
evt_return |
event | variable (proportional) | ~400–800 | scaled 2× return_rate |
bridge_customer_promotion |
bridge | static M:N | 100–400 | each customer eligible for 1–4 promotions |
100 entities across six segments: loyal_repeat (22),
holiday_shopper (18), bargain_hunter (22), churning (16),
new_customer (14), vip (8).
Features exercised¶
- Multi-locale faker —
locale: [en_US, en_GB, fr_FR, de_DE]. Customer names, emails, and faker-driven columns rotate across the four locales. - Noise preset —
slightly_messy(sigma 0.03, outliers 0.01, MCAR 0.005). - Seasonality — Q4 holiday lift Nov–Dec (+0.45), summer slowdown Jun–Aug (-0.10), post-holiday January dip (-0.25).
- Correlations —
order_volume driven_by loyalty_score,cart_value related conversion_rate, plus explicitloyalty_score 0.55 repeat_purchase_rate,nps 0.55 loyalty_score,return_rate opposes loyalty_score. - SCD2 —
loyalty_tierondim_customertrackingloyalty_scorewith thresholds[0.25, 0.55, 0.80](bronze / silver / gold / platinum). - Parent / child + cross-fact FK —
fct_ordersis variable-grain driven byorder_volume;fct_order_itemsisper_parent_row(1–5 items per order);fct_returnsreferences orders viaref.fct_orderscross-fact FK and is driven byreturn_rate. - CDC —
fct_orderscarries audit columns for refund-processing amendments. - Bridge —
bridge_customer_promotion(M:N), trajectory-driven byloyalty_scoreso loyal customers are eligible for more promotions. - Geo bundle —
home_country,home_country_code,home_region,home_cityondim_customer. - Narrative column —
review_textonfct_customer_activitywith per-segment lexicons. - Pool-driven columns —
payment_method,order_channel,return_reasonarepool.<attr>columns sourcing from the segment's attribute lists. - Multi-phase archetypes —
flat > decline @ 10,flat > growth @ 4, plusseasonalandaccelerating. - Lifecycle stages —
browser/first_purchase/returning/loyalonloyalty_score. - Quality injection — null injection on conversion_rate (3%), duplicate rows on sessions (1.5%), late arrivals on orders (2%).
Use it¶
Common customizations¶
Switch to a single locale¶
Default rotates across four locales. To produce all-US data:
Increase the line-item fan-out¶
Default is 1–5 items per order. Bump to 1–12 for high-volume warehouse modeling:
Add a struct column for device info on sessions¶
Native nested cells survive Parquet and JSONL writes:
events=[
{
"name": "evt_session",
"trigger": "proportional",
"driver": "conversion_rate",
"scale": 12.0,
"columns": [
{"name": "event_id", "type": "id"},
{"name": "date_key", "type": "ref.dim_date"},
{"name": "customer_id", "type": "ref.dim_customer"},
{"name": "event_ts", "type": "timestamp"},
{
"name": "device",
"type": "struct",
"nested_schema": {"os": "string", "version": "string", "screen_height": "int"},
},
],
},
]
events:
- name: evt_session
trigger: proportional
driver: conversion_rate
scale: 12.0
columns:
- { name: event_id, type: id }
- { name: date_key, type: ref.dim_date }
- { name: customer_id, type: ref.dim_customer }
- { name: event_ts, type: timestamp }
- name: device
type: struct
nested_schema:
os: string
version: string
screen_height: int
Then change output.format to parquet or jsonl to preserve the
nested cells natively.
Where it shines¶
- E-commerce schema teaching — the order / order_item parent/child
relationship plus the
fct_returnscross-fact FK is the canonical retail star pattern; students join across three fact tables with different grains. - Promotion-attribution exercises —
bridge_customer_promotionplusdim_promotion'spromo_typeanddiscount_bandcolumns let students practice promotion-eligibility joins. - Loyalty-program SCD2 —
loyalty_tierversioning produces a textbook SCD Type 2 pattern withdim_row_idresolution on facts that FK into the dim.