How to Build a Kimball Star Schema

A Kimball star schema models analytics data as one fact table (the measurements) surrounded by dimension tables (the context), joined on surrogate keys. It's why reporting queries are fast. Here's how to build one.

Data Engineerdimensional-modelingkimballstar-schema

Why a star schema

Reporting against raw, normalized tables means every dashboard joins many tables and runs slow. A star schema reshapes the data for reads: a central fact table of measurements, surrounded by dimension tables of descriptive context. Queries become a few predictable joins from the fact out to the dimensions - hence "star."

The two table types

Surrogate keys

Dimensions get a surrogate key - a synthetic id, independent of the source system's natural key. It decouples the warehouse from source changes and supports slowly-changing dimensions later.

-- dim_customers
SELECT
    md5(id::text) AS customer_sk,   -- surrogate key
    id            AS customer_id,   -- natural key, kept for lineage
    name          AS customer_name,
    email
FROM {{ source('raw', 'customers') }}

The fact table

Pick the grain first, then join each dimension to get its surrogate key and keep the measures:

-- fct_order_lines (grain: one row per order line)
SELECT
    md5(ol.id::text)        AS order_line_sk,
    c.customer_sk,                       -- FK to dim_customers
    p.product_sk,                        -- FK to dim_products
    d.date_sk,                           -- FK to dim_date
    ol.quantity,                         -- measure
    ol.quantity * p.price   AS line_total  -- measure
FROM {{ source('raw', 'order_lines') }} ol
JOIN dim_customers c ON c.customer_id = ol.customer_id
JOIN dim_products  p ON p.product_id  = ol.product_id
JOIN dim_date      d ON d.date_day    = ol.ordered_on::date

The rules that keep it clean

Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.

Try it in a workspace →

What you'll practice

FAQ

What is a Kimball star schema?

A dimensional model with one central fact table (measurements at a fixed grain) surrounded by dimension tables (descriptive context), joined on surrogate keys - shaped for fast, simple reporting queries.

What's the difference between a fact and a dimension table?

A fact table holds the events/measurements (numeric measures + foreign keys) at one grain; dimension tables hold the descriptive 'who/what/when' you filter and group by, one row per entity.

Why use surrogate keys in a star schema?

A synthetic key decouples the warehouse from source-system natural keys (which can change or collide) and enables slowly-changing-dimension history later. Keep the natural key as an attribute for lineage.

Keep learning

Make an ETL Pipeline IdempotentData projectSpeed Up a Slow SQL Report QueryData projectMake a CSV Importer Resilient to Bad DataData projectData roadmapStep by step to hiredData interview questionsSTAR answersAll Data projectsProjects hub

Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.

Open the workspace →