Data Engineering  /  Data Modeling

๐Ÿงฑ Data Modeling 20 guides ยท updated 2026

From ER diagrams to data mesh โ€” relational, dimensional, NoSQL, and governance-driven modeling for building data platforms people can trust.

Analytical Data Modeling: Star Schemas, Facts, and Dimensions for BI That Works

A schema that is perfect for running an application is usually terrible for analyzing one. The normalized model that keeps your transactions clean forces analysts to write ten-table joins for a simple revenue-by-region chart โ€” and when every dashboard query reinvents those joins, every dashboard finds a different number. Analytical data modeling (also called dimensional modeling) solves this by reorganizing data around one goal: making business questions easy and consistent to answer.

This post is for data engineers and analysts building a warehouse or BI layer. It covers the star schema, the concept of grain, dimension design, and the classic problem of slowly changing dimensions.

Why OLTP Models Fail at Analytics

Transactional (OLTP) schemas optimize for many small writes: insert an order, update a status, one row at a time. Analytical (OLAP) workloads are the opposite โ€” few writes, massive reads: โ€œsum revenue across 50 million orders, grouped by month and product category.โ€

Run that against a normalized schema and you join orders โ†’ order_items โ†’ products โ†’ categories โ†’ customers โ†’ regions, six tables deep, and every analyst on the team writes that join slightly differently. Dimensional modeling, popularized by Ralph Kimball in the 1990s, restructures the data so the join logic is decided once, by the modeler โ€” not nightly, by whoever is writing SQL at 6 p.m.

The Star Schema: Facts and Dimensions

A star schema has two kinds of tables:

Fact tables record measurements of business events โ€” a sale happened, a payment cleared, a shipment left. Facts are narrow but enormously long: mostly numeric measures (amount, quantity) plus foreign keys to dimensions. They grow forever.

Dimension tables hold the descriptive context โ€” who, what, where, when. A product dimension carries name, brand, category, size. Dimensions are wide but comparatively short, and theyโ€™re where humans filter and group.

dim_date

date, month, quarter,

fiscal_year, is_holiday

fact_sales

date_key, product_key,

store_key, customer_key,

quantity, net_amount

dim_product

name, brand,

category, size

dim_store

store, city,

region, format

dim_customer

name, segment,

signup_channel

Every business question now follows one shape: filter and group by dimension attributes, aggregate fact measures. โ€œRevenue by brand by quarterโ€ is one join from fact_sales to dim_product and dim_date. The star is deliberately denormalized โ€” dim_product repeats the category name on every product row โ€” and thatโ€™s fine, because dimensions are small, rebuilt by pipelines, and read a million times more often than theyโ€™re written.

Grain: The Most Important Decision Youโ€™ll Make

The grain is the answer to โ€œwhat does one row of the fact table represent?โ€ โ€” one order line? one order? one daily store total? Everything else in the design flows from this answer, and getting it wrong is nearly impossible to patch later.

The rule from decades of practice: declare the grain first, and choose the finest grain the source data supports. For retail sales, thatโ€™s one row per product per order line. You can always aggregate a fine grain up to daily totals; you can never disaggregate a daily total back into transactions when someone asks โ€œwhat time of day do we sell the most coffee?โ€

Two mistakes to guard against:

Designing Dimensions Analysts Actually Enjoy

Good dimensions are what make a warehouse feel effortless. Practices that pay off:

Flatten hierarchies in. Put category and department directly on dim_product rather than making analysts join through a snowflaked chain of lookup tables. (The โ€œsnowflake schemaโ€ โ€” normalizing dimensions โ€” saves trivial storage and costs real usability; Kimballโ€™s advice to avoid it has aged well.)

Use surrogate keys. Dimension rows get warehouse-generated integer keys, not source-system IDs. This insulates the warehouse from source-system key reuse and โ€” critically โ€” makes dimension history possible, as weโ€™ll see below.

Build a real date dimension. A dim_date table with one row per calendar day, carrying month, quarter, fiscal period, week number, and holiday flags, turns painful date math into simple filters. Itโ€™s the single highest-value table in any warehouse and takes an hour to generate.

Spell values out. status = 'Returned' beats status = 3. Storage is cheap; every decoded lookup an analyst doesnโ€™t need is a small gift.

Slowly Changing Dimensions: Handling History Honestly

Hereโ€™s the classic trap. A customer lives in Pune and places 50 orders. She moves to Mumbai. If you simply overwrite city on her dimension row, all 50 historical orders now report as Mumbai revenue โ€” youโ€™ve silently rewritten history, and last yearโ€™s regional report no longer reproduces.

The industry patterns are numbered as SCD types:

Type 2 is where surrogate keys earn their keep: the same real-world customer legitimately has multiple rows, distinguished by validity dates, and the fact tableโ€™s foreign key pins each event to the version that was true at the time.

Decide the SCD treatment per attribute, with the business: โ€œIf a customer changes segment, should last yearโ€™s numbers move with them or stay put?โ€ is a policy question wearing a technical costume.

A Worked Grain Exercise

Suppose the business asks for: daily revenue by store, top products by margin, and repeat-purchase rate by signup channel. Working backwards:

  1. Repeat-purchase analysis needs customer identity per transaction โ†’ grain must be transaction-level, not daily aggregate.
  2. Margin by product needs cost and price per line โ†’ grain is the order line, with quantity, net_amount, and cost_amount as measures.
  3. Dimensions needed: date, product, store, customer (with signup channel โ€” Type 2 if channels get reclassified).

Ten minutes of working backwards from questions just prevented a month of remodeling. Make this exercise a habit: collect the questions before you design the schema.

Practical Guidance

Dimensional modeling has survived thirty years of platform churn โ€” from on-prem Oracle to Snowflake and BigQuery โ€” because it models something more stable than technology: the shape of business questions. Later in this series weโ€™ll see how cloud warehouses bend some old rules (wide tables get cheaper, storage stops mattering) while the core ideas of grain, facts, and conformed dimensions remain exactly as load-bearing as ever.