Star schemas win on performance
Power BI implementations scale to billions of rows when built on star schema foundations: one central fact table (sales, transactions) connecting directly to dimension tables (customers, products, dates). The pattern works because it's simple—fewer joins, clearer query paths, faster aggregations.
Snowflake schemas—where dimensions branch into normalized sub-tables—reduce data redundancy but add query complexity. For most enterprise use cases, the storage savings don't justify the performance hit. Power BI's columnar engine compresses data well enough that normalization beyond the star pattern rarely pays off.
What actually matters in production
Fact tables hold measurable data (revenue, quantity) with integer foreign keys pointing to dimensions. Dimension tables provide context (product names, customer segments, geographic hierarchies). Connect them through one-to-many relationships using those integer keys—not text, not composite keys.
Many-to-many relationships appear in requirements regularly (students-to-courses, products-to-campaigns) but cause ambiguity in aggregations and cross-filtering. The workaround: bridge tables that decompose the many-to-many into two one-to-many relationships. More tables, yes, but predictable query behavior.
Slowly changing dimensions (tracking historical changes to dimension attributes) add another layer. Type 2 SCDs—creating new dimension rows for each change—preserve history but bloat dimension tables. Type 3 SCDs—adding columns for current and previous values—limit history but keep dimensions lean. The choice depends on whether you need full audit trails or just point-in-time comparisons.
The performance traps
Bi-directional cross-filtering sounds convenient for ad-hoc exploration but creates calculation ambiguity. Single-direction filters keep aggregation logic clear. Calculated columns in fact tables with millions of rows consume memory and slow refreshes—push calculations upstream to your data warehouse when possible.
Date tables remain non-negotiable for time-intelligence functions. Hiding unnecessary columns and foreign keys reduces model surface area. Using web-based sources (Databricks, Azure SQL) over local files enables incremental refresh and partitioning.
Why this still matters
Power BI holds roughly 20-25% of the enterprise BI market. Teams still deploy models that violate these basics—usually because developers come from application backgrounds where normalized schemas make sense. In analytical workloads, denormalization wins.
The pattern hasn't changed: star schema, integer keys, one-to-many relationships, minimal DAX complexity. What's changed is scale—implementations now routinely handle datasets that would have required OLAP cubes a decade ago. The fundamentals still hold.