Что такое Slowly Changing Dimensions (типы SCD)?

Ответ

Slowly Changing Dimensions (SCD) — это методология в хранилищах данных для управления историей изменений в таблицах-измерениях (например, клиенты, продукты). Основные типы:

  1. Тип 1: Перезапись

    • Стратегия: Старые данные перезаписываются новыми. История не сохраняется.
    • Использование: Для исправления ошибок или когда история изменений не важна.
      -- Изменение города клиента. Старое значение теряется.
      UPDATE dim_customer 
      SET city = 'Новосибирск' 
      WHERE customer_id = 123;
  2. Тип 2: Добавление новой версии

    • Стратегия: При изменении атрибута создается новая строка с обновленными данными. Старая строка помечается как неактуальная. Это самый распространенный тип для сохранения полной истории.
    • Использование: Когда требуется полный аудит изменений.
      
      -- 1. Помечаем старую запись как неактивную
      UPDATE dim_customer 
      SET is_current = FALSE, valid_to = CURRENT_DATE - 1
      WHERE customer_id = 123 AND is_current = TRUE;

    -- 2. Добавляем новую запись INSERT INTO dim_customer (customer_id, name, city, is_current, valid_from, valid_to) VALUES (123, 'Иван Иванов', 'Новосибирск', TRUE, CURRENT_DATE, NULL);

  3. Тип 3: Добавление нового столбца

    • Стратегия: Добавляются дополнительные столбцы для хранения предыдущего значения атрибута. Сохраняет только ограниченную историю (обычно одно предыдущее состояние).
    • Использование: Когда важно отслеживать конкретное изменение (например, предыдущий почтовый индекс).
      
      -- Добавляем столбец для предыдущего города
      ALTER TABLE dim_customer ADD COLUMN previous_city VARCHAR(100);

    -- При изменении обновляем оба столбца UPDATE dim_customer SET previous_city = city, city = 'Новосибирск' WHERE customer_id = 123;

Выбор типа зависит от бизнес-требований к детализации истории, производительности и сложности ETL-процессов.

Ответ 18+ 🔞

Давай разжую эту тему про SCD, а то звучит как диагноз, а на деле всё проще, чем кажется. Представь, что у тебя есть табличка с клиентами, и один из них, пидарас шерстяной, вдруг взял и переехал из Москвы в Новосибирск. И вот тут начинается ёперный театр — как это изменение запихнуть в хранилище данных так, чтобы потом не охуеть от неразберихи.

Тип 1: Похуй-стратегия (Перезапись) Самый простой, но и самый беспощадный. Стратегия — «да похуй на историю». Клиент был в Москве? А теперь он в Новосибирске. Старые данные просто затираются, как будто их и не было. Используется, когда история не нужна или когда надо поправить косяк, например, если изначально записали город с опечаткой. Всё быстро, но доверия ебать ноль, если вдруг понадобится посмотреть, где он жил год назад.

-- Была Москва, стала Новосибирск. Что было — забыли.
UPDATE dim_customer 
SET city = 'Новосибирск' 
WHERE customer_id = 123;

Тип 2: Полная история, или «Овердохуища версий» Вот это уже серьёзно. Тут каждый переезд клиента — это новая строка в таблице. Старая запись не удаляется, а помечается как архивная, а новая — актуальная. Получается полный аудит: видно, когда жил где, и что менялось. Это самый частый и правильный способ, когда история критически важна. Но, бля, таблица раздувается как на дрожжах, если клиенты — распиздяи и часто меняют данные.

-- 1. Старую версию отправляем на пенсию
UPDATE dim_customer 
SET is_current = FALSE, valid_to = CURRENT_DATE - 1
WHERE customer_id = 123 AND is_current = TRUE;

-- 2. Создаём свеженькую, актуальную версию чувака
INSERT INTO dim_customer 
(customer_id, name, city, is_current, valid_from, valid_to) 
VALUES (123, 'Иван Иванов', 'Новосибирск', TRUE, CURRENT_DATE, NULL);

Тип 3: Хитрая жопа (Добавление нового столбца) Промежуточный вариант для тех, кому надо знать только КОНКРЕТНОЕ предыдущее значение, а не всю историю с пелёнок. В таблицу добавляется доп. столбец, например, previous_city. При изменении мы сдвигаем значение: текущее уезжает в «прошлое», а новое встаёт на его место. Сохраняется только одно предыдущее состояние — больше никакой истории нет. Удобно, если бизнес спрашивает что-то вроде: «А в каком городе он был до этого?». Но если спросят «А где он был три переезда назад?», будет вам хиросима — данных-то нет.

-- Добавляем столбец для прошлого города (если ещё нет)
ALTER TABLE dim_customer ADD COLUMN previous_city VARCHAR(100);

-- При переезде делаем рокировку
UPDATE dim_customer 
SET previous_city = city, 
    city = 'Новосибирск'
WHERE customer_id = 123;

Какой тип выбрать? А вот тут, чувак, надо думать головой, а не жопой.

  • Нужна полная, детальная история всех изменений, даже если таблица будет весить как хуй с горы? Бери Тип 2. Терпения ноль ебать на поддержку, зато данные целы.
  • История вообще не нужна, главное — актуальная картина? Тип 1, и не парься.
  • Нужно отслеживать только последнее изменение конкретного поля (например, смена тарифа)? Тип 3 может выручить, но помни — это история в одном кадре.

Выбор, в общем, зависит от того, насколько бизнес хочет бздеть по поводу аудита и сколько ресурсов готов на это потратить.