Dimensional Modeling
Advanced 16 min read Dimensional Modeling

Slowly Changing Dimensions (SCD)

When an attribute changes, what does history say?

SCDs handle dimension attributes that change over time. Type 1 overwrites (no history), Type 2 keeps versioned rows (full history), Type 3 keeps prior/current columns (limited history) — each trades history for complexity.

SCDtype 1type 2type 3historyeffective datesdimension attributes
Before we start

What you will learn

  • Choose SCD type by the business need for history
  • Implement SCD-2 with surrogate keys and effective dates
  • Avoid the common type-2 traps: grain drift, orphan rows, double-counting
Introduction

What is this?

Slowly Changing Dimensions handle attributes — like a customer's region or tier — that change occasionally, not per transaction. Type 1 overwrites the attribute, losing the past. Type 2 inserts a new dimension row per version with effective dates and a current flag, preserving full history. Type 3 keeps a current and prior column, preserving only the last change. BI correctness often depends on choosing the right type.

Motivation

Why do you need it?

  • Analysts need to see sales attributed to the customer's region AT THAT TIME, not today's.
  • Overwriting (type 1) is tempting for simplicity but silently rewrites history for everyone.
  • Type 2 gives full history at the cost of surrogate keys, active flags and grain tests.
  • Report behavior changes with the type — the choice shapes daily queries.
Think about it

Mental model

Imagine

Updating a band member's bio

Think of

SCD types

Type 1: correct the typo, forget the old name. Type 2: keep 'the drummer who joined in 2015' as its own era with start/end dates. Type 3: keep only the previous band member's name in a 'previous keyboardist' column. Each record of history differs — and so does what you can later say.

Mechanics

How it works

  • Type 1: UPDATE in place; the old value is gone; history reports change retroactively.
  • Type 2: on change, close the current row's effective_to, open a new row with a new surrogate key and active=1.
  • Type 3: retain previous value in a column and roll the current one; only last change survives.
  • Facts reference the surrogate key of the version active at their event time.
  • Invariants: one active row per natural key; contiguous effective dates (no gaps/overlap).

Type 2 versioning through time.

Customer joins
Tier change
Another change
Fact joins
Two eras
Real world

In production

  • A telecom models customer plans SCD-2; revenue by plan today vs plan-at-signup both compute correctly.
  • An e-commerce company tracks product category changes type 1 (past doesn't matter) and customer tier type 2 (history drives retention analysis).
  • A finance dim type 3 for 'previous manager' supports a compare-last-role report.
Guidelines

Best practices

  • Ask the question that must survive: 'sales by tier AT sale time' needs type 2; 'fix a typo' needs type 1.
  • For type 2 add: surrogate key, business key, effective_from/to, current flag, and tests.
  • Close periods to 'end of last month' where reports compare snapshots, to avoid mid-month flips.
  • Document the type per attribute — a mixed dimension needs an attention note.
Watch out

Common mistakes

  • Mixing type 1 and 2 by updating rows 'to be safe', losing both history and simplicity.
  • Forgetting effective dates align, causing overlapping or gapped history.
  • Two active rows per natural key after a partial load breaks every join.
  • Reports counting dimension versions instead of fact members.
Root cause analysis

Common issues

Error
Report shows today's region on last year's orders
Root cause

Fact joined current dim row instead of the version at event time

Fix

Join on the surrogate key present in the fact, or use as-of date logic.

Error
Gap in history after a failed load
Root cause

Close/insert not applied atomically

Fix

Wrap the versioning update in a transaction; add contiguity tests.

When things break

Debugging tips

  • History 'jumps' in reports? Check the SCD type — overwrite (T1) rewrites the past.
  • Customer appearing twice in a group-by? Two active SCD-2 rows for one business key.
  • Date slices inconsistent? Verify effective_to boundaries and the as-of rule.
Interviews

Interview checkpoint

Practice

Hands-on lab

Implement SCD Type 2 in SQL
45 min · advanced
In progress
Objectives
  • Version customer tiers with surrogate keys and effective dates
  • Prove old facts keep their event-time tier
  • Test the 'one active row' invariant

Implement SCD Type 2 in SQL

45 min · advanced

0/5 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/2
1

Which SCD type preserves full historical versions of an attribute?

2

Type 1 SCD overwrites the old attribute value, losing history.

Go deeper

Official documentation