Data Warehouse, Data Lake and Lakehouse

First lesson of the Data Warehouses and Analytical Modeling course, free to read: about 16 minutes, 3 exercises and 4 quiz questions. This is the catalogue's base lesson; in the student space, it is rewritten for your profile.

Objectives

  • Distinguish a data warehouse, a data lake and a lakehouse
  • Describe a layered analytical architecture (raw, cleaned, business)
  • Write a transformation from the raw layer to the cleaned layer in SQL

Data warehouseData lakeLakehouseELT and transformation layers

An application records orders, a CRM records contacts, a marketing tool records campaigns. To answer “which channel brings in the most loyal customers?”, you need to bring this data together in one place, historize it and make it easy to query, without slowing down the production databases. That is the role of the analytical data platform. This course teaches you how to model it; this first lesson sets out the vocabulary.

The data warehouse

A data warehouse is a database designed for analysis. The data in it is structured (typed tables and columns), integrated (a customer has the same identifier whatever the source), historized (past states are kept) and organized for aggregation queries over large volumes. Product examples: BigQuery, Snowflake, Amazon Redshift, Azure Synapse, or PostgreSQL for modest volumes. Most store data by column: a query that reads three columns of a fifty-column table only reads those three columns.

The schema is applied at write time (schema on write): data that doesn’t respect the expected type is rejected at load.

The data lake

A data lake is low-cost file storage, often object storage (Amazon S3, Azure Data Lake Storage, Google Cloud Storage). You drop everything in as is: CSV exports, JSON events, Parquet files, images, logs. The schema is applied at read time (schema on read): the query engine (Spark, Trino, etc.) interprets the files.

Advantage: you keep everything, at low cost, including what you don’t yet know the use of. Risk: without a catalog or rules, the lake becomes a “swamp” where nobody knows which files are reliable.

The lakehouse

The lakehouse combines the two: the data stays in open files (often Parquet) on object storage, but a table format (Delta Lake, Apache Iceberg, Apache Hudi) adds on top what the lake was missing: transactions, a controlled schema, row updates and deletions, version history. Several engines can read the same tables.

Warehouse Lake Lakehouse
Data structured any format structured and semi-structured
Schema on write on read controlled by the table format
Querying SQL various engines SQL and various engines

The choice depends on volumes, uses (reporting, data science) and the team’s skills; the modeling you are about to learn is the same in all three cases.

ETL or ELT

Historically, you would extract, transform on a dedicated server, then load the result (ETL). With powerful, usage-billed warehouses, you tend to do ELT instead: you load the raw data first, then transform it inside the warehouse, in SQL. Tools like dbt (course DE2) organize these transformations.

The layered architecture

Transformations are arranged in successive layers. Names vary by team:

  1. Raw (bronze, raw): a faithful, timestamped copy of the sources, never modified. You can always recompute everything from it.
  2. Cleaned (silver, staging): correct types, harmonized column names, normalized values, load duplicates removed. One table per source, with no business logic.
  3. Business (gold, marts): analysis-ready models, typically star schemas, with the business rules (“a cancelled order doesn’t count in revenue”).

Here is a typical transformation from the raw layer to the cleaned layer. The source is loaded several times a day: the same order may appear in two loads; we keep the most recent version.

WITH classees AS (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY id ORDER BY _loaded_at DESC) AS rang
    FROM raw_commandes
)
SELECT CAST(id AS INTEGER)       AS commande_id,
       lower(trim(client))       AS client,
       CAST(montant AS REAL)     AS montant,
       upper(devise)             AS devise
FROM classees
WHERE rang = 1;

Notice that the cleaned layer does not filter incomplete rows (a missing amount stays NULL): it makes them visible. Deciding that an order with no amount is excluded from a metric is a business rule, which belongs to the next layer.

Exercises

Solutions and tests stay on the server. In the student space, your code is run and checked, and the tutor gives hints before the solution.

  1. CodeDifficulty 2SQL (SQLite) in the browser2 hints

    From the raw layer to the cleaned layer

    Raw table: raw_commandes(id, client, montant, devise, _loaded_at), all columns as text; _loaded_at is the load timestamp.

    Write the cleaned layer query. For each id, keep only the most recent load, and produce:

    • commande_id: the id as an integer;
    • client: the name without surrounding spaces, in lowercase;
    • montant: the amount as a real number (leave NULL if absent);
    • devise: the currency in uppercase.
    Exercise data (SQL)
    -- Couche brute (bronze) : chargée deux fois par jour, sans transformation
    CREATE TABLE raw_commandes (id TEXT, client TEXT, montant TEXT, devise TEXT, _loaded_at TEXT);
    INSERT INTO raw_commandes VALUES
     ('1', ' amina ', '49.90', 'EUR', '2026-03-01 02:00'),
     ('2', 'BASTIEN', '120', 'eur', '2026-03-01 02:00'),
     ('2', 'BASTIEN', '125', 'eur', '2026-03-02 02:00'),
     ('3', 'Camille', '15.5', 'EUR', '2026-03-01 02:00'),
     ('4', 'camille', NULL, 'EUR', '2026-03-02 02:00');
    WITH classees AS (
        SELECT *, ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...) AS rang
        FROM raw_commandes
    )
    SELECT ...
    FROM classees
    WHERE rang = 1;
  2. CodeDifficulty 1SQL (SQLite) in the browser1 hint

    Volume check between layers

    Raw table: raw_commandes(id, client, montant, devise, _loaded_at), all columns as text; _loaded_at is the load timestamp.

    Before publishing the cleaned layer, you check the volumes. Display on one row the number of raw rows (alias lignes_brutes) and the number of distinct orders (alias commandes).

    Exercise data (SQL)
    -- Couche brute (bronze) : chargée deux fois par jour, sans transformation
    CREATE TABLE raw_commandes (id TEXT, client TEXT, montant TEXT, devise TEXT, _loaded_at TEXT);
    INSERT INTO raw_commandes VALUES
     ('1', ' amina ', '49.90', 'EUR', '2026-03-01 02:00'),
     ('2', 'BASTIEN', '120', 'eur', '2026-03-01 02:00'),
     ('2', 'BASTIEN', '125', 'eur', '2026-03-02 02:00'),
     ('3', 'Camille', '15.5', 'EUR', '2026-03-01 02:00'),
     ('4', 'camille', NULL, 'EUR', '2026-03-02 02:00');
    SELECT COUNT(*) AS lignes_brutes, ... AS commandes
    FROM raw_commandes;
  3. Multiple choiceDifficulty 11 hint

    Choose an architecture

    A team wants to keep JSON logs and product images at low cost, while offering analysts reliable SQL tables with row updates. Which architecture fits best?

    • A classic data warehouse only
    • A lakehouse: open files on object storage with a table format such as Delta Lake or Iceberg
    • A simple shared folder of CSV files

End-of-lesson quiz

  1. What does “schema on read” mean?

    • The schema is checked at load time
    • The schema is applied by the engine when the files are read
    • Data never has a schema
  2. In which layer do you put the rule “a cancelled order doesn’t count in revenue”?

    • Raw
    • Cleaned
    • Business
  3. Why is the raw layer never modified?

    • Because SQL forbids it
    • So that all transformations can be replayed from the original data
    • To save space
  4. What characterizes ELT?

    • Data is transformed before being loaded
    • Raw data is loaded and then transformed in the warehouse
    • Data is never transformed

The rest of the course

  1. Building a Star Schema in SQL20 min
  2. Slowly Changing Dimensions (SCD)20 min
  3. Partitioning, Clustering and Aggregate Tables18 min
  4. Controlling a Warehouse's Costs16 min

Data Warehouses and Analytical Modeling · Intermediate · 1 h 30 min