Chiều thay đổi chậm (SCD, Slowly Changing Dimension)
1. Tổng quan
A. Định nghĩa
Chiều thay đổi chậm (SCD, Slowly Changing Dimension) là kỹ thuật mô hình hóa chiều quy định cách lưu trữ và theo dõi sự thay đổi khi giá trị thuộc tính trong bảng chiều (Dimension) của kho dữ liệu thay đổi chậm theo thời gian. Nó được phân loại từ Type 0 đến Type 6 tùy theo việc lịch sử thay đổi có được bảo tồn hay không và bằng cách nào.
Câu hỏi cốt lõi của khái niệm này, được Ralph Kimball hệ thống hóa, tuy đơn giản nhưng mạnh mẽ. "Khi địa chỉ của khách hàng thay đổi từ Seoul sang Busan, đơn hàng quá khứ nên được giữ là đã phát sinh ở Seoul, hay nên đổi tất cả sang Busan?" Câu trả lời cho câu hỏi này chi phối độ chính xác của kết quả phân tích. Chiều cung cấp ngữ cảnh "ai, cái gì, ở đâu, khi nào" cho fact (giá trị đo lường), và cách xử lý ngữ cảnh đó khi nó thay đổi chính là chiến lược quản lý lịch sử.
Từ khóa của SCD là "chậm (slowly)". Đối tượng là các thuộc tính thay đổi hiếm và không định kỳ — như phân loại sản phẩm, hạng khách hàng, đơn vị trực thuộc tổ chức, mã vùng — khác về bản chất với dữ liệu giao dịch (fact) đổ vào hàng nghìn bản ghi mỗi giây. Các thuộc tính thay đổi nhanh ngược lại nên được tách thành fact hoặc trích xuất thành một mini-dimension riêng.
B. Bối cảnh ra đời và sự cần thiết
Cơ sở dữ liệu vận hành (OLTP) truyền thống chỉ quản lý "trạng thái hiện tại". Khi khách hàng đổi địa chỉ, bản ghi hiện có bị ghi đè bằng UPDATE, và địa chỉ quá khứ biến mất không dấu vết. Điều này hợp lý vì nghiệp vụ vận hành chỉ cần giá trị mới nhất. Tuy nhiên, trong thế giới phân tích (OLAP), câu chuyện hoàn toàn khác. Nếu địa chỉ quá khứ của khách hàng bị mất khi phân tích "xu hướng doanh thu theo vùng", doanh thu ba năm trước sẽ bị tổng hợp theo địa chỉ hiện tại một cách méo mó, làm tổn hại sự thật lịch sử (historical truth).
Vấn đề này đặc biệt nghiêm trọng trong lĩnh vực quy định và kiểm toán. Lịch sử biến động xếp hạng tín dụng trong tài chính, thay đổi thuộc tính người được bảo hiểm trong bảo hiểm, và theo dõi tình trạng bệnh nhân trong y tế phải có thể tái hiện chính xác "giá trị là gì tại thời điểm đó". Việc ghi đè đơn giản về cơ bản loại bỏ khả năng tái dựng theo thời điểm (point-in-time reconstruction) này. SCD ra đời chính để lấp khoảng trống này — giữa "chỉ giữ hiện tại" của hệ vận hành và "yêu cầu bảo tồn lịch sử" của hệ phân tích.
Hơn nữa, khi kho dữ liệu trở thành Single Source of Truth cho việc ra quyết định toàn doanh nghiệp, việc xử lý thay đổi chiều tùy tiện không có quy tắc nhất quán gây ra sự hỗn loạn khi kết quả phân tích khác nhau theo từng nhà phân tích và từng truy vấn. SCD chuẩn hóa phương thức xử lý thay đổi thành các loại, buộc phải quyết định một cách rõ ràng tại thời điểm thiết kế thuộc tính nào bảo tồn lịch sử và thuộc tính nào bị ghi đè. Điều này bảo đảm một nền tảng phân tích có thể tái hiện và có thể kiểm toán.
2. Vị trí của SCD trong mô hình chiều và cấu trúc tổng thể
Để hiểu SCD, trước hết phải thấy mối quan hệ giữa chiều và fact trong mô hình chiều (star schema). Bảng fact giữ các giá trị đo lường (số tiền doanh thu, số lượng) cùng với khóa ngoại trỏ đến từng chiều, và điểm xuất phát của SCD là các khóa ngoại này không phải khóa tự nhiên của hệ vận hành (business key, ví dụ: số khách hàng) mà là khóa thay thế (surrogate key). Khóa thay thế là một số thứ tự vô nghĩa do chính DW sinh ra, cho phép phân biệt "các phiên bản theo thời điểm khác nhau của cùng một khách hàng" thành các dòng riêng biệt. Gần như mọi loại SCD bảo tồn lịch sử đều được xây dựng trên khóa thay thế này.
flowchart LR
subgraph SRC["Hệ vận hành (OLTP)"]
OP[("Bảng nguồn khách hàng<br/>(chỉ giá trị hiện tại, UPDATE)")]
end
OP --> ETL["Nạp ETL / ELT<br/>(phát hiện thay đổi, xử lý theo loại)"]
subgraph DW["Kho dữ liệu (star schema)"]
DIM[("Chiều khách hàng<br/>(khóa thay thế, phiên bản lịch sử)")]
FACT[("Fact đơn hàng<br/>(giá trị đo lường, FK chiều)")]
FACT -->|"tham chiếu khóa thay thế"| DIM
end
ETL --> DIM
ETL --> FACT
DIM --> BI["BI / phân tích<br/>(tái dựng theo thời điểm, phân tích xu hướng)"]
FACT --> BI
Cốt lõi trong cấu trúc trên là phát hiện thay đổi (change detection) ở giai đoạn ETL. ETL so sánh giá trị hiện tại của nguồn với phiên bản mới nhất của chiều đã được nạp vào DW và (1) chèn nếu là khóa mới, (2) xử lý theo quy tắc từng loại nếu thuộc tính theo dõi đã thay đổi, (3) cho đi qua nếu không có thay đổi. Ở đây, "thuộc tính nào là đối tượng theo dõi và mỗi thuộc tính được xử lý bằng Type nào" là sản phẩm của thiết kế, và việc trộn các Type khác nhau theo từng thuộc tính ngay trong một chiều là phổ biến (đây trở thành cơ sở cho Type 6 sẽ giải thích sau).
Để nâng cao độ chính xác của phát hiện thay đổi, trong thực tế người ta lưu giá trị băm (hash diff) của từng thuộc tính rồi so sánh với băm nguồn, hoặc xử lý các sự kiện thay đổi nhận từ CDC ([[change-data-capture]]) đã thấy ở Phần 2. Cách thứ nhất phù hợp với so sánh theo lô, cách thứ hai phù hợp với nạp gần thời gian thực. Dù theo cách nào, chỉ khi xác định đáng tin cậy "cái gì đã thay đổi" thì mới áp dụng đúng các quy tắc SCD.
Tại đây phải phân biệt hai khái niệm thời gian. Một là thời gian hiệu lực (valid time) — khoảng thời gian giá trị có hiệu lực trong thực tế — và hai là thời gian nạp (transaction/load time) — thời điểm DW biết được sự thật đó. Hai thời gian này có thể lệch nhau do độ trễ nguồn hoặc hiệu chỉnh hồi tố, và thiết kế theo dõi cả hai được gọi là lưỡng thời gian (bitemporal). Trong các lĩnh vực mà yêu cầu quy định và kiểm toán đòi hỏi cả "khi nào có hiệu lực trong thực tế" lẫn "khi nào chúng ta ghi nhận như vậy", cần một thiết kế chiều lưỡng thời gian thêm cột thời gian nạp vào khoảng hiệu lực của Type 2.
3. Phương thức xử lý theo loại SCD (Type 0 ~ 6)
Các loại SCD được sắp xếp dọc theo một trục duy nhất: "thay đổi được lưu trữ như thế nào". Khởi đầu từ Type 0 bảo thủ nhất (bất biến), chúng tiến triển qua ghi đè (Type 1), lịch sử hóa đầy đủ bằng thêm dòng (Type 2), lịch sử hạn chế (Type 3), và sự kết hợp của chúng (Type 6). Dưới đây, mỗi loại được trình bày theo thứ tự về tình huống nó được tạo ra để phục vụ và cái giá nó phải trả.
flowchart TB
START["Phát sinh thay đổi thuộc tính chiều"] --> Q0{"Có phải phản ánh thay đổi không?"}
Q0 -- "Không (thuộc tính bất biến)" --> T0["Type 0<br/>giữ giá trị gốc vĩnh viễn"]
Q0 -- "Có" --> Q1{"Lịch sử quá khứ có cần cho phân tích?"}
Q1 -- "Không cần (chỉ mới nhất)" --> T1["Type 1<br/>ghi đè giá trị hiện có"]
Q1 -- "Cần (lịch sử đầy đủ)" --> T2["Type 2<br/>thêm dòng phiên bản mới"]
Q1 -- "Chỉ giá trị liền trước" --> T3["Type 3<br/>thêm cột giá trị trước đó"]
T2 --> T6["Type 6<br/>hỗn hợp 1+2+3<br/>(hiện tại và lịch sử cùng lúc)"]
T3 --> T6
A. Type 0 — Giữ nguyên bản gốc (Retain Original). Phương thức không bao giờ thay đổi một giá trị đã ghi. Nó áp dụng cho các thuộc tính bất biến theo định nghĩa hoặc phải được coi là bất biến, như ngày gia nhập đầu tiên, ngày sinh, định danh duy nhất của khách hàng. Dù giá trị thay đổi ở nguồn, DW bỏ qua hoặc phân loại thành lỗi riêng. Triển khai đơn giản nhất, nhưng nếu phán đoán "bất biến" sai (ví dụ: lỗi nhập liệu ban đầu không bao giờ sửa được), nó lại cố định hóa vấn đề chất lượng, nên chỉ áp dụng hạn chế cho các thuộc tính thực sự không được thay đổi.
B. Type 1 — Ghi đè (Overwrite). Phương thức vứt bỏ quá khứ bằng UPDATE giá trị hiện có bằng giá trị mới. Nó trực quan nhất vì giống hành vi hệ vận hành, và có chi phí lưu trữ/truy vấn thấp vì số dòng chiều không tăng. Nó phù hợp khi lịch sử quá khứ vô nghĩa về mặt phân tích hoặc là hiệu chỉnh lỗi đơn giản, như sửa lỗi gõ số điện thoại hay chỉnh cách viết mã phân loại. Tuy nhiên, ghi đè bằng Type 1 gây ra điều chỉnh hồi tố (retroactive restatement) của việc tổng hợp fact quá khứ trên cơ sở thuộc tính đó. Nghĩa là doanh thu ba năm trước bị tổng hợp lại theo tiêu chí phân loại hiện nay, khiến không thể tái hiện "bức tranh thực tại thời điểm đó". Việc hiệu ứng hồi tố này có được phép hay không là tiêu chí quyết định áp dụng Type 1.
C. Type 2 — Thêm dòng để bảo tồn lịch sử (Add New Row). Chuẩn mực trên thực tế và phương thức được dùng rộng rãi nhất của SCD. Khi thuộc tính thay đổi, thay vì ghi đè dòng hiện có, một dòng mới với khóa thay thế mới được thêm vào. Nhiều phiên bản dùng chung một khóa tự nhiên (số khách hàng) nhưng khác khóa thay thế cùng tồn tại, và mỗi phiên bản được phân biệt bằng các cột meta như ngày bắt đầu hiệu lực (effective_date), ngày kết thúc hiệu lực (end_date), và cờ hiện tại (is_current). Khi phiên bản mới được tạo, end_date của phiên bản liền trước được đóng và is_current được tắt. Ưu điểm lớn nhất của phương thức này là tái dựng theo thời điểm một cách đầy đủ. Vì fact tham chiếu khóa thay thế tại thời điểm nó phát sinh, một đơn hàng quá khứ mãi mãi liên kết với "phiên bản địa chỉ Seoul của khách hàng đó tại thời điểm ấy". Cái giá là số dòng chiều tăng lên và độ phức tạp của truy vấn "chỉ truy vấn phiên bản hiện tại" (cần điều kiện cờ/ngày). Nó được dùng thiết yếu trong các lĩnh vực mà lịch sử chính là yêu cầu quy định, như xếp hạng tín dụng tài chính, tình trạng hợp đồng bảo hiểm, và thay đổi đơn vị trực thuộc tổ chức.
D. Type 3 — Thêm thuộc tính mới (cột giá trị trước đó) (Add New Attribute). Phương thức thêm cột thay vì dòng, đặt vùng_hiện_tại và vùng_liền_trước cạnh nhau. Nó được dùng khi phải "so sánh đồng thời ngay trước và ngay sau thay đổi", như trong một cuộc tái cơ cấu toàn diện, nhưng không cần lịch sử đầy đủ. Chi phí lưu trữ ít và truy vấn đơn giản, nhưng vì chỉ bảo tồn một bước liền trước (hoặc N bước cố định), lịch sử thay đổi vượt quá hai lần bị mất. Do đó nó chỉ giới hạn trong các tình huống đặc biệt mà thay đổi hiếm và so sánh "trước↔hiện tại" là cốt lõi của phân tích.
Sự khác biệt về tính chất giữa bốn loại có thể tóm tắt như sau. Bảng chỉ là phương tiện hỗ trợ so sánh; lựa chọn thực tế được quyết định bởi sự cân bằng của "nhu cầu lịch sử, khả năng cho phép hồi tố, và chi phí lưu trữ/truy vấn" đã giải thích ở trên.
| Phân loại | Xử lý thay đổi | Bảo tồn lịch sử | Tác động lên fact quá khứ | Tăng dòng/cột | Ứng dụng tiêu biểu |
|---|---|---|---|---|---|
| Type 0 | Không phản ánh | Cố định bản gốc | Không | Không | Ngày sinh, ngày gia nhập |
| Type 1 | Ghi đè | Không (chỉ hiện tại) | Bị thay đổi hồi tố | Không | Lỗi gõ, chỉnh mã |
| Type 2 | Thêm dòng mới | Bảo tồn đầy đủ | Bất biến (cố định theo thời điểm) | Tăng dòng | Xếp hạng tín dụng, tình trạng hợp đồng |
| Type 3 | Thêm cột | Chỉ giá trị liền trước | Lẫn lộn | Tăng cột | So sánh trước/sau tái cơ cấu |
| Type 6 | Kết hợp 1+2+3 | Đầy đủ + hiện tại cùng lúc | Tùy chọn | Tăng dòng + cột | Phân tích hiện tại & thời điểm cùng lúc |
E. Type 4 · Type 6 — Dạng kết hợp. Type 4 tách giá trị hiện tại vào chiều chính và lịch sử vào một mini-dimension lịch sử riêng, nhắm tới cả hiệu năng truy vấn hiện tại lẫn bảo tồn lịch sử. Type 6 (tên bắt nguồn từ 1+2+3=6) đặt trong một chiều duy nhất các dòng phiên bản Type 2, một cột "giá trị hiện tại" luôn giữ giá trị mới nhất qua Type 1, và một cột giá trị trước đó kiểu Type 3 cùng nhau. Điều này cho phép truy vấn cả "giá trị tại thời điểm đó" (dòng phiên bản) lẫn "giá trị hiện tại của khách hàng này" (cột current) từ cùng một bảng, cho phép ví dụ một phân tích kép "nhóm các đơn hàng từ thời cư trú ở Seoul theo cả góc nhìn của khách hàng nay sống ở Busan". Nó linh hoạt nhưng có nhược điểm làm logic ETL phức tạp hơn.
4. Kiến trúc triển khai và kỹ thuật xử lý ETL
Trong thực tế, SCD được triển khai như giai đoạn nạp chiều của pipeline ETL/ELT. Mẫu điển hình nhất là câu lệnh MERGE (UPSERT) của SQL, nối snapshot hiện tại của nguồn với chiều DW, INSERT các dòng mới và xử lý thay đổi theo loại. Với Type 2, một MERGE đơn lẻ khó xử lý "đóng phiên bản hiện có + mở phiên bản mới" cùng một lúc, nên thường tách thành hai bước: (1) một UPDATE đóng end_date của dòng hiện tại của khóa tự nhiên đã thay đổi → (2) INSERT phiên bản mới. Nếu thứ tự này bị đảo ngược, phát sinh lỗi nhất quán khi tồn tại hai dòng is_current cho một khóa tự nhiên, nên phải bảo đảm tính nguyên tử bằng cách gói trong một giao dịch.
sequenceDiagram
participant S as Snapshot nguồn
participant E as Động cơ ETL
participant D as Bảng chiều
S->>E: chuyển bản ghi khách hàng hiện tại
E->>D: tra cứu phiên bản hiện tại (is_current=Y) theo khóa tự nhiên
alt Khóa tự nhiên mới
E->>D: INSERT với khóa thay thế mới
else Thuộc tính theo dõi thay đổi (Type 2)
E->>D: đặt end_date dòng hiện có, is_current=N
E->>D: INSERT dòng phiên bản mới (is_current=Y)
else Thuộc tính không theo dõi thay đổi (Type 1)
E->>D: UPDATE dòng hiện tại (ghi đè)
else Không thay đổi
E-->>E: cho qua (bỏ qua)
end
Để nâng cao độ tin cậy của phát hiện thay đổi, trong thực tế người ta nối các thuộc tính theo dõi để tạo một dấu vân tay băm (ví dụ: SHA-256) và lưu nó trên dòng chiều. So sánh băm nguồn với băm đã lưu chỉ một lần khi nạp cho phép phát hiện thay đổi ngay lập tức mà không phải đối chiếu nhiều cột từng cái một, giảm đáng kể chi phí so sánh cho các chiều hàng chục triệu dòng. Ngoài ra, đặt end_date của khoảng hiệu lực thành một dấu hiệu vô cực như 9999-12-31 thay vì thời gian kết thúc thực tế cho phép biểu diễn điều kiện "đang có hiệu lực" đơn giản bằng một phép nối theo khoảng.
Thiết kế khóa thay thế cũng là một điểm triển khai quan trọng. Dùng trực tiếp khóa tự nhiên của hệ vận hành làm FK của fact không chỉ khiến không thể phân biệt các phiên bản lịch sử mà còn trở nên dễ tổn thương với tích hợp hệ nguồn, tái sử dụng khóa, và xử lý NULL. Khóa thay thế đóng vai trò cách ly (insulation) DW khỏi những thay đổi của hệ vận hành như vậy, và các khóa dành riêng (ví dụ: -1) được vận hành cùng cho các tình huống đặc biệt như unknown và late arriving. Vấn đề chiều đến muộn (late arriving dimension), khi fact đến trước nguồn, được xử lý bằng cách tạo trước một dòng giữ chỗ tạm thời rồi sau đó điền giá trị thực tế.
5. So sánh lựa chọn loại và các trường hợp áp dụng
Ngay cả với cùng một "thay đổi địa chỉ", Type đúng khác nhau tùy mục đích phân tích. Lý do căn bản của sự khác biệt này là SCD không phải một kỹ thuật lưu trữ dữ liệu mà là sự triển khai một quy tắc nghiệp vụ về "cách diễn giải quá khứ". Ba trường hợp dưới đây thể hiện điều này rõ ràng.
Thứ nhất, trong trường hợp đánh giá tín dụng tài chính, Type 2 trên thực tế là bắt buộc. Khi xếp hạng tín dụng của khách hàng được nâng từ BBB lên A, việc không tái hiện được khoản vay quá khứ đã được thực hiện tại thời điểm xếp hạng nào sẽ không thể đáp ứng yêu cầu tái hiện rủi ro của cơ quan giám sát (ví dụ: phân bố xếp hạng của danh mục cuối quý tại một thời điểm cụ thể). Trên thực tế, các DW tuân thủ Basel nạp các thuộc tính xếp hạng, hạn mức, tài sản bảo đảm đều ở Type 2 để tái dựng chính xác mức phơi nhiễm tại bất kỳ thời điểm quá khứ tùy ý nào.
Thứ hai, trong trường hợp danh mục sản phẩm thương mại điện tử, các Type được trộn theo thuộc tính. Sửa lỗi gõ tên sản phẩm chỉ cần Type 1 (ghi đè) là đủ, nhưng việc tái phân loại danh mục sản phẩm phải được giữ ở Type 2 để có thể phân tích cả "doanh thu theo quý trên cơ sở trước khi tái phân loại" lẫn "cơ sở sau khi tái phân loại". Việc hàng chục thuộc tính trong một chiều sản phẩm được trộn ở Type 0/1/2 là phổ biến, và chính tài liệu thiết kế này trở thành sản phẩm của quản trị dữ liệu.
Thứ ba, trong trường hợp phân tích nhân sự/tổ chức, Type 3 hoặc Type 6 hữu ích. Khi phải so sánh cạnh nhau "thành tích trên cơ sở đơn vị trực thuộc trước tái cơ cấu" và "thành tích trên cơ sở sau tái cơ cấu" ngay sau một cuộc tái cơ cấu quy mô lớn, một cột đơn vị trực thuộc liền trước (Type 3) hoặc các cột current/historical cùng tồn tại (Type 6) đơn giản hóa đáng kể truy vấn của nhà phân tích. Tuy nhiên, nếu tái cơ cấu lặp lại từ hai lần trở lên, chỉ riêng Type 3 sẽ mất lịch sử trung gian, nên việc chạy song song Type 2 là không thể tránh khỏi.
Điều mà ba trường hợp này cùng ngụ ý là lựa chọn Type sai dẫn đến các lỗi dữ liệu âm thầm. Nếu một thuộc tính cần lịch sử bị ghi đè bằng Type 1, các báo cáo quá khứ bị làm sai lệch hồi tố, nhưng hệ thống không hề báo lỗi, và nhà phân tích có thể đưa ra quyết định sai mà thậm chí không biết các con số đã thay đổi. Ngược lại, xử lý một thuộc tính hiệu chỉnh đơn giản bằng Type 2 sẽ chất đống các phiên bản vô nghĩa và làm chiều phình to. Đây chính là lý do việc rà soát thiết kế SCD phải được coi là một hoạt động cốt lõi của quản lý chất lượng dữ liệu.
6. Chuyên sâu — SCD trong kỷ nguyên lakehouse và xu hướng mới nhất
SCD truyền thống phát triển trên tiền đề các DW dựa trên RDBMS, nhưng sự lan rộng của data lakehouse ([[data-lakehouse]]) và mô thức ELT đang thay đổi cách triển khai của nó. Trước đây, các công cụ ETL trực tiếp UPDATE/INSERT các dòng, nhưng UPDATE truyền thống trên các tệp trên object storage là đắt đỏ hoặc bất khả thi. Cái giải quyết điều này là các định dạng bảng mở như Delta Lake, Apache Iceberg, và Apache Hudi, vốn hỗ trợ giao dịch ACID và MERGE INTO, cho phép thực hiện nạp Type 2 một cách khai báo ngay cả trên một lake. Đặc biệt, time travel của Iceberg/Delta gán phiên bản cho chính các snapshot bảng, nên nó cũng có thể đóng vai trò một phương tiện bổ trợ giải quyết một số yêu cầu tái dựng theo thời điểm ở tầng lưu trữ mà không cần SCD.
Ở tầng chuyển đổi, tính năng snapshot của dbt đã thực tế chuẩn hóa SCD Type 2. Khi một analytics engineer chỉ khai báo chiến lược theo dõi (check/timestamp) và các cột theo dõi, dbt tự động sinh việc quản lý khoảng hiệu lực, cờ hiện tại và phát hiện thay đổi. Điều này đã giảm đáng kể lỗi so với quá khứ triển khai logic SCD bằng tay, và trở thành một thành phần cốt lõi của các pipeline dữ liệu dạng mã (Analytics Engineering) có thể quản lý phiên bản và kiểm thử.
Mặt khác, một nhiệm vụ thiết kế đi kèm với SCD là xử lý chiều thay đổi nhanh (RCD, Rapidly Changing Dimension). Nếu các thuộc tính thay đổi thường xuyên như dải tuổi hay điểm xu hướng mua của khách hàng được giữ ở Type 2, các phiên bản bùng nổ. Khi đó, các thuộc tính thay đổi nhanh được tách khỏi chiều chính thành một mini-dimension, và fact được thiết kế để tham chiếu cả hai chiều riêng rẽ. Vì SCD là kỹ thuật cho "thay đổi chậm", việc phán đoán nhận diện và tách các thay đổi nhanh ngoài ranh giới đó cũng là trách nhiệm của người thiết kế chiều.
Về phía chuẩn cơ sở dữ liệu, bảng thời gian phiên bản hệ thống (system-versioned temporal table) được SQL:2011 giới thiệu thu hút sự chú ý. Được hỗ trợ bởi PostgreSQL, SQL Server, MariaDB, và các hệ khác, tính năng này cung cấp truy vấn theo thời điểm quá khứ ở cấp ngôn ngữ bằng cú pháp FOR SYSTEM_TIME AS OF, để từ góc nhìn ứng dụng, DBMS xử lý một cách trong suốt việc bảo tồn lịch sử tương tự Type 2. Tuy nhiên, vì đây là lịch sử thời gian hệ thống của "toàn bộ dòng", nó khác về mục tiêu với "sự trộn chiến lược theo dõi theo từng thuộc tính" hay liên kết fact dựa trên khóa thay thế được yêu cầu trong mô hình hóa phân tích, nên nó có xu hướng bổ trợ hơn là thay thế hoàn toàn SCD của DW phân tích.
7. Điểm cần cân nhắc và hàm ý (góc nhìn Kỹ sư chuyên nghiệp)
Vì SCD không phải chỉ là một kỹ thuật nạp mà là một quyết định thiết kế chi phối độ tin cậy, khả năng kiểm toán, và độ chính xác phân tích của kho dữ liệu, nên từ góc nhìn Kỹ sư chuyên nghiệp cần cân nhắc một cách tổng hợp những điều sau.
- Chiến lược áp dụng (làm rõ ánh xạ Type theo từng thuộc tính): Quyết định Type theo từng thuộc tính thay vì cho toàn bộ chiều, và văn bản hóa nó trong một từ điển dữ liệu và tài liệu quản trị. Vì "thay đổi nào là sự thật lịch sử và thay đổi nào là hiệu chỉnh đơn giản" là câu hỏi mà nghiệp vụ, không phải IT, phải trả lời, nên quá trình đồng thuận với nghiệp vụ phải được đưa vào quy trình thiết kế.
- Đánh đổi (tính đầy đủ của lịch sử ↔ chi phí lưu trữ/truy vấn): Type 2 bảo tồn lịch sử một cách hoàn hảo nhưng kéo theo sự bùng nổ dòng và độ phức tạp của truy vấn "phiên bản hiện tại". Đặt các thuộc tính tần suất thay đổi cao thành Type 2 một cách bừa bãi sẽ làm chiều phình to, nên các thuộc tính tần suất cao phải được cân bằng bằng cách điều chỉnh thiết kế qua tách mini-dimension hoặc fact hóa.
- Bảo đảm tính nhất quán/nguyên tử: "đóng phiên bản hiện có + mở phiên bản mới" của Type 2 phải được gói trong một giao dịch để ngăn trùng lặp is_current, chồng lấn khoảng (overlap), và khoảng trống (gap), và việc kiểm tra tính liên tục của khoảng hiệu lực sau nạp phải được tự động hóa thành một bài kiểm thử chất lượng dữ liệu. Bảo đảm tính idempotent ([[idempotency]]) để ngăn tạo phiên bản trùng lặp khi nạp lại cũng là thiết yếu.
- Triển vọng và công nghệ liên quan: Kết hợp với CDC ([[change-data-capture]]), SCD gần thời gian thực thay vì theo lô trở nên khả thi, và các định dạng bảng mở của lakehouse, dbt snapshot, và các bảng thời gian phiên bản hệ thống đang nâng việc triển khai SCD lên mức khai báo và chuẩn hóa. Tuy nhiên, dù dùng công nghệ nào, bản thân quy tắc nghiệp vụ "cách diễn giải quá khứ" không được tự động hóa, nên việc định nghĩa rõ ràng chính sách lịch sử phải đi trước lựa chọn công nghệ.
Tài liệu tham khảo
- Kimball Group, "Slowly Changing Dimension (SCD)" — https://www.kimballgroup.com/data-warehouse-business-intelligence-resources/kimball-techniques/dimensional-modeling-techniques/
- dbt Labs, "Snapshots" — https://docs.getdbt.com/docs/build/snapshots
- Delta Lake Documentation, "Slowly changing data (SCD) Type 2 operation into Delta tables" — https://docs.delta.io/latest/delta-update.html
Tóm tắt một câu: SCD là kỹ thuật quy định cách lưu trữ và theo dõi các thay đổi thuộc tính chậm trong một chiều của kho dữ liệu, triển khai quy tắc nghiệp vụ "cách diễn giải quá khứ" bằng cách lựa chọn — theo từng thuộc tính — giữa ghi đè (Type 1), thêm dòng lịch sử đầy đủ (Type 2), cột giá trị trước đó (Type 3), và hỗn hợp (Type 6).