# Retail star schema

A dimensional model you can actually practise joins on: one fact table and four
dimensions, 63,170 rows, free and public domain.

Every commodity mock-data generator hands you one flat CSV. A flat file has no
joins, which makes it useless for the exact skill most people downloading
practice data are trying to learn.

## The model

    dim_date (730) ─┐
    dim_product (400) ─┼──> fact_sales (60,000)
    dim_customer (2,000) ─┤
    dim_store (40) ─┘

## What holds, and how it was checked

Measured with DuckDB against these exact files, which shares no code with the
generator. Full output in `INTEGRITY.txt`.

- **Zero orphaned rows** on all four joins.
- **Zero duplicate keys** in any dimension.
- **Category share of revenue lands exactly**: Electronics 42.00%, Home 26.00%,
  Apparel 20.00%, Grocery 12.00%.
- **Monthly revenue lands exactly** on a declared two-year curve: 820,000 in
  January 2024, 1,150,000 in December 2024, 1,480,000 in December 2025.

That last pair is the point. Your `GROUP BY` has an answer that is known to be
right, so you can check your own SQL rather than eyeballing whether it looks
plausible.

## Things to try

- Revenue by category and region, joining the fact table to two dimensions.
- Month-over-month growth, which should trace the declared curve.
- A cohort chart from `dim_customer.segment` and `dim_date`.
- Deliberately write the join wrong and watch the totals stop matching.

## Make your own

    pip install misata
    misata generate --config schema.yaml --output-dir ./out

`schema.yaml` is the entire specification. Change the row counts, the date
range, the category mix or the revenue curve, and regenerate. The joins stay
intact and the totals stay exact, because they are solved for rather than
sampled.

## Provenance

Generated by [Misata](https://github.com/rasinmuhammed/misata) (MIT). No real
customer, product, store or transaction exists here, and nothing was sampled
from a real dataset, so there is no personal or proprietary information in it.

Public domain (CC0). No signup, no attribution required.
