Star schema, filter flow, and building models that work.
Model Architecture Series
Scroll to explore
Why Model Data?
Three reasons a well-designed model changes everything
Deduplication
Store each value once. "Minerals" appears in one dimension row, not repeated across thousands of transactions.
Performance
Smaller model size, faster refresh, better compression. The engine thrives on narrow, typed columns with low cardinality.
Filter Propagation
Relationships create automatic filter paths. Select a category in a slicer, and every measure recalculates instantly.
Dimensions & Facts
The two types of tables that make up every model
Imagine one giant flat table with every column crammed together. It works, but look at all the duplication:
CargoName
Class
Origin
Cycle
Quarter
MerchantName
Sector
Units
Credits
Stardust Ore
Minerals
Titan
2224
Q1
Apex Corp
Core
150
₵450,000
Stardust Ore
Minerals
Titan
2225
Q1
Apex Corp
Core
180
₵540,000
Stardust Ore
Minerals
Titan
2226
Q2
Nova Ltd
Rim
200
₵600,000
Plasma Crystals
Minerals
Andara
2224
Q3
Apex Corp
Core
200
₵600,000
Nav Beacon
Tech
Polar
2225
Q2
Zenith Co
Mid
600
₵30,000
Void Silk
Textiles
Verdant
2225
Q4
Nova Ltd
Rim
350
₵52,500
Stardust Ore
Minerals
Titan
2225
Q2
Zenith Co
Mid
160
₵480,000
Nebula Thread
Textiles
Titan
2226
Q3
Apex Corp
Core
300
₵45,000
Repeated values that could be stored once
The solution: Separate your data into dimension tables (the "who, what, when, where") and fact tables (the numeric events). Dimensions hold unique descriptive rows. Facts hold the transactions, linked by keys. This eliminates redundancy and creates the filter paths your measures depend on.
This is a star schema. Dimensions radiate outward like spokes from the fact table hub, connected by one-to-many relationships (1 dimension row to * many fact rows):
Dimension
Cargo
CargoKey (PK)
CargoName
Class
Value
Dimension
Stardate
StardateKey (PK)
Cycle
Quarter
Month
Dimension
Merchants
MerchantKey (PK)
MerchantName
Sector
Segment
Fact Table
Trades
TradeKey (PK)
CargoKey (FK)
StardateKey (FK)
MerchantKey (FK)
Units
TradeTotal
Filter Flow
See how filters propagate through the star schema in real time
This is what star schema enables. When someone selects "Minerals" in a slicer, the filter hits the Cargo dimension first, then flows down the relationship into the Trades fact table. Only matching rows survive. Try it yourself:
Cargo Class
Cycle
Cargo (Dimension)
Stardate (Dimension)
Trades (Fact)
Rows in Context
20 / 20
filtered rows
Total Units
4,500
SUM( Trades[Units] )
Total Revenue
$4,972,000
SUM( Trades[Credits] )
Star vs Snowflake
Two schemas, one clear winner for Power BI
Star Schema
Cargo
Stardate
Merchants
↓ ↓ ↓
Trades
Recommended for Power BI
VS
Snowflake Schema
CargoClass
↓
Cargo
CycleYear
↓
Stardate
Merchants
↓ ↓ ↓
Trades
Avoid in Power BI
Query Performance
Single join per dimension. Engine optimized for this pattern.
Multiple chained joins. More work for the engine.
DirectQuery Support
Fewer joins means faster live queries to the source.
Each extra join compounds latency in DirectQuery mode.
DAX Simplicity
Measures stay short. Every dimension attribute is one RELATED() away.
Longer formulas, extra variables, and helper tables just to reference a normalized column.
Self-Service Usability
Flat dimensions are intuitive. Users browse and filter naturally.
Normalized tables confuse business users looking for fields.
Analytic Queries
Every visual in Power BI generates a query with three ingredients
Filter
Narrow the data. Slicers, page filters, report filters, and row-level security all restrict which rows participate.
Group
Split the remaining data into groups. Fields on rows, columns, or axes define the granularity of the result.
Summarize
Aggregate each group. SUM, AVERAGE, COUNT, or any measure expression evaluates once per group.
Where Do These Filters Come From?
Click any element in the report below, or any source chip, to see how they connect:
Filter
Group
Summarize
Power BI Report
Cycle ▾
2224
2225
2226
Origin ▾
All ▾
Class ▾
All ▾
Cargo
Stardust Ore
Plasma Crystals
Void Silk
Table Visual
Cargo
Origin
Class
Units
Revenue
Stardust Ore
Titan
Minerals
340
$1.0M
Plasma Crystals
Andara
Minerals
220
$661K
Nav Beacon
Polar
Tech
600
$30.8K
Cryo Flask
Cobalt
Tech
400
$20.4K
Void Silk
Verdant
Textiles
350
$52.8K
Nebula Thread
Titan
Textiles
250
$37.8K
Revenue by Cargo
+62%$1.0M
Stardust
-41%$661K
Plasma
+78%$52.8K
Void S.
+33%$37.8K
Nebula
-67%$30.8K
Nav B.
+80%$20.4K
Cryo
Total Revenue
$1.8M
12.4% vs Prior Cycle
MAMJJASONDJF
Avg per Cargo
$303.8K
8.2% vs Prior
MAMJJASONDJF
Cargo Count
6
3.4% vs Prior
MAMJJASONDJF
Filters
Filters on this visual
Cargo is not blank
Filters on this page
Class = Minerals
Filters on all pages
Cycle >= 2224
Click to Explore
Click any element in the report above, or any source chip, to see how they connect.
The takeaway: Every visual you see in Power BI is the result of an analytic query that filters, groups, and summarizes your model. A clean star schema makes these queries fast, predictable, and easy to extend with DAX.
Intuitive Fields List
A model should be business-friendly, not just technically correct
Fields (Before)
dim_cargo
cargo_key
cargo_name_text
cls_cd
fct_trades_data
cgo_key_fk
trade_amount_sum
unit_cnt
Confusing for users
VS
Fields (After)
Metrics
Base Measures
Total Revenue
Total Units
Cargo
Cargo Name
Class
Origin
Self-service ready
Friendly Names
Remove prefixes (dim_, fct_), abbreviations, and underscores. Use plain business language: "Cargo Name" not "cargo_name_text".
Display Folders
Group measures into folders (e.g., "Measures", "KPIs", "Time Intelligence") so users can find what they need without scrolling.
Hide Technical Columns
Keys, foreign keys, and sort columns should be hidden from the report view. Users should never see "CargoKey" or "SortOrder".
Descriptions
Add descriptions to measures and key columns. They appear as tooltips in the fields list, helping users understand what each field means.
Need help designing your star schema or optimizing your semantic model?
We help teams build clean, performant data models from the ground up. Star schemas, naming conventions, measure architecture, and everything covered in this guide.
**On screen:** Title slide with "Modeling Fundamentals"
- This is a quick refresher on the foundations. Everything that follows in the workshop builds on these concepts.
- If you already work with star schemas daily, think of this as a vocabulary alignment.
*Transition: "Let's start with why we bother modeling at all."*
**On screen:** Deduplication card
- One row per cargo item instead of thousands of repeated strings. Less storage, better compression.
**On screen:** Filter Propagation card
- The real payoff. Relationships create the automatic filter paths that make your measures work without extra code.
*Transition: "So what do these separated tables actually look like?"*
**On screen:** Flat table with duplicate values highlighted in red
- Point out the repeated "Stardust Ore / Minerals / Titan" rows. Every transaction carries the full cargo description.
- Ask: "How many unique cargo items are there?" (6). "How many times does 'Minerals' appear?" (4 times in just 8 rows).
*Transition: "Now watch what happens when we separate this."*
**On screen:** The Solution callout
- Separate your data into dimension tables (who, what, when, where) and fact tables (numeric events). Dimensions hold unique descriptive rows. Facts hold transactions, linked by keys.
**On screen:** Star schema diagram with animated arrows
- Hub and spokes. Fact table in the center, dimensions radiating out.
- One-to-many relationships: one Cargo row matches many Trades rows.
- The dashed arrows show the direction filters flow: from dimension down to fact.
*Transition: "Let's see that filter flow in action."*
**On screen:** Interactive filter flow demo with clickable slicers
- Click "Minerals" in Cargo Class. Watch how the Cargo dimension grays out non-mineral rows, then the Trades fact table follows suit.
- Click "2225" in Cycle. Now both filters apply simultaneously.
- Point out the metric cards updating in real time. The formula never changes; the context does.
*Transition: "This pattern is called a star schema. There's another option called snowflake. Let's compare."*
**On screen:** Side-by-side star vs snowflake diagrams
- Star: flat dimensions, one join per dimension. Simple and fast.
- Snowflake: normalized dimensions with sub-tables. More joins, more complexity.
- For Power BI specifically, star schema wins on every axis we're about to cover.
*Transition: "Let me show you the four reasons why."*
**On screen:** Query Performance card
- Single join per dimension means the engine scans fewer paths. Star schema is what VertiPaq was built for.
**On screen:** DirectQuery Support card
- Every extra join in a snowflake becomes a round-trip to the source. Star keeps it minimal.
**On screen:** DAX Simplicity card
- RELATED() crosses one relationship in a star. In a snowflake, you need workarounds or bridging tables.
**On screen:** Self-Service Usability card
- Business users see flat, intuitive dimension tables. No confusion about which normalized sub-table has their field.
*Transition: "Now let's see what happens on the report side."*
**On screen:** Section header: "Analytic Queries"
- Every visual in Power BI generates a DAX query. Three ingredients, every time.
**On screen:** Filter card
- Slicers, page filters, report filters, RLS. All of these narrow which rows participate before anything else happens.
**On screen:** Group card
- Fields on rows, columns, or axes split data into buckets. Each bucket is a group.
**On screen:** Summarize card
- Measures aggregate each group: SUM, AVERAGE, COUNT, or any DAX expression evaluates once per group.
**On screen:** Interactive PBI wireframe
- Click the slicer to see which chip lights up. Click the table to see grouping highlighted.
- The filter pane connects to the Filter chip. KPI cards show summarization.
- Reinforce: every element you see is a source of automatic filtering, grouping, or summarization.
**On screen:** The Takeaway callout
- Every visual is an analytic query: filter, group, summarize. A clean star schema makes these queries fast, predictable, and easy to extend with DAX.
*Transition: "Last piece: making your model user-friendly."*
**On screen:** Friendly Names card
- Remove prefixes, abbreviations, underscores. "Cargo Name" not "cargo_name_text". Plain business language.
**On screen:** Display Folders card
- Group measures into logical folders. Users can find what they need without scrolling through a flat list.
**On screen:** Hide Technical Columns card
- Keys, foreign keys, sort columns. Users should never see "CargoKey". Hide anything they don't need.
**On screen:** Descriptions card
- Add descriptions to measures and key columns. They appear as tooltips in the fields list.
**On screen:** CTA card linking to DAX Foundations
- Wrap up: you now have the modeling vocabulary. Star schema, dimensions, facts, filter propagation, analytic queries.
- Everything we do next (calculation groups, field parameters, RLS) builds on this foundation.
Discussion