Key takeaways
- Define the grain of each fact table in one sentence before building anything.
- Keep facts numeric and dimensions descriptive, with stable keys on both sides.
- Use a continuous, marked date table and handle multiple date roles deliberately.
- Validate row counts, totals, and relationship coverage against the source before publishing.
On this page
Start with the grain
The grain is what one row in a fact table represents: one order line, one invoice, one stock movement, or one support ticket. Write it down in a single sentence before opening Power BI. If the sentence needs an 'and', the table probably holds more than one grain.
Grain determines which dimensions are valid and which measures can be summed. Combining order headers and order lines in one table double-counts header-level values such as delivery charges. Keep separate fact tables when the events differ, then relate them through shared dimensions. A header fact can hold delivery charges and discounts once per order, while a line fact holds quantity and line value. Relating both to the same dimensions lets each measure aggregate at its own level without double counting.
Separate facts from dimensions
A fact table holds foreign keys and numeric measures that can be aggregated. A dimension holds the descriptive attributes used to filter and group those measures: customer segment, product category, store region, account owner.
Resist the temptation to put descriptions in the fact table or measures in a dimension. That shortcut makes the model harder to extend and usually produces inconsistent totals. Keep dimensions narrow, conformed, and reusable across facts. A conformed dimension, such as a shared customer or date table, is what allows separate facts to be compared. A degenerate dimension, such as the order number stored on the fact table, is acceptable when it is needed for drill-through.
| Model object | Examples | Rule |
|---|---|---|
| Fact table | Order line, invoice, stock movement, support ticket | One clearly stated grain; foreign keys and additive measures |
| Dimension table | Customer, product, store, account, date | Descriptive attributes and one stable key |
| Conformed dimension | Shared customer or date table | Reused across facts so results can be compared |
| Degenerate dimension | Order number stored on the fact | Used for drill-through when it has no attributes of its own |
Design a date table
Create a dedicated date table with one row per day and no gaps. Add year, quarter, month, month name, week, and an is-working-day flag. Mark it as the date table in Power BI so time intelligence behaves predictably. Do not rely on the date column inside a fact table as the date table; it will miss days with no transactions and break comparisons across periods.
A business often has several dates on one fact table: order date, invoice date, due date, and payment date. One active relationship per date role is the safe default. Use separate role-playing date tables or USERELATIONSHIP in specific measures rather than stacking active relationships between the same tables.
Build clean relationships
Use one-to-many relationships from the dimension side to the fact side, with single-direction filtering. Match data types exactly, hide foreign keys from report users, and give keys stable, meaningless values where possible. Natural keys can be reused or changed by source systems.
Bidirectional filtering is occasionally necessary, but it creates ambiguous filter paths and unexpected totals. Use it only for a defined many-to-many requirement, then test the result carefully. An unknown-member row in each dimension is better than blank keys that silently drop transactions from reports. After building the model, test a matrix with a known total and a filter on every dimension. A blank row or a sudden drop usually points to a missing key or a filter direction problem.
Validate before publishing
Compare the model with the source at the lowest grain and at the totals users will see. Check row counts, duplicate dimension members, unmatched foreign keys, and date coverage. A report that is fast but unexplainable is not finished.
Document the grain, sources, refresh schedule, and owner. Name measures in business language and apply consistent format strings. Remove unused columns, because every column adds size and maintenance, then review the model with someone who will use it. Set a refresh failure notification and record the last successful refresh where users can see it.
- One fact table, one grain, one clearly stated purpose.
- Dimensions filtered in one direction unless a documented exception exists.
- Date table marked, continuous, and mapped to each date role.
- Totals reconciled with the ledger, platform, or source system.
Frequently asked questions
Does a star schema always beat a single flat table?+
No. A flat table can work for a small, simple report with one audience. A star schema becomes more valuable when multiple facts share dimensions, when the model needs to grow, or when consistent filtering and reusable measures matter.
How many dimensions should a fact table have?+
As many as the grain genuinely requires. There is no target number. Avoid adding dimensions for convenience if the attributes belong on an existing dimension or can be derived at query time.
Should dimensions be flattened or snowflaked?+
Flatten dimensions where practical. Snowflaking a large, shared dimension can reduce duplication, but each extra join adds complexity and another place for filter behaviour to go wrong.
How should multiple fact tables be handled?+
Give each fact table its own grain and relate it to shared conformed dimensions. Measure only at the grain of the fact being queried, and avoid combining measures from different facts in one visual unless the aggregation logic is explicitly defined.
Need help applying this?
Improve your bi dashboards & reporting.
Review the service scope or tell us what you are trying to improve. We will reply with a clear next step.
Free KPI definition templateRelated reading
Power BI star schema mistakes to avoid
Common star schema mistakes in Power BI, from mixed grain and bidirectional relationships to missing date tables, with fixes you can apply to an existing model.
Power BI date tables: why they matter
Why a dedicated date table is required for reliable time intelligence in Power BI, how to build one, and how to handle fiscal years and multiple date roles.