Skip to the content
Software Made Clear Diagrams that show the mechanism About

Data warehouse design

Choose a warehouse's fact grain, shared dimensions and history rules. Step through a failed reload to see why delete and insert must commit together.

6 min read Updated September 30, 2026 Last verified August 19, 2026
ANSWER

Design a warehouse around the questions and history it must support. Define what each fact row means, how sources share dimensions and how loads handle changes and retries. A star schema is one useful model; it does not dictate storage layout or ingestion timing.

IN PLAIN TERMS

A shop wants last year's sales by product and region. Give each sold item one row and keep the descriptions needed for the report. If a day's load fails after deleting its old rows, undo that deletion too so the report does not quietly lose a day.

A shop wants last year’s sales by product and region. Its order tables record current transactions, but a report also needs an agreed meaning for a sale, the relevant historical region and a way to correct a failed data load. This shop is an illustrative example. Start with those questions before choosing staging tables, reporting tables or a new database product.

The workload is the whole argument#

A checkout changes one order; the annual report combines many orders. OLTP, online transaction processing, names the first workload. OLAP, online analytical processing, names the second. One engine may serve both. The row and column layout example separates query access patterns from the schema decision made here.

AspectTypical operational workloadTypical analytical workload
How data arrivesApplication transactions, which may change several records.Ingestion through scheduled batches, streams or change data capture.
How it is readShort lookups and updates, often found by key.Filters, joins and aggregates over the history a question needs.
What correctness demandsRelated changes commit together and preserve application rules.Agreed measures, the right history and loads that handle failures and retries.
What the model supportsThe application’s writes and lookups.Recurring analytical questions and consistent reporting definitions.

Normalisation reduces duplicated facts and the updates needed to keep copies consistent. It does not make incorrect data impossible or turn every write into one row. The warehouse still receives writes: source records can be late, duplicated or corrected, and dimensions can change. Preparing data for reports moves work into the loading process; it does not remove that work.

Microsoft’s warehouse architecture example includes batch and streaming ingestion, quality checks and prepared analytical layers. Those are options rather than a required vendor stack. A star schema can help express the report, but it neither requires a column store nor guarantees that every query scans most rows.

What you decide before you write any SQL#

For a dimensional model, settle four questions before relying on its reports. They describe the data contract, not a mandatory number of warehouse layers.

01

The grain of each fact table

The grain states what one row represents. For the shop, choose one product line on one receipt. Two line amounts of £40 and £60 total £100; adding their £100 receipt subtotal as another row produces £200. Keep those grains separate. Kimball’s grain rule makes this choice precede dimensions and measures. The star-schema experiment lets you change those rows and inspect the sum.

02

Which dimensions are shared across fact tables

If sales and returns are compared by shop, agree which shop each source record identifies and how its key maps to the shared dimension. Two reports can use the same label while assigning different records to it. Reconcile those mappings and metric definitions; a successful SQL join does not prove their business meaning agrees.

03

What happens when a descriptive value changes

When a shop changes region, should last year’s sales use its current region or the region at sale time? Overwriting the dimension supports current labels. Keeping versions can preserve the earlier label when each fact points to the appropriate version. Late or corrected records still need rules; versioning alone does not freeze every report. Microsoft’s changing-dimension guidance explains the overwrite and versioned approaches.

04

How a load re-runs safely

A load will re-run — a job restarted after a failure, a backfill for a date that arrived late, a full reload once a bug upstream is fixed. An append-only retry can count the same source rows twice. To replace one date safely, prepare the staging input, then delete and insert that date in one transaction. With the same staged rows, a second successful run leaves the same result; a failed transaction must roll back before retrying.

Try it: fail between deleting and replacing one date

Illustrative starting rows: this date has £25; the prepared replacement has £40 and £60. Another date’s £9 stays unchanged. Predict what remains if the insert fails.

Committed rows for this date
£25
Rows seen by the loading session
£25
Prepared staging rows
£40 + £60 = £100

Before the load: £25 is committed. Deleting inside a transaction does not commit the empty date; a later rollback can restore its rows.

With BEGIN and a rollback after the failed insert, the old £25 remains. If DELETE commits separately, the failed insert leaves the date empty. Enable JavaScript to step through those cases.

A simplified single-writer model with fixed staging input, not a database engine. Failure happens before any insert row is added. This does not model isolation levels, concurrent loaders, duplicate staging rows or changing input. Other sessions’ reads depend on the database’s isolation rules.

reload_one_partition.sql
-- Illustrative load: prepare a stable staging batch first.
-- Supply the same bound :run_date_key in both statements.
BEGIN;
DELETE FROM fact_orders
WHERE order_date_key = :run_date_key;

INSERT INTO fact_orders (
  order_date_key, customer_key, product_key, quantity, revenue
)
SELECT
  order_date_key, customer_key, product_key, quantity, revenue
FROM staging_orders
WHERE order_date_key = :run_date_key;
COMMIT;
-- On an error before COMMIT, ROLLBACK the transaction.

The transaction boundary matters as much as the date filter. Without it, a failure after DELETE can leave that date empty. With a rollback, the old rows remain until a complete load commits. This simplified example assumes a stable staging batch and one writer for the date; it does not solve duplicate source rows, concurrent loaders or changing input. PostgreSQL’s transaction guide explains why the two statements must commit together.

Where it goes wrong#

A copy or read replica of the application database can be a useful reporting starting point. It retains the source’s schema, so check whether that schema and its available history answer the question. The database and warehouse comparison explains when reporting isolation is enough and when integrated history is needed.

01

A report becomes slow or competes with checkout

Inspect the query plan, filters, indexes and shared resource use before blaming the schema. Fewer joins can make a report easier to write without making it faster. The index-plan guide gives a concrete scan-versus-index counterexample. Compare representative plans and timings for a proposed analytical model.

02

Two teams compute different sales totals

Check grain, source mappings and inclusion rules. One report may include cancelled orders while another counts only paid lines. Agree the intended measure and test representative records. A dimensional model helps make that agreement explicit; it cannot decide the business rule for the teams.

03

A source change alters reporting inputs

A renamed column can break a query; a new status can change which rows it includes. Version and test the transformation contract, and keep enough permitted input history to investigate corrections. A prepared reporting layer can absorb some source changes, but its loading code also needs maintenance.

Keep the simpler copy if its reports and freshness meet the requirements. Introduce a prepared analytical model when a specific history, integration or reporting problem calls for it. A warehouse label, a star diagram or a successful load does not establish that its metrics are correct.

Optimising for reads at the expense of writes, or the other way round, is not a decision unique to how a warehouse’s tables are modelled — the article on two storage engines built around opposite assumptions about reads and writes covers the same fork one layer down, inside a single engine rather than across a schema. The persistence path is the roadmap this article aligns with most closely.

IF YOU REMEMBER ONE THING

Choose the fact grain, shared meanings, historical rules and retry behaviour for the reports you need. Check the loading process as carefully as the query: a failed insert must not commit an earlier deletion.

Questions people also ask

5 QUESTIONS
What is the difference between a data warehouse and a database?

A database is the broader system that stores and manages data. A warehouse is an analytical system or architecture that integrates data and useful history for reporting. It may use a relational database. OLTP and OLAP describe transactional and analytical workloads, not two mandatory products.

Do I need a warehouse if I only have one application?

Often the application's database or a reporting replica is sufficient. Reconsider when reports need data from other systems, historical versions, shared metrics or resources isolated from checkout traffic. Check those requirements and actual query plans before choosing another platform.

What is a data mart?

A data mart serves one subject or team's analytical questions. It can be fed by a wider warehouse or built from source systems. Define its measures and dimensions consistently with other models when their reports must be compared.

Should the warehouse hold raw data or cleaned data?

Many designs keep source-shaped arrivals separately from prepared reporting tables. Retained inputs can help redo a faulty transformation, subject to retention and access rules. A raw layer is a design choice, not permission to retain every source field forever.

How is a data lake different from a warehouse?

A lake can hold source-shaped and prepared files; a warehouse provides an analytical model and query system. A lakehouse combines lake storage with managed tables and analytical capabilities. The boundaries overlap: the report still needs explicit grain, history and quality rules wherever the data is stored.

The library Browse all articles