🔗 Data Model

Data Model & Relationships

Star Schema, Snowflake Schema, relationship types, cross-filter direction — nền tảng để DAX hoạt động đúng và report chạy nhanh.

Star Schema — Chuẩn vàng
1 Fact table ở trung tâm, nhiều Dimension tables xung quanh
Dim_Date
PK DateID
Date, Year, Quarter
Month, MonthName
WeekDay, IsWeekend
Fact_Sales ⭐
PK SaleID
FK DateID
FK ProductID
FK CustomerID
FK RegionID
Qty, UnitPrice, Discount
Revenue, Cost, Profit
Dim_Product
PK ProductID
ProductName, SKU
Category, Brand
CostPrice, ListPrice
Dim_Customer
PK CustomerID
Name, Email, Phone
Segment, JoinDate
Dim_Region
PK RegionID
City, Province
Country, Zone
Tại sao Star Schema? (1) DAX chạy nhanh hơn (filter propagation đơn giản). (2) Relationships 1-to-many rõ ràng. (3) Dễ add dimension mới. (4) Reduces data duplication so với flat table.
✅ Fact Table
  • Chứa numeric measures (Revenue, Qty, Cost)
  • Chứa FK keys trỏ đến Dimension tables
  • Hàng triệu rows — narrow columns
  • Không chứa descriptive attributes
  • Ví dụ: Sales, Inventory, Budget, Forecast
📋 Dimension Table
  • Chứa descriptive attributes (Name, Category)
  • Có PK duy nhất (1 side của relationship)
  • Ít rows hơn Fact — wide columns
  • Được filter bởi slicers/visuals
  • Ví dụ: Date, Product, Customer, Region, Employee
🔗
Relationship Types
Cardinality và Cross-filter Direction
Type Ví dụ Ghi chú
1-to-Many ⭐ Dim_Product (1) → Fact_Sales (*) Loại phổ biến nhất, đây là chuẩn
1-to-1 Employee (1) ↔ EmployeeDetail (1) Dùng khi split bảng cho performance
Many-to-Many ⚠️ Orders (*) ↔ Products (*) Tránh nếu có thể. Dùng Bridge table
Cross-filter: Single Direction
Filter chảy 1 chiều: Dim → Fact. Khi filter Product, chỉ ảnh hưởng Sales — không ảnh hưởng ngược lại. Đây là default và recommended.
Cross-filter: Both ⚠️
Filter chảy 2 chiều. Nguy hiểm: có thể gây ambiguity và bugs khó debug. Chỉ dùng khi thực sự cần, ví dụ Many-to-Many qua bridge table.
Lỗi phổ biến: Bật bidirectional filter trên tất cả relationships để "cho chắc". Điều này gây ra circular dependency, DAX engine cảnh báo hoặc cho kết quả sai. Chỉ bật khi cần thiết và có lý do rõ ràng.
📅
Date Table — Bắt buộc phải có
Nền tảng để Time Intelligence hoạt động đúng
Tại sao cần Date Table riêng? Power BI cần 1 bảng Date liên tục không có ngày trống để Time Intelligence (YTD, MTD, SAMEPERIODLASTYEAR) hoạt động đúng. Cột date trong Fact table không đủ — có thể có ngày trống (ngày không có đơn hàng).
// Tạo Date Table bằng DAX (vào Modeling → New Table)
Dim_Date =
ADDCOLUMNS(
    CALENDAR(DATE(2020,1,1), DATE(2030,12,31)),
    "Year",         YEAR([Date]),
    "Quarter",      "Q" & FORMAT(CEILING(MONTH([Date])/3, 1), "0"),
    "QuarterNum",   CEILING(MONTH([Date])/3, 1),
    "Month",        MONTH([Date]),
    "MonthName",    FORMAT([Date], "MMMM"),
    "MonthShort",   FORMAT([Date], "MMM"),
    "WeekDay",      WEEKDAY([Date], 2),
    "WeekDayName",  FORMAT([Date], "dddd"),
    "IsWeekend",    IF(WEEKDAY([Date],2) >= 6, TRUE(), FALSE()),
    "YearMonth",    FORMAT([Date], "YYYY-MM"),
    "FiscalYear",   IF(MONTH([Date])>=4, YEAR([Date]), YEAR([Date])-1)
)

// Sau đó: Model View → Right-click Dim_Date → Mark as date table → chọn cột Date