Skip to content
About
Main content

Feeding history tables

Why does a Type 2 history table constrain every earlier decision in the pipeline?

A slowly changing dimension (SCD) is a table that describes things which change slowly, such as a customer's address. There are two common styles.

  • Type 1: overwrite the old value. Only the current state is kept. It is .
  • Type 2: keep every version of the row, each with a validity interval valid_from and valid_to. It is path-dependent.
customer_id | address  | valid_from | valid_to
51          | Pune     | 2026-01-05 | 2026-03-02   <- closed when the change arrived
51          | Mumbai   | 2026-03-02 | NULL         <- the current row (open)

The modeling choice (history wanted) propagates backwards through every decision here and constrains all of them.

  • Polling CDC cannot feed Type 2 correctly. destroys the intermediate states you are trying to record. If a customer moved twice between two polls, one version is lost.
  • The envelope must carry before-images, or you cannot find and close the previous version's validity interval.
  • Order must be preserved per key, or intervals overlap or leave gaps.
  • The merge is no longer a simple upsert. It is close the open row plus insert the new row: two operations that must be atomic. So a single MERGE is not enough, and implementations use a multi-statement transaction or a two-pass write.
BEGIN;
UPDATE dim_customer SET valid_to = :change_ts
 WHERE customer_id = :id AND valid_to IS NULL;                -- close the old version
INSERT INTO dim_customer (customer_id, address, valid_from, valid_to)
VALUES (:id, :new_address, :change_ts, NULL);                 -- open the new version
COMMIT;

Type 1 tolerates everything above. Type 2 tolerates none of it. The downstream model's history requirement determines the minimum viable capture fidelity. This decision is made at the modeling layer and paid for at the capture layer, usually by different people, which is why the mismatch is so common.

In one line: ; you cannot bolt Type 2 onto a polling pipeline.