[Tech Blog #08 | Data Engineering] Data Warehouse Căn Bản: Bảng Fact, Bảng Dimension & Thiết Kế Star Schema Thực Chiến
![[Tech Blog #08 | Data Engineering] Data Warehouse Căn Bản: Bảng Fact, Bảng Dimension & Thiết Kế Star Schema Thực Chiến](/uploads/ai-images/cover-data-warehouse-star-schema.png)
1. Đặt vấn đề: Tại sao không thể làm báo cáo trực tiếp trên CSDL ứng dụng?
Khi một ứng dụng web hay ứng dụng di động hoạt động, cơ sở dữ liệu của nó (gọi là OLTP - Online Transaction Processing) được tối ưu hóa cho các thao tác thêm, sửa, xóa cực nhanh và tuân thủ chuẩn 3NF (như chúng ta đã tìm hiểu ở [Tech Blog #04]).
Nhưng hãy tưởng tượng kịch bản sau:
Giám đốc yêu cầu bộ phận phân tích dữ liệu chạy một báo cáo: "Thống kê tổng doanh thu, số lượng bán ra của từng danh mục sản phẩm theo từng quý trong 3 năm qua trên tất cả các chi nhánh".
Nếu bạn chạy câu truy vấn SQL này trực tiếp trên CSDL ứng dụng:
- Làm nghẽn hoặc sập ứng dụng: Câu lệnh sẽ phải quét qua hàng chục triệu bản ghi và
JOINqua 8–10 bảng chuẩn hóa 3NF, chiếm dụng toàn bộ CPU và RAM của hệ thống. Khách hàng đang mua sắm trên web sẽ bị xoay vòng hoặc không thể thanh toán được. - Cấu trúc quá phức tạp cho người làm phân tích: Một Data Analyst sẽ phải vật lộn với hàng chục bảng nhỏ li ti chỉ để lấy ra một con số doanh thu đơn giản.
Để giải quyết vấn đề này, các kỹ sư dữ liệu xây dựng một hệ thống tách biệt hoàn toàn gọi là Kho dữ liệu (Data Warehouse - DWH). Và phương pháp thiết kế dữ liệu thống trị trong Data Warehouse suốt nhiều thập kỷ qua chính là Mô hình hóa chiều (Dimensional Modeling) của tác giả Ralph Kimball.
2. Cặp đôi quyền lực: Bảng Fact & Bảng Dimension
Trong một Data Warehouse, mọi dữ liệu đều được phân loại thành hai nhóm bảng duy nhất: Bảng Fact và Bảng Dimension.
+-------------------+
| dim_customer |
+-------------------+
|
| (1:N)
+----------------+ | +----------------+
| dim_date |---+ | +---| dim_product |
+----------------+ | | | +----------------+
| v |
+-------------+
| fact_sales | <--- TRUNG TÂM (Fact Table)
+-------------+
^
| (1:N)
|
+-------------------+
| dim_store |
+-------------------+
2.1. Bảng Fact (Bảng Sự Kiện / Đo Lường)
- Bản chất: Ghi lại những sự kiện nghiệp vụ đã diễn ra trong thế giới thực (ví dụ: một giao dịch bán hàng, một lượt nhấp chuột, một lần rút tiền ATM).
- Thành phần chứa bên trong:
- Các chỉ số số học (Measures / Metrics): Có thể tính toán cộng, trừ, nhân, chia (ví dụ:
doanh_thu,so_luong_ban,tien_chiet_khau,thue_vat). - Các khóa ngoại (Foreign Keys): Liên kết đến các bảng Dimension để biết bối cảnh của sự kiện.
- Các chỉ số số học (Measures / Metrics): Có thể tính toán cộng, trừ, nhân, chia (ví dụ:
- Đặc điểm: Tăng trưởng kích thước cực nhanh theo thời gian (hàng triệu, hàng tỷ dòng), dữ liệu gần như chỉ ghi thêm (
Append-only), không bao giờ sửa đổi lịch sử.
2.2. Bảng Dimension (Bảng Chiều / Bối Cảnh)
- Bản chất: Cung cấp bối cảnh xung quanh sự kiện. Nó trả lời cho bộ câu hỏi kinh điển: Ai? Cái gì? Ở đâu? Khi nào? Như thế nào?
- Khách hàng nào mua?
dim_customer - Mua sản phẩm gì?
dim_product - Mua tại cửa hàng nào?
dim_store - Mua vào ngày nào, thứ mấy, quý mấy?
dim_date
- Khách hàng nào mua?
- Thành phần chứa bên trong: Các trường văn bản định tính dùng để lọc (FILTER), phân nhóm (GROUP BY) hoặc cắt lát dữ liệu (SLICING).
- Đặc điểm: Số lượng dòng ít hơn bảng Fact rất nhiều, ít biến động.
3. Kiến trúc Star Schema vs. Snowflake Schema
3.1. Star Schema (Mô hình Ngôi sao)
- Đặc điểm: Bảng Fact nằm ở chính giữa, các bảng Dimension bao bọc xung quanh giống như các cánh sao.
- Triết lý: Chấp nhận phi chuẩn hóa (Denormalization) trong các bảng Dimension. Ví dụ trong bảng
dim_product, ta lưu luôn cả tên ngành hàng (category_name) và phân loại (subcategory_name) vào cùng 1 bảng thay vì tách riêng ra. - Ưu điểm vượt trội: Các câu truy vấn báo cáo chỉ cần
JOINđúng 1 bước từ Fact sang Dimension, giúp truy vấn siêu nhanh và câu lệnh SQL cực kỳ ngắn gọn, dễ hiểu.
3.2. Snowflake Schema (Mô hình Bông tuyết)
- Đặc điểm: Là mô hình ngôi sao nhưng các bảng Dimension được tiếp tục chuẩn hóa thành các bảng nhỏ hơn nữa (ví dụ:
dim_producttách thêm bảng condim_subcategory, rồi tách tiếpdim_category). - Nhược điểm: Làm tăng số lượng phép
JOINkhi truy vấn, khiến tốc độ đọc dữ liệu bị chậm đi đáng kể. Trong thực tế hiện đại (khi dung lượng ổ cứng đã rẻ), Star Schema luôn là lựa chọn ưu tiên hàng đầu.
Bảng so sánh nhanh
| Tiêu chí | Star Schema (Mô hình Ngôi sao) | Snowflake Schema (Mô hình Bông tuyết) |
|---|---|---|
| Mức độ chuẩn hóa | Thấp (Phi chuẩn hóa các bảng Dimension). | Cao (Chuẩn hóa các bảng Dimension về 2NF/3NF). |
| Số lượng phép JOIN | Rất ít (Chỉ 1 cấp giữa Fact và Dimension). | Nhiều (Phải JOIN qua nhiều tầng Dimension con). |
| Tốc độ truy vấn (Query Speed) | 🚀 Cực nhanh, tối ưu cho OLAP / BI Dashboard. | 🐢 Chậm hơn do tốn tài nguyên JOIN. |
| Dung lượng lưu trữ | Tốn dung lượng hơn một chút do lặp chuỗi. | Tiết kiệm dung lượng lưu trữ hơn. |
| Mức độ phổ biến trong thực tế | 90% các hệ thống DWH hiện đại sử dụng. | Ít dùng, chỉ phù hợp khi Dimension quá khổng lồ. |
4. Thực hành thực chiến: Khởi tạo Star Schema bằng SQL
Dưới đây là đoạn mã SQL chuẩn tạo một Data Mart bán lẻ theo mô hình Star Schema hoàn chỉnh:
-- =============================================================
-- BƯỚC 1: TẠO CÁC BẢNG DIMENSION (CHIỀU PHÂN TÍCH)
-- =============================================================
-- 1. Dimension Thời gian (Tránh việc hàm DATE_TRUNC phải chạy lại triệu lần)
CREATE TABLE dim_date (
date_key INT PRIMARY KEY, -- Định dạng YYYYMMDD (vd: 20260921)
full_date DATE NOT NULL,
day_of_week VARCHAR(15) NOT NULL, -- Thứ Hai, Thứ Ba...
month_name VARCHAR(15) NOT NULL, -- Tháng 1, Tháng 2...
quarter INT NOT NULL, -- Quý 1, 2, 3, 4
year INT NOT NULL,
is_weekend BOOLEAN NOT NULL -- Cờ đánh dấu ngày cuối tuần
);
-- 2. Dimension Khách hàng
CREATE TABLE dim_customer (
customer_key SERIAL PRIMARY KEY, -- Surrogate Key (Khóa thay thế của DWH)
customer_id VARCHAR(50) NOT NULL, -- Business Key (Mã gốc từ app nguồn)
full_name VARCHAR(100) NOT NULL,
gender VARCHAR(10),
customer_segment VARCHAR(50) -- Phân khúc: VIP, Khách quen, Khách mới
);
-- 3. Dimension Sản phẩm (Phi chuẩn hóa Category vào chung bảng)
CREATE TABLE dim_product (
product_key SERIAL PRIMARY KEY,
product_id VARCHAR(50) NOT NULL, -- Mã SKU từ nguồn
product_name VARCHAR(150) NOT NULL,
brand VARCHAR(100) NOT NULL,
category_name VARCHAR(100) NOT NULL, -- Lưu trực tiếp, không tách bảng phụ
cost_price NUMERIC(12, 2) NOT NULL
);
-- 4. Dimension Cửa hàng
CREATE TABLE dim_store (
store_key SERIAL PRIMARY KEY,
store_code VARCHAR(20) NOT NULL,
store_name VARCHAR(100) NOT NULL,
city VARCHAR(100) NOT NULL,
region VARCHAR(50) NOT NULL -- Miền Bắc, Miền Trung, Miền Nam
);
-- =============================================================
-- BƯỚC 2: TẠO BẢNG FACT BÁN HÀNG (TRUNG TÂM)
-- =============================================================
CREATE TABLE fact_sales (
sales_id BIGSERIAL PRIMARY KEY,
-- Các khóa ngoại kết nối đến 4 Dimension (Tạo thành hình cánh sao)
date_key INT NOT NULL REFERENCES dim_date(date_key),
customer_key INT NOT NULL REFERENCES dim_customer(customer_key),
product_key INT NOT NULL REFERENCES dim_product(product_key),
store_key INT NOT NULL REFERENCES dim_store(store_key),
-- Các chỉ số số học đo lường (Metrics / Measures)
quantity_sold INT NOT NULL CHECK (quantity_sold > 0),
unit_price NUMERIC(12, 2) NOT NULL,
discount_amount NUMERIC(12, 2) DEFAULT 0,
net_revenue NUMERIC(12, 2) NOT NULL -- Doanh thu thực = (quantity * unit_price) - discount
);
-- =============================================================
-- BƯỚC 3: TRUY VẤN BÁO CÁO KINH DOANH (CỰC KỲ ĐƠN GIẢN & NHANH)
-- =============================================================
-- Yêu cầu: Tính tổng doanh thu và số lượng bán theo Từng Quý năm 2026 và Danh mục sản phẩm
SELECT
d.year,
d.quarter,
p.category_name,
SUM(f.quantity_sold) AS total_items_sold,
SUM(f.net_revenue) AS total_revenue
FROM
fact_sales f
JOIN dim_date d ON f.date_key = d.date_key
JOIN dim_product p ON f.product_key = p.product_key
WHERE
d.year = 2026
GROUP BY
d.year,
d.quarter,
p.category_name
ORDER BY
d.quarter,
total_revenue DESC;
5. Khái niệm mở rộng: Surrogate Key là gì và vì sao cần nó?
Trong các bảng Dimension ở trên, bạn sẽ thấy xuất hiện hai loại khóa:
- Business Key (Natural Key): Ví dụ
customer_id = "KH_9981"do ứng dụng sinh ra. - Surrogate Key: Khóa thay thế dạng số nguyên tự tăng (
customer_key = 1, 2, 3...) do Data Warehouse tự quản lý.
Tại sao không dùng trực tiếp Business Key?
- Hiệu năng JOIN: Khóa ngoại dạng số nguyên (
INT) trong bảng Fact hàng tỷ dòng sẽ chiếm ít dung lượng bộ nhớ hơn rất nhiều và tốc độ so khớp (JOIN) nhanh hơn gấp bội so với chuỗiVARCHAR. - Lịch sử dữ liệu (SCD - Slowly Changing Dimensions): Giả sử khách hàng Nguyễn Văn A chuyển từ Hà Nội vào TP.HCM. Nếu dùng mã
KH_9981, bạn buộc phải ghi đè địa chỉ (làm sai lệch lịch sử doanh thu cũ của Hà Nội). Nhưng với Surrogate Key, bạn chỉ cần tạo thêm một dòng mới vớicustomer_key = 2mang địa chỉ TP.HCM, trong khi dòngcustomer_key = 1vẫn giữ địa chỉ Hà Nội cho các đơn hàng quá khứ.
6. Câu hỏi phỏng vấn thực tế (Interview Q&A)
Câu 1 (Mức độ: Entry / Junior)
Câu hỏi: "Làm thế nào để bạn phân biệt một bảng là Fact hay Dimension khi được bàn giao một cơ sở dữ liệu lạ?"
Gợi ý trả lời:
*"Dấu hiệu trực quan nhất để phân biệt:
- Bảng Fact chứa các chỉ số đo lường định lượng dạng số (Metrics) có thể tổng hợp được như doanh thu, số lượng, thời gian, kèm theo nhiều cột khóa ngoại (Foreign Keys). Kích thước của bảng Fact thường rất lớn và số dòng tăng liên tục theo thời gian.
- Bảng Dimension chứa các thông tin văn bản mô tả định tính (Attributes) như tên, địa chỉ, trạng thái, ngày tháng, được dùng làm điều kiện lọc (
WHERE) hoặc phân nhóm (GROUP BY). Kích thước bảng Dimension nhỏ hơn nhiều và có tốc độ thay đổi chậm."*
Câu 2 (Mức độ: Junior / Mid-level)
Câu hỏi: "Tại sao các hệ thống Data Warehouse hiện đại vẫn ưu tiên dùng Star Schema thay vì Snowflake Schema dù Star Schema gây lãng phí dung lượng lưu trữ hơn?"
Gợi ý trả lời:
"Lý do lớn nhất là Ưu tiên tốc độ truy vấn phân tích (Read Performance) hơn chi phí lưu trữ phần cứng.
Hiện nay, chi phí lưu trữ ổ đĩa đã trở nên rất rẻ, trong khi chi phí thời gian chờ đợi của người dùng và chi phí tài nguyên tính toán (CPU/RAM) khi thực hiện các phép JOIN phức tạp trong Snowflake Schema lại rất đắt đỏ.
Star Schema giúp giảm thiểu số lượng phép JOIN xuống mức tối đa (chỉ 1 cấp), giúp các hệ thống cơ sở dữ liệu dạng cột (Columnar Database) như ClickHouse, BigQuery hay Snowflake quét dữ liệu song song cực kỳ hiệu quả, đồng thời giúp mô hình dữ liệu trực quan, thân thiện cho đội ngũ phân tích (BI/Analyst) tự viết truy vấn mà không sợ nhầm lẫn."
7. Key Takeaways (Ghi nhớ nhanh)
- Bảng Fact ghi lại hành động và con số; Bảng Dimension cung cấp bối cảnh (Ai, Cái gì, Ở đâu, Khi nào).
- Star Schema là chuẩn mực vàng cho Data Warehouse nhờ giảm thiểu số lượng
JOIN, tối ưu hóa tốc độ báo cáo BI. - Luôn sử dụng Surrogate Key (Số nguyên) cho các bảng Dimension để tối ưu hiệu năng bộ nhớ và hỗ trợ theo dõi lịch sử dữ liệu (SCD).
- Bảng
dim_datelà bắt buộc: Luôn xây dựng sẵn một bảng thời gian chuyên dụng trong kho dữ liệu để tránh việc phải chạy các hàm biến đổi ngày tháng nặng nề trên hàng triệu dòng Fact.