Chapter 1 · Foundations
The Big Picture
A data warehouse is a database built for questions instead of transactions. This chapter starts with the infrastructure the lab runs on and how it is deployed, then shows the whole SBEcoLTDDW pipeline (source, layers, orchestration and consumers) so every later chapter has a place to hang on.
Infrastructure: Linux + Docker + SQL Server on Linux
The lab is one Ubuntu Linux virtual machine deployed in AWS. Docker runs every service in a container: SQL Server 2022 for Linux in one, Apache Airflow in six more. Your PC only edits files, opens SSH sessions and a browser.
Deployment: from the PC into the containers
Nothing is installed by hand inside a container. Files are edited on the PC, copied to the Linux server, and reach the containers either through bind mounts (Airflow) or through docker exec / docker cp (SQL Server).
- Copy the lab to the Linux server.
scpputs the master copy from the PC into~/sbecoltddw; shell scripts get their line endings converted to LF. - Build the warehouse objects.
run_sbecoltddw.shpipes each course SQL file intosqlcmdinside the SQL Server Linux container withdocker exec. There is no SQL Server client installed on the host. - Reset the source when replaying.
reset_source.shpipes SQL intosqlcmdinside the container to undo the simulator's changes in AdventureWorks2022, so the scenarios of Chapter 12 can be run again from the original data. - Install the pipeline into Airflow.
setup_airflow_sbecoltddw.shinstalls compose Version11, copies DAGs, plugin and SQL into~/airflow, recreates the Airflow containers once, and creates the connection. - Bind mounts make them live. The containers see
~/airflow/{dags,plugins,sql}as/opt/airflow/…; the scheduler picks up the DAGs within seconds. - Run. Every task opens an ODBC connection from the Airflow worker container to
mssql:1433and runs one SQL file in SBEcoLTDDW.
The pipeline on one diagram
In 60 seconds. Everything runs on one Ubuntu Linux VM deployed in AWS, with Docker: SQL Server 2022 runs in a Linux container, and Airflow in its own containers. The source is AdventureWorks2022, the shop's sales database. Each run copies customers and changed orders into stg, builds the dimensions (Date, and Customer with history) and the fact (Orders), maintains the indexes, checks data quality, and only then marks the data as published. Airflow runs the 26 steps in order. Each step is one SQL file, and every step writes to an audit table.
How one run flows
- Extract into staging. Customers are copied in full (7,819 rows is cheap). Orders are copied incrementally: only rows whose
ModifiedDateis newer than the stored watermark. Both are cross-databaseINSERT … SELECTs inside the one SQL Server Linux container. 02_extract/*.sql · Chapter 5 - Build the dimensions. The calendar is generated, and customers are compared with a row hash and get a new version when they move (SCD Type 2). 04_dimensions/*.sql · Chapter 6
- Load the fact. Orders are matched to the customer version that was valid on the order date and merged on their business key, so a re-run never duplicates. The indexed views update themselves. 05_facts/*.sql · Chapter 7
- Maintain, check, publish. Columnstore delta stores are compressed and statistics refreshed. Then 5 data quality rules run, including a reconciliation against the live source. Only when they pass is the watermark advanced and the batch marked
Succeeded. 06_post_load, 07_dq, 08_publish · Chapters 8, 10 and 12 - Serve. Consumers read the
rptviews, never the staging or load tables. 01_deploy/07–10 · Chapter 13
Why a separate warehouse at all?
AdventureWorks2022 is an OLTP database: it is designed so the shop can insert an order in a millisecond. Answering "sales by state per year, using the address the customer had at the time" from it means joining six normalised tables, it competes with the shop for resources, and the history is gone because an address update overwrites the old one. A warehouse is shaped for the opposite workload.
| OLTP (AdventureWorks2022) | Data warehouse (SBEcoLTDDW) | |
|---|---|---|
| Optimised for | Many small writes | Large reads and aggregations |
| Shape | Normalised (3NF): Customer → Person → BusinessEntityAddress → Address → StateProvince | Star schema: one fact table, a few wide dimensions |
| History | Current state only; updates overwrite | Kept on purpose (SCD Type 2, append-only facts) |
| Keys | Source IDs (CustomerID) | Surrogate keys (CustomerKey) plus the source ID as an alternate key |
| Indexes | B-trees for point lookups | Columnstore and indexed views for scans and totals |
| Loaded by | The application | A scheduled, audited pipeline |
The layers and their contracts
| Layer | Contains | Contract |
|---|---|---|
stg | Copies of source rows for this run | Emptied at the start of each extract; never read by consumers; checked before use |
Dimension / Fact | The star schema (course objects + pipeline columns) | Keys are stable; history is never lost; loads are idempotent |
rpt | Views | The only objects consumers depend on, so tables can change behind them |
audit, etl | Run, step and DQ logs; watermarks | Written by every task; the source of truth for "what happened" |
ETL or ELT?
In classic ETL a separate engine (SSIS, Informatica) transforms rows before they reach the warehouse. In ELT the raw data is landed first and transformed inside the database with SQL. SBEcoLTDDW is ELT on a single engine: INSERT … SELECT moves source rows into stg, and all transformations are T-SQL running where the data already is, inside the SQL Server Linux container. Airflow never touches a row. It only tells SQL Server which file to run next.
Design rule used throughout
Keep orchestration (order, retries, schedules, alerts) in Airflow and logic (joins, rules, history) in SQL files. The DAG file is about 100 lines and contains no SQL. You can open any task's Rendered Template in Airflow and run exactly that SQL by hand with sqlcmd in the container, or from SSMS.
Five properties every step has
- Idempotent: running a step twice gives the same result. DDL uses
IF NOT EXISTS, the fact usesMERGEon the business key, and dimensions only add missing rows. - Restartable: a failed task can be cleared and re-run alone (Chapter 12 does this for real).
- Audited: each step writes one row to
audit.StepLogwith its row counts, login and Resource Governor group. - Safe on failure: the watermark only moves in the last publish step, so a failed run is simply picked up again next time.
- Checked: nothing is published until the data quality gate passes.
Key takeaways
- The lab is one Ubuntu Linux VM deployed in AWS; Docker runs SQL Server 2022 for Linux and Airflow in containers.
- Files are deployed from the PC to the Linux host and reach the containers through bind mounts or
docker exec. - A warehouse is shaped for questions: a star schema, history, and indexes built for scans.
- SBEcoLTDDW has four layers:
stg→ star →rpt, plusaudit/etlfor control. - Every step is idempotent, restartable, audited and gated.