Introduction to Data Warehousing

By Nembot Jules · October 26, 2026 · 15 min read

I have been working as a Data Engineer for almost a year now, and a large part of that time has gone into data warehousing.

This post is the first of a series on data warehousing and the concepts around it. I want it to be a kind of roadmap: something that helps new team members get up to speed quickly, and that anyone on the internet can use to start their own data warehouse journey.

1) Data management in an organization

Every organization does two very different things with its data.

Data management is the set of systems and practices that serve both needs. The history of the data warehouse is the history of how organizations learned to serve them separately.

2) The early era: one database for everything

When organizations first moved their records into databases, the natural design was a single system. The applications wrote to it, and the reports read from it. Same database, same schema, same tables, often the same people writing both the application and the reports.

One database serving every purposeThree applications write to a single database; reports, ad-hoc queries and spreadsheet exports read from that same database.Run the business: writesUnderstand it: readsOrder entryBillingWebsiteOne databasesame schemasame tablesMonthly reportAd-hoc SQLSpreadsheet export
Figure 1. The early pattern: the same database, schema and tables serve both the applications that record transactions and the reports that analyse them.

At small scale this works well, and it is the right choice for many young products today. There is only one copy of the data, so nothing is out of sync. Reports are always up to date. There is no extra infrastructure to build or pay for. When a manager wants a number, someone writes a query against the production tables and gets it.

3) Why it stopped working

As the organization grows, so do the data volumes, the number of applications and the number of people asking questions. The single-database model starts to crack in several places at once:

Point-to-point extracts versus a central warehouseLeft: three sources feed five reports through a tangle of individual extracts. Right: the same sources load one integrated warehouse that serves every consumer.Point-to-point: N × M extractsWith a warehouse: N + M flowsCRMBillingSupportSales reportFinance xlsMkt martFinance v2Ops reportCRMBillingSupportWarehouseintegratedhistoricalReportsBIML / SQL
Figure 2. Without a warehouse, every consumer extracts from every source it needs. With one, each source is integrated once and every consumer reads the same numbers.

These problems share one cause. The same system is asked to run the business and to analyse it: short transactions and long scans compete for the same resources, a schema designed for writing is used for reading, current-state tables are expected to answer questions about the past, and data spread across many systems is expected to give one consistent answer.

4) The evolution: two kinds of systems

Over the past few decades, organizations converged on a simple idea: stop asking one system to do both jobs. Keep operational systems optimized for running the business, and copy their data into a separate analytical system optimized for understanding it. The two families have names: OLTP (online transaction processing) and OLAP (online analytical processing).

Separate operational and analytical systemsThree operational databases are extracted and integrated into one separate analytical system.OLTP: run the businessOLAP: understand the businessCRMBillingWebsiteExtract &integrate(copy, clean, align)Analyticalsystemhistory, integrated
Figure 3. The split: each operational system keeps doing its job, and a copy of its data is integrated into a separate system designed for analysis.

The two are optimized for opposite workloads:

OLTP (operational)OLAP (analytical / warehouse)
PurposeRun the businessUnderstand the business
Typical queryRead or write one record: “update this order”Aggregate millions of rows: “sales by region by month”
DataCurrent stateHistory, integrated from many sources
DesignNormalized, to avoid update anomaliesOften denormalized (star schemas), to make reads simple and fast
WritesMany small, concurrent transactionsPeriodic or streaming bulk loads
UsersApplications, front-line staffAnalysts, data scientists, managers, dashboards
StorageUsually row-orientedUsually column-oriented in modern platforms
Row access versus column scansTwo grids of the same table. On the left one full row is highlighted; on the right the region and amount columns are highlighted for every row.OLTP: read or write one whole rowiddatecustregionamountUPDATE … WHERE id = 42OLAP: scan a few columns, all rowsiddatecustregionamountSELECT region, SUM(amount) …
Figure 4. Operational systems touch a few complete rows per transaction; analytical queries read a few columns across millions of rows, which is why warehouses favour columnar storage.

The split addresses each of those problems. Heavy queries no longer run on production, so they no longer slow down transactions. The analytical system can use a schema designed for reading, keep the history that operational systems overwrite, and integrate data from every source into one consistent view. This separate analytical system is the data warehouse.

Evolution of data platformsTimeline: one database for everything in the 1970s and 80s, separate OLTP systems and a data warehouse from the late 1980s and 90s, data lakes in the 2010s, lakehouses in the 2020s.One databaseapps + reports1970s–80sOLTP + warehousesplit by workloadlate 1980s–90sData lakeraw data, any format2010sLakehouselake + warehouse2020sEach step adds a layer; none removes the operational database.
Figure 5. From one database for everything to separate operational and analytical systems, then lakes and lakehouses for scale and variety. Dates are approximate eras, not exact launches.

5) The Data Warehouse

Definition

Bill Inmon, often called the father of the data warehouse, defined it as a subject-oriented, integrated, time-variant and non-volatile collection of data in support of management’s decision-making process. These four properties map onto the problems of the single-database model:

What it was built for

Decision support. The warehouse exists to separate running the business from understanding it, and to give the whole organization one consistent, historical version of the numbers. It is not a backup of production, and it is not a place to dump every table “just in case”.

Where it came from

6) Anatomy of a data warehouse

Most warehouse platforms are made of the same building blocks:

Anatomy of a data warehouse platformSix stages from left to right: sources, ingestion, staging, core, marts and semantic layer. Below, four bars span all stages: metadata and lineage, data quality tests, orchestration, security.Sourcesapps, DBsfiles, APIsIngestionETL / ELTbatch, streamStagingraw copyof sourcesCoreintegrated,with historyMartsper subjectstar schemasSemantic / BImetrics,dashboardsMetadata & lineageData quality testsOrchestration & schedulingSecurity & access control
Figure 6. The stages data flows through, left to right, and the concerns that span every stage.
ETL versus ELTTop row: source, then a separate transform engine, then the warehouse. Bottom row: source loads raw tables into the warehouse, where SQL transforms them into models.ETL: transform before loadingSourceTransformseparate ETL engineWarehousereceives clean dataELT: load raw, transform inside the warehouseSourceWarehouseRaw tablesTransformin-warehouse SQLModels
Figure 7. The only real difference is where the transformation runs: in a separate engine before the load, or inside the warehouse after it.

Every warehouse has these building blocks. Where architectures differ is in how they model the core and the marts, and in which order they build them.

7) The architectures

Inmon: the Corporate Information Factory (top-down)

Inmon’s approach starts with an enterprise data warehouse modelled in third normal form (3NF), integrated across the whole company. Data marts are then built from the warehouse: they are dependent data marts. The wider framework, described with Claudia Imhoff and Ryan Sousa in the 1998 book of the same name, is called the Corporate Information Factory (CIF).

Inmon Corporate Information FactorySources go through ETL and staging into a normalized enterprise data warehouse, which feeds dependent sales, finance and HR marts, which feed BI.Top-down: integrate first, then derive dependent martsCRMBillingSupportETL +stagingEnterprise DWH3NF, normalizedintegratedsingle source of truthSalesmartFinancemartHRmartBI
Figure 8. Inmon: one normalized enterprise warehouse is the integration point; marts are derived from it and never loaded directly from sources.

Kimball: dimensional modelling and the bus architecture (bottom-up)

Kimball starts from the business process (taking an order, shipping, invoicing) and models each one as a star schema: a central fact table of measurements, surrounded by dimension tables that give context (who, what, where, when). The warehouse is the sum of these stars, tied together by conformed dimensions: dimensions such as Date, Customer or Product that mean exactly the same thing in every star. The plan that lists which processes share which dimensions is the bus matrix.

Kimball bus architecture and bus matrixSources feed staging, which loads three star schemas for sales, inventory and returns. All three share one set of conformed dimensions. Below, a matrix marks which dimensions each process uses.CRMPOSERPStagingSales starInventory starReturns starConformed dimsDateProductStoreCustomerBus matrix: which business process uses which conformed dimensionProcessDateProductStoreCustomerSales●●●●Inventory●●●–Returns●●●●
Figure 9. Kimball: the warehouse is the set of star schemas, one per business process, held together by shared conformed dimensions. The bus matrix is the plan.

The core concepts:

Serving users: the presentation area and aggregate fact tables.

In Kimball’s terms, the stars form the presentation area: the dimensional data marts that BI tools and users query. Staging is the back room where data is cleaned and conformed, and users never query it directly.

The fact tables in the presentation area are kept at the finest grain declared above, such as one product line on one receipt, so they quickly reach millions or billions of rows. When every report computes its indicators on the fly with ad hoc queries over those rows, two problems follow: dashboards slow down as the fact tables grow, and two reports can compute the same indicator in slightly different ways.

Kimball’s answer is the aggregate fact table: a second fact table at a coarser grain whose indicators are precomputed during the nightly load. Instead of one row per receipt line, agg_sales_daily holds one row per day, store and product category, with revenue, units and margin already summed. It is built from the detailed fact_sales and joins to the same conformed dimensions, often through shrunken dimensions: conformed subsets such as a category-level version of dim_product. Dashboards read the aggregate and answer in seconds, while the detailed star stays available for drill-down and for indicators that are not precomputed. Each indicator is then defined once, in the load that builds the aggregate, rather than in every report. A semantic layer, described in the anatomy above, can sit on top and expose both levels under the same business names.

Aggregate fact tables on top of the detailed starA detailed star with fact_sales at receipt-line grain and the dimensions date, store, product and customer holds millions of rows. A nightly load builds agg_sales_daily at day, store and product category grain, with precomputed indicators and the same conformed dimensions. BI dashboards read the aggregate in seconds; drill-down and ad hoc queries still read the detailed star.Detailed star (finest grain)fact_sales1 row = receipt linedim_datedim_storedim_productdim_customermillions of rowsindicators computed on the flynightlyloadAggregate fact (coarse grain)agg_sales_dailyday × store × categoryrevenue, units, marginprecomputed oncesame conformed dimsthousands of rowsindicators precomputedBI dashboardsanswer in secondsDrill-down /ad hoc queriesread the detaildetail stays available
Figure 10. Aggregate fact tables: the nightly load summarises the detailed star into a coarser fact table that dashboards read directly, while drill-down and ad hoc questions still go to the detail.

Aggregates have a cost: extra storage, a longer nightly load, and one more table to keep consistent with the detail. They stay consistent only if they are rebuilt from the detailed facts and share the same conformed dimensions, and they are worth adding only for queries that have been measured as slow.

Data Vault: auditable integration

Data Vault, created by Dan Linstedt (Data Vault 2.0 is its current version), models the integrated layer with three types of tables: hubs (unique business keys, e.g. a customer number), links (relationships between business keys) and satellites (descriptive attributes with their history and load timestamps). It is insert-only and records where and when every piece of data arrived.

Data Vault exampleTwo hubs, customer and product, joined by a purchase link. Each hub and the link has a satellite underneath holding descriptive attributes and their load dates.hub_customercustomer_hk (PK)customer_id (BK)load_daterecord_sourcelink_purchasepurchase_hk (PK)customer_hk (FK)product_hk (FK)load_datehub_productproduct_hk (PK)sku (BK)load_daterecord_sourcesat_customercustomer_hk (PK, FK)load_date (PK)namecitysat_purchasepurchase_hk (PK, FK)load_date (PK)quantityamountsat_productproduct_hk (PK, FK)load_date (PK)namecategoryHubs (business keys) · Links (relationships) · Satellites (attributes + history)
Figure 11. Data Vault: keys, relationships and descriptive history live in separate insert-only tables, so new sources plug in without remodelling.

One Big Table (OBT)

A fully denormalized wide table, with facts and all dimension attributes on every row. Columnar engines make this practical. It is great for a specific dashboard or ML feature set, but it duplicates logic, makes history and changes painful, and is best treated as a final output built from a dimensional model, not as a replacement for one.

Data lake, lakehouse and Medallion

A data lake stores raw data of any format (files, JSON, logs, images) cheaply in object storage, without imposing a schema upfront (“schema on read”). It solved scale and variety, but without governance, many lakes became “data swamps”: lots of data, little trust.

The lakehouse adds warehouse features (ACID transactions, schemas, time travel, SQL performance) on top of open file formats in the lake, using table formats such as Delta Lake, Apache Iceberg or Apache Hudi. The term was popularized by Databricks, in a 2020 blog post and a 2021 research paper.

The Medallion architecture, also popularized by Databricks, organizes lakehouse data in three layers: bronze (raw data as ingested), silver (cleaned, deduplicated and conformed) and gold (business-ready tables for reporting and ML).

Medallion architecture in a lakehouseSources land in bronze, are refined into silver, then gold, inside a lakehouse built on object storage with an open table format. Gold serves BI, ML and SQL.SourcesLakehouse: object storage + table format (Delta, Iceberg, Hudi)Bronzeraw, as ingestedappend-onlySilvercleaned, dedupedconformedGoldbusiness-readyKimball star schemasBI · ML · SQLBronze ≈ stagingSilver ≈ integrated coreGold ≈ marts
Figure 12. Medallion organizes data by level of refinement. It does not say how to model; the gold layer is very often a set of Kimball star schemas.

Be precise about what Medallion is: it is a data layout and quality-progression pattern, not a modelling methodology. It tells you how refined the data is at each layer, but not how to model it. Bronze looks a lot like staging; silver plays the role of the integrated layer; and the gold layer is very often… Kimball star schemas. Medallion does not replace Inmon or Kimball; it can be combined with either.

8) Comparison and how to choose

InmonKimballData VaultMedallion
What it isArchitecture + 3NF modelArchitecture + dimensional modelModelling method for the integration layerLayering pattern in a lakehouse
DirectionTop-downBottom-up, by business processSource/business-key drivenRaw to refined
Core structureNormalized enterprise DWHStar schemas + conformed dimensionsHubs, links, satellitesBronze, silver, gold
Time to first valueSlowFastMedium (needs marts on top)Fast for raw, depends on gold model
Business readabilityLowHighLowDepends on gold model
Auditability, changeGoodMediumExcellentGood (raw kept in bronze)

How to choose, in practice:

9) Common mistakes

10) A small worked example

Take a generic retail business. The business process is selling; the grain is one product line on one receipt. The dimensions are date, store, product and customer. The customer dimension is SCD type 2, so we keep the customer’s city at the time of each sale.

Star schema for retail salesA central fact_sales table with four foreign keys, a degenerate receipt number and two measures, joined to dim_date, dim_product, dim_store and dim_customer.fact_salesdate_key (FK)store_key (FK)product_key (FK)customer_key (FK)receipt_numberquantitysales_amountdim_datedate_key (PK)dateyear_monthweekdaydim_productproduct_key (PK)skunamecategorydim_storestore_key (PK)store_namecityregiondim_customercustomer_key (PK)customer_idcityvalid_from/to
Figure 13. The retail sales star. Grain: one product line on one receipt. Keys point outward to dimensions; measures stay in the fact.
-- Dimension with SCD type 2
CREATE TABLE dim_customer (
  customer_key   INT PRIMARY KEY,     -- surrogate key
  customer_id    VARCHAR(20),         -- business key from the source
  customer_name  VARCHAR(100),
  city           VARCHAR(50),
  valid_from     DATE,
  valid_to       DATE,                -- '9999-12-31' for the current row
  is_current     BOOLEAN
);

-- Fact table, grain: one product line on one receipt
CREATE TABLE fact_sales (
  date_key       INT REFERENCES dim_date(date_key),
  store_key      INT REFERENCES dim_store(store_key),
  product_key    INT REFERENCES dim_product(product_key),
  customer_key   INT REFERENCES dim_customer(customer_key),
  receipt_number VARCHAR(20),         -- degenerate dimension
  quantity       INT,                 -- additive
  sales_amount   DECIMAL(12,2)        -- additive
);

-- Sales by month and product category, for the customer's city at sale time
SELECT d.year_month,
       p.category,
       c.city,
       SUM(f.sales_amount) AS revenue
FROM fact_sales f
JOIN dim_date d     ON f.date_key = d.date_key
JOIN dim_product p  ON f.product_key = p.product_key
JOIN dim_customer c ON f.customer_key = c.customer_key
GROUP BY d.year_month, p.category, c.city
ORDER BY d.year_month, revenue DESC;

The query stays readable: join the fact to its dimensions, group, sum. This is what dimensional modelling is designed for: business questions become simple queries. And because the fact points to the customer row that was valid at the time of the sale, a customer who moved last month does not rewrite last year’s sales by city.

Slowly changing dimension type 2Before: one row for customer C-001 in Douala. After a move: that row gets valid_to 2026-03-31 and is_current false, and a new row with surrogate key 245 and city Yaoundé becomes current.Before: one current row per customercustomer_keycustomer_idnamecityvalid_fromvalid_tois_current101C-001AnaDouala2024-01-159999-12-31trueAfter she moves: old row closed, new row currentcustomer_keycustomer_idnamecityvalid_fromvalid_tois_current101C-001AnaDouala2024-01-152026-03-31false245C-001AnaYaoundé2026-04-019999-12-31trueSales before April 2026 keep customer_key 101 (Douala); new sales use 245 (Yaoundé).
Figure 14. SCD type 2: a change adds a row with a new surrogate key instead of overwriting, so history stays correct.

More writing

How to build a top data engineering team

The Game at Work