Skip to content
Mar 11

Slowly Changing Dimensions Type 1 and 2

MT
Mindli Team

AI-Generated Content

Slowly Changing Dimensions Type 1 and 2

In data warehousing and business intelligence, the ability to track how descriptive attributes change over time is what transforms static data into a powerful historical record. Slowly Changing Dimensions (SCDs) are the core techniques for managing these changes in dimension tables, directly impacting the accuracy of trend analysis, compliance reporting, and business decisions. Whether you are a data engineer building pipelines or an analyst interpreting reports, understanding how to implement SCD Type 1 and Type 2 is fundamental to handling real-world, evolving data.

Understanding Slowly Changing Dimensions

A dimension table in a data warehouse contains descriptive attributes (like customer name, product category, or employee department) that provide context to the numerical measures in fact tables. When these attributes change—a customer moves, a product is renamed—you face a design choice: do you overwrite the old value or preserve the history? This is the realm of Slowly Changing Dimensions. SCDs are categorized into types, with Type 1, 2, and 3 being the most common. The choice of type is not technical but business-driven, hinging on the reporting requirements for historical accuracy. Ignoring SCD strategies can lead to misleading analytics, where all past facts appear to relate to the current dimension state, erasing valuable temporal context.

SCD Type 1: The Overwrite Approach

SCD Type 1 is the simplest strategy: when an attribute changes, you overwrite the old value with the new one in the dimension table. This method does not preserve history; the dimension always reflects the most current state. For example, if a customer's city changes from "Springfield" to "Shelbyville," a Type 1 update would simply replace "Springfield" with "Shelbyville" in the customer dimension record. All past sales transactions associated with this customer would now be linked to the new city, effectively retroactively changing history.

This approach is implemented with a standard SQL UPDATE statement. It is appropriate for correcting data errors or when historical tracking of a particular attribute is not required by business rules. Consider a scenario where a product's internal warehouse code is updated; if no report ever needs to show the old code, a Type 1 change is sufficient. Its primary advantage is simplicity and minimal storage, but its major drawback is the complete loss of historical data, which can be a critical flaw for auditing or longitudinal analysis.

SCD Type 2: Preserving Full History

SCD Type 2 is the standard method for preserving complete history. When an attribute changes, instead of overwriting, you create a new version of the dimension row. The old row remains untouched, representing the historical state, and a new row is inserted to represent the current state. To manage this, three key technical elements are used: surrogate keys, effective date ranges, and a current flag.

A surrogate key is a unique, system-generated identifier (like an integer) for each row in the dimension table, distinct from the business key (like CustomerID). When a change occurs, you insert a new row with a new surrogate key but the same business key. This allows multiple versions of the same business entity to coexist. The effective date range typically consists of start_date and end_date columns. The active row has a start_date equal to when the change took effect and an end_date set to a far-future date (e.g., '9999-12-31'), while the expired row has its end_date updated to the day before the change. The current flag is a Boolean column (e.g., is_current) that quickly identifies the active version, with a value of 1 for the current row and 0 for all historical ones.

For instance, if Employee 101 is promoted from "Analyst" to "Manager" on 2023-10-01, the dimension table would hold two rows:

  • Surrogate Key 456, Business Key 101, Title='Analyst', startdate='2020-05-15', enddate='2023-09-30', is_current=0
  • Surrogate Key 789, Business Key 101, Title='Manager', startdate='2023-10-01', enddate='9999-12-31', is_current=1

This structure allows historical fact records to remain joined to the version of the dimension (via surrogate key) that was valid at the time of the transaction, enabling accurate time-based analysis.

SCD Type 3 and Implementation with Merge Statements

SCD Type 3 offers a middle ground by preserving limited history, typically only the previous value. It does this by adding additional columns to the dimension table to store the old attribute value. For example, a customer table might have current_city and previous_city columns. When a change occurs, you shift the value: previous_city receives the old current_city value, and current_city is updated with the new value. This is useful for tracking only the most recent change, such as keeping a customer's last address on file, but it cannot track a full sequence of changes like Type 2.

The most efficient way to process SCDs, especially Type 1 and Type 2, in a modern data pipeline is using SQL MERGE statements. The MERGE command (also known as UPSERT) allows you to combine insert, update, and delete operations in a single, atomic statement based on a join condition between a source (new data) and a target (dimension table). For Type 2 processing, the logic within a MERGE becomes powerful but more complex.

Here is a conceptual SQL skeleton for a Type 2 MERGE:

MERGE INTO dim_customer AS target
USING stg_customer_updates AS source
ON target.business_key = source.customer_id AND target.is_current = 1

WHEN MATCHED AND target.attribute <> source.attribute THEN
    -- Expire the current row
    UPDATE SET target.end_date = CURRENT_DATE - 1, target.is_current = 0
    -- Insert the new row
    INSERT (business_key, attribute, start_date, end_date, is_current)
    VALUES (source.customer_id, source.attribute, CURRENT_DATE, '9999-12-31', 1);

This statement finds rows where the business key matches and the dimension is currently active. If a tracked attribute has changed, it updates (expires) the old row and inserts a new current row. For Type 1, the MERGE would simply contain an UPDATE clause to overwrite the value when matched.

Choosing SCD Types Based on Business Requirements

Selecting the appropriate SCD type is a critical design decision driven entirely by business reporting needs. You must ask stakeholders: "Do we need to report on facts based on how the dimension looked at the time of the transaction?" If the answer is yes, you likely need Type 2. If historical reporting is unnecessary for a specific attribute, Type 1 saves complexity. Type 3 serves niche cases where only the immediate past state is relevant.

Consider a product dimension. The product name might require Type 2 history for accurate historical sales analysis. However, the product's assigned sales manager, used only for current operational reports, could be handled with Type 1. The choice involves trade-offs: Type 2 offers full auditability but increases table size and join complexity; Type 1 is simple but loses history; Type 3 is a compromise with schema alteration limits. Always document the SCD strategy per attribute to maintain clarity across the data team and ensure ETL processes are built correctly.

Common Pitfalls

  1. Using Natural Keys as Primary Keys for Type 2: A common mistake is using the business key (e.g., CustomerID) as the primary key in a Type 2 dimension. This violates uniqueness when multiple rows for the same customer exist. Always use a surrogate key as the primary key to uniquely identify each historical version, while the business key remains a regular attribute for grouping versions.
  2. Incorrect Date Range Handling: Failing to properly manage end_date for expired rows can lead to overlapping or gap-ridden date ranges. Ensure your ETL logic consistently sets the expired row's end_date to one day before the new row's start_date. Also, always join fact tables to dimension tables using a condition like fact.transaction_date BETWEEN dim.start_date AND dim.end_date for accurate historical context.
  3. Misapplying the SCD Type: Choosing Type 1 for an attribute that later requires historical analysis is a costly error. Thoroughly interview business users to understand all potential reporting requirements before implementation. Conversely, applying Type 2 to every attribute can create unnecessary storage and processing overhead.
  4. Inefficient MERGE Logic: Writing MERGE statements that don't correctly isolate changed rows can cause infinite loops or performance issues. Always include a precise condition in the WHEN MATCHED clause to check if the relevant attributes have actually changed before triggering an update/insert for Type 2.

Summary

  • SCD Type 1 overwrites old dimension values with new ones, sacrificing all history for simplicity. It is suitable for attributes where only the current state matters.
  • SCD Type 2 preserves full history by creating new dimension rows with new surrogate keys, using effective date ranges and a current flag to track active and historical versions.
  • SCD Type 3 maintains limited history by storing previous values in additional columns, useful for tracking only the most recent change.
  • SQL MERGE statements provide an efficient, single-pass method for implementing SCD logic, especially for Type 1 and Type 2 processing within data pipelines.
  • The choice between SCD types is a business decision, not a technical one, and must be based on specific reporting and analytical requirements for historical accuracy.

Write better notes with AI

Mindli helps you capture, organize, and master any subject with AI-powered summaries and flashcards.