You're probably dealing with this already. Stripe says one thing about revenue. HubSpot says something else about customers. Your product database tells a third story about active accounts. Then someone asks a simple question like, “What was churn last month?” and the room turns into a debate about definitions instead of a decision about the business.
That's usually not a dashboard problem. It's a modeling problem.
If you want reliable MRR, believable LTV, and churn numbers that don't change depending on who ran the query, you need a structure that separates what happened from the context around what happened. That's where fact and dimension tables come in. They aren't academic warehouse theory. They're the practical foundation for consistent metrics in a modern SaaS or e-commerce stack, and they matter even more when you want AI systems to answer business questions without making up logic on the fly.
Table of Contents
- Why Your Business Metrics Disagree
- The Anatomy of a Business Question
- Defining the Grain The Most Important Decision
- Real World Schemas for SaaS and E-commerce
- Handling Change and Complexity in Your Model
- From Tables to Trusted Answers with a Semantic Layer
Why Your Business Metrics Disagree
A founder asks for net new MRR. Finance pulls data from Stripe. RevOps checks Salesforce. Product looks at account events in Postgres. Marketing brings in HubSpot lifecycle stages. Everyone uses real data, but they still land on different answers.
That doesn't happen because people are careless. It happens because each system stores the business from its own point of view. Stripe stores charges. Salesforce stores pipeline and accounts. HubSpot stores contacts and campaigns. Your app stores user behavior. None of those systems, by themselves, were designed to be the company's final source of truth for analytics.

The hidden cause of reporting chaos
Most reporting chaos starts with ad hoc joins and local definitions.
A revenue analyst might join invoices to customers by email. A growth manager might define “active customer” from product usage. Finance might define “customer” at the billing account level. All three approaches can be reasonable. They just answer different questions while sounding like the same one.
That's why teams keep relitigating MRR, churn, LTV, CAC payback, and conversion rates. The issue isn't only metric definitions. It's the structure underneath those definitions.
The warehouse needs a business shape
A good analytics warehouse gives business data a stable shape. In dimensional modeling, that shape centers on fact and dimension tables.
- Fact tables record measurable business events or states.
- Dimension tables describe the entities around those facts, such as customer, product, plan, date, or region.
- Together they create a consistent path for slicing and aggregating metrics.
Practical rule: If your team can't say what one row means in the central measurement table, your metrics will drift.
This is why dimensional modeling became the standard pattern for analytics warehouses. It gives analysts readable structures, keeps business meaning visible, and supports consistent reporting logic across tools. When you build on that foundation, your dashboard, board deck, and AI analyst are much more likely to produce the same answer.
The Anatomy of a Business Question
Most business questions sound simple: Which plan drives the most revenue? Which campaign brought in the highest-value customers? Which products churn fastest after a discount?
Underneath each question are two different kinds of data. You need the numbers and you need the context.
A store receipt is a useful analogy. The receipt has line items, quantities, prices, and totals. That's the measurable part. It also tells you who bought, when they bought, where they bought, and maybe how they paid. That's the descriptive part.

Facts are the measurable events
A fact table stores what happened in a form you can aggregate.
In e-commerce, one row might represent an order line. In SaaS, one row might represent a subscription billing event or a monthly account snapshot. Facts usually contain numeric measures such as revenue, quantity, discount amount, seat count, or usage volume.
Think of facts as the answer to this question: What can I add up, count, average, or compare over time?
Examples:
- Order fact: quantity, unit price, total amount
- Subscription fact: recurring revenue amount, status change flag
- Usage fact: event count, session duration, consumed credits
Facts are where your KPI math starts. If this table is wrong, every downstream chart gets shaky.
Dimensions provide the business context
A dimension table answers the surrounding questions. Who was the customer? What product was involved? Which plan, channel, country, or date applied?
Dimensions are descriptive. They hold labels, categories, and attributes that make facts useful to the business. Without dimensions, you can total revenue, but you can't explain revenue by plan, region, customer segment, or signup cohort.
A simple way to remember it:
| Table type | Answers |
|---|---|
| Fact table | What happened, and what was measured |
| Dimension table | Who, what, where, when, and how |
For a SaaS founder, that distinction matters because MRR by itself isn't enough. You want MRR by plan, by acquisition source, by segment, by account owner, and by month. Those breakdowns come from dimensions.
Why this structure became the standard
The core relationship is straightforward. A fact table sits in the center and links to dimensions through foreign keys. Kimball's foundational guidance states that every foreign key in the fact table should match a unique primary key in its related dimension, which is what preserves referential integrity and keeps the model analyzable in a predictable way, as described in the Kimball Group's explanation of fact tables and dimension tables.
That design became the standard for analytics warehouses because it balances query performance with business readability. Analysts can write understandable SQL. BI tools can traverse the relationships. Leaders can ask business questions in plain language without the data team reverse-engineering intent from operational tables.
A good dimensional model makes your data easier to trust because it makes your business logic easier to see.
Defining the Grain The Most Important Decision
If fact and dimension tables are the skeleton of analytics, grain is the rule that keeps the skeleton from bending into nonsense.
Grain means one thing: what exactly does one row in the fact table represent? One invoice line? One subscription per month? One shipment? One support ticket's final status?
Microsoft's Fabric guidance says the grain must be defined before implementation because each fact row should represent an atomic business event or an explicitly chosen snapshot level. The same guidance notes that fact tables can reach billions of rows, and that grain directly drives the tradeoff between precision and performance. If grain is too coarse, you can lose drill-down capability and introduce double counting. If it's too fine, storage and query cost rise quickly, as outlined in Microsoft's dimensional modeling guidance for fact tables.
What grain actually means
Suppose you run a SaaS company. You want to measure MRR.
You have at least three plausible grains:
- One row per invoice line
- One row per subscription change event
- One row per customer per month
Each option is valid for some purpose. Each creates a different style of reporting.
If you choose invoice line grain, finance questions may be easier, but product-led movement inside a billing cycle can be harder to analyze. If you choose monthly customer snapshots, month-end reporting becomes simple, but you may lose detail about upgrades and downgrades that happened during the month.
Fine grain versus coarse grain
Teams frequently run into trouble. They pick a grain because it feels convenient in the moment, then try to stretch it into every dashboard later.
A finer grain gives you more flexibility. You can roll detailed events up into summaries. You can audit edge cases. You can trace a weird MRR jump back to a specific subscription event.
A coarser grain feels easier at first, but it can lock you out of questions you'll care about later.
| Grain choice | Benefit | Risk |
|---|---|---|
| Very fine | Strong drill-down and auditability | Higher storage and query cost |
| Very coarse | Simple reporting and smaller tables | Lost detail and double counting |
| Well chosen | Enough detail for decisions without waste | Requires discipline up front |
For e-commerce, this often shows up when a team stores one row per order instead of one row per order line. That works until someone asks for revenue by product category, bundle behavior, or promotion. For SaaS, it shows up when a team stores only month-end account balances and later wants to analyze upgrade paths within the month.
A practical test before you build
Ask three questions before you create the fact table:
- What business event am I measuring: A purchase, a renewal, a support interaction, a shipment, a login, or a daily account state?
- What decisions will this metric support: Board reporting, pricing analysis, retention work, campaign attribution, or support staffing?
- What mistakes become possible at the wrong grain: Double counting, hidden churn, missing attribution, or inability to explain changes?
If your warehouse model is still fuzzy at this stage, it helps to review a more detailed walkthrough of data modeling in a data warehouse.
Design check: Write the sentence “Each row in this fact table represents…” and force it to be specific. If the sentence sounds vague, the model isn't ready.
Real World Schemas for SaaS and E-commerce
Theory helps. Schemas make it real.
Below are two practical patterns. They aren't the only way to model these businesses, but they show how fact and dimension tables translate into metrics leaders actually care about.

A SaaS model for recurring revenue
For SaaS, start with the metric questions:
- What is current MRR?
- Which plan changes drove expansion or contraction?
- Which customer segments churn fastest?
- How does revenue trend by month and plan?
A clean model often includes a central subscription fact plus supporting dimensions.
Fact table
subscription_fact
Dimensions
customer_dimproduct_dimdate_dimsubscription_status_dim
The fact table might include fields such as subscription identifier, customer key, product key, date key, status key, recurring revenue amount, and a churn-related indicator. The dimensions hold the descriptive context: customer region, plan family, billing interval, status label, and calendar attributes.
A simple mental model is this: the fact tells you that revenue changed. The dimensions tell you whose revenue, on which plan, at what time, and in what state.
A short schema sketch:
| Table | Purpose |
|---|---|
| subscription_fact | Core subscription measures and foreign keys |
| customer_dim | Account attributes such as segment or region |
| product_dim | Plan and package details |
| date_dim | Reporting calendar fields |
| subscription_status_dim | Status labels such as active or canceled |
A short visual reference helps before the SQL details. This walkthrough is useful for teams that want a verbal explanation alongside a schema diagram.
An e-commerce model for orders and promotions
E-commerce has a different heartbeat. The questions are usually about sales mix, discount behavior, customer repeat rate, and product performance.
A solid starting pattern is a sales fact at the order-line level.
Fact table
sales_fact
Dimensions
customer_dimproduct_dimstore_dimdate_dim
You might later add promotion, channel, or fulfillment dimensions depending on your business. The key idea is that one sale event should be measurable without duplicating descriptive attributes into the fact.
This lets you answer questions like:
- Which products sell best by region?
- Do discounts drive more units but lower margin quality?
- Which customer segments buy at full price?
- What's repeat purchase behavior by acquisition cohort?
If you want trustworthy LTV in e-commerce, you need a stable connection between the order facts and the customer dimension. If customer identity is messy, LTV becomes a moving target.
Simple SQL examples
These examples are intentionally minimal. They show the shape, not a full production design.
SaaS subscription model
CREATE TABLE customer_dim (
customer_id BIGINT PRIMARY KEY,
customer_name TEXT,
email TEXT,
region TEXT,
signup_date DATE
);
CREATE TABLE product_dim (
product_id BIGINT PRIMARY KEY,
product_name TEXT,
plan_type TEXT,
price_per_month NUMERIC
);
CREATE TABLE date_dim (
date_id BIGINT PRIMARY KEY,
full_date DATE,
month_name TEXT,
year_num INT
);
CREATE TABLE subscription_status_dim (
status_id BIGINT PRIMARY KEY,
status_name TEXT
);
CREATE TABLE subscription_fact (
subscription_id BIGINT PRIMARY KEY,
customer_id BIGINT,
product_id BIGINT,
date_id BIGINT,
status_id BIGINT,
monthly_recurring_revenue NUMERIC,
churn_flag BOOLEAN
);
E-commerce sales model
CREATE TABLE customer_dim (
customer_id BIGINT PRIMARY KEY,
customer_name TEXT,
email TEXT,
city TEXT,
state TEXT
);
CREATE TABLE product_dim (
product_id BIGINT PRIMARY KEY,
product_name TEXT,
category TEXT,
brand TEXT
);
CREATE TABLE store_dim (
store_id BIGINT PRIMARY KEY,
store_name TEXT,
region TEXT,
manager TEXT
);
CREATE TABLE date_dim (
date_id BIGINT PRIMARY KEY,
full_date DATE,
month_name TEXT,
year_num INT
);
CREATE TABLE sales_fact (
sale_id BIGINT PRIMARY KEY,
customer_id BIGINT,
product_id BIGINT,
store_id BIGINT,
date_id BIGINT,
quantity_sold INT,
unit_price NUMERIC,
total_sale_amount NUMERIC
);
These schemas work because they align business questions with table structure. When the model mirrors how the business thinks, metrics become easier to explain and harder to accidentally corrupt.
Handling Change and Complexity in Your Model
A clean star schema is only the beginning. Real businesses change. Customers move segments. Products get reclassified. Sales reps switch territories. Subscriptions move through lifecycle states. If your model can't absorb those changes without rewriting history by accident, your metrics won't stay trusted for long.

Keys are what make the model trustworthy
At the mechanical level, dimensional models depend on keys.
A primary key uniquely identifies a row in a dimension. A foreign key in the fact table points back to that row. That sounds basic, but it's what keeps your business logic attached to the right context.
If a sales fact points to the wrong customer key, your revenue by segment is wrong. If a subscription fact points to an outdated product record without a clear strategy, plan-level MRR gets fuzzy.
The model is only trustworthy when table relationships are stable, explicit, and enforced through process.
Why slowly changing dimensions affect trust
Such scenarios often make reporting political. A customer changes region. A product moves to a different category. A sales owner changes mid-quarter. Do you overwrite the old value, or preserve the old version and create a new one?
That choice is your slowly changing dimension strategy.
- Type 1 overwrites the old value.
- Type 2 keeps history by adding a new versioned row.
- Type 3 keeps limited prior-state context.
For modern BI and AI-driven analytics, the hard decision is usually between Type 1 and Type 2. The tradeoff isn't academic. Governed semantic layers and metric-aware AI systems depend on historical consistency, and overwriting a customer's attributes can retroactively change past revenue reports. That's why the Type 1 versus Type 2 choice has major downstream effects on auditability, as discussed in this guide to best practices for fact and dimension table design.
Here's the practical difference:
| SCD type | What it does | Business consequence |
|---|---|---|
| Type 1 | Replaces old value with new one | Simpler model, weaker historical fidelity |
| Type 2 | Creates a new row for changed attributes | Stronger audit trail, more join complexity |
A report people trusted last quarter can become untrustworthy this quarter if you overwrite dimension history without meaning to.
This is also where related patterns matter. Conformed dimensions help different fact tables use the same customer or product definition. Junk dimensions can group scattered low-value flags. Degenerate dimensions can hold identifiers that don't deserve a full dimension table. None of these patterns are glamorous, but they often determine whether metrics remain stable across teams and tools.
If your team is formalizing ownership over these decisions, a good companion concept is data contracts, especially when product, finance, and go-to-market teams all depend on the same warehouse definitions.
Choosing the right fact table pattern
Not all facts behave the same way. Kimball distinguishes three patterns because business processes differ in how they unfold over time:
- Transaction fact tables capture discrete events such as orders or invoices.
- Periodic snapshot fact tables store state at regular intervals for trend analysis.
- Accumulating snapshot fact tables track milestones across a lifecycle.
The pattern matters because the wrong one can distort KPIs. If you mix event-level revenue changes with month-end state in the same logic, MRR becomes slippery. If you track a sales pipeline with the wrong pattern, velocity can look better or worse because the table semantics don't match the process.
A simple mapping helps:
- Use transaction facts for purchases, clicks, refunds, and billing events.
- Use periodic snapshots for monthly account state, daily inventory position, or weekly pipeline posture.
- Use accumulating snapshots for processes like onboarding, fulfillment, or claims handling where milestones arrive over time.
From Tables to Trusted Answers with a Semantic Layer
Fact and dimension tables don't create trust by themselves. They create the conditions for trust.
Once your warehouse has a stable dimensional model, you can build a semantic layer on top of it. That layer defines business metrics in shared language. Revenue means the same thing in the board deck, in the product dashboard, in finance reporting, and in the AI interface your team uses to ask questions.
That matters because AI-driven analytics is only as reliable as the structure beneath it. If the warehouse mixes incompatible fact patterns, the semantic layer has to compensate for confusion. If the warehouse is clean, the semantic layer can map metrics consistently and answer plain-English questions without inventing logic.
Ralph Kimball distinguished transaction, periodic snapshot, and accumulating snapshot fact tables because different business processes need different reporting behavior. Using the wrong pattern can distort KPIs like MRR or pipeline velocity by mixing event-level and state-level data, as explained in Holistics' overview of the three types of fact tables.
That's the ultimate payoff. You stop asking, “Why does this dashboard disagree with finance?” and start asking, “What should we do next?”
If you're evaluating how this fits into an outsourced or fractional analytics setup, this overview of business intelligence as a service is a useful next step.
If your SaaS or e-commerce team is tired of arguing over MRR, churn, LTV, or revenue definitions, HelpWithMetrics can help you put the right structure underneath your numbers. They set up governed analytics, semantic layers, and AI-ready reporting inside your own stack so your team gets fast, auditable answers without building a full in-house BI function first.