📚 Qlik Sense Kurs – Artikel 10 von 28
← Vorheriger Artikel: Synthetic Keys & Circular References auflösen
→ Nächster Artikel: Fact vs Dimension – Design-Entscheidungen
Star Schema in Qlik – Performance & Klarheit
Was können Sie in 25 Minuten über Star Schema in Qlik lernen?
Nach diesem Guide können Sie:
- Star Schema Architektur in Qlik implementieren für 3-8x bessere Expression-Performance
- Fact vs Dimension Entscheidungen treffen die Memory-Verbrauch um 40-60% reduzieren
- Saubere Business-Hierarchien modellieren ohne Circular References oder Synthetic Keys
Zeitinvestition: 25 Min Lesen + 4 Std Hands-on
Voraussetzung: Kenntnisse in Synthetic Keys & Circular References und grundlegende Table Relationships
Quick Win: In 15 Minuten ein funktionierendes Fact-Dimension-Modell mit sofortiger Performance-Steigerung
Wie starte ich mit meinem ersten Star Schema in Qlik?
Das Problem: Ihre Umsatzdaten sind in denormalisierter Form (eine große Tabelle) und Expressions werden bei steigenden Datenmengen immer langsamer.
Lösung in 4 Schritten:
- Identifizieren Sie Transaktionsdaten (Facts) vs. Beschreibende Daten (Dimensions)
- Extrahieren Sie Dimensions in separate Tabellen mit eindeutigen Keys
- Behalten Sie nur Keys und Measures in der Fact-Tabelle
- Nutzen Sie Qlik’s automatische Associations zwischen Facts und Dimensions
// Ausgangslage: Denormalisierte Umsatztabelle
SalesFlat:
LOAD * FROM [lib://Data/sales_flat.csv];
// Probleme: 10M Rows x 25 Spalten = redundante Daten, langsame Aggregationen
// Star Schema: Fact-Tabelle (nur Transaktionen + Keys)
Sales_Fact:
LOAD
SalesID,
CustomerID, // FK zu Customer Dimension
ProductID, // FK zu Product Dimension
DateID, // FK zu Date Dimension
SalesAmount, // Measure
Quantity, // Measure
Discount // Measure
FROM [lib://Data/sales_flat.csv];
// Customer Dimension (beschreibende Attribute)
Customer_Dim:
LOAD DISTINCT
CustomerID, // PK
CustomerName,
CustomerSegment,
CustomerRegion,
CustomerCountry
FROM [lib://Data/sales_flat.csv];
// Product Dimension (beschreibende Attribute)
Product_Dim:
LOAD DISTINCT
ProductID, // PK
ProductName,
ProductCategory,
ProductSubCategory,
ProductBrand,
ProductUnitPrice
FROM [lib://Data/sales_flat.csv];
// Date Dimension (Zeit-Hierarchien)
Date_Dim:
LOAD DISTINCT
Date(SalesDate) as DateID, // PK
Year(SalesDate) as Year,
Month(SalesDate) as Month,
Week(SalesDate) as Week,
WeekDay(SalesDate) as WeekDay
FROM [lib://Data/sales_flat.csv];
Erklärung:
- Fact-Tabelle: Enthält nur Transaktions-Keys und numerische Measures. Hohe Granularität, viele Rows.
- Dimension-Tabellen: Enthalten beschreibende Attribute für Facts. Niedrige Granularität, wenige Rows.
- Automatische Associations: CustomerID in beiden Tabellen → Qlik verknüpft automatisch ohne JOINs.
Performance: 10M Rows: Denormalisiert 45s Expression-Time → Star Schema 8s Expression-Time (5,6x Speedup)
Checkpoint: Sehen Sie im Datenmodell eine zentrale Fact-Tabelle mit mehreren Dimension-Tabellen drumherum? → Perfekt! Immer noch eine große Tabelle? → Troubleshooting
Für systematische Modellierung siehe Fact vs Dimension Design.
Welches Star Schema-Pattern für Ihr Projekt?
Wählen Sie die Star Schema-Variante basierend auf Datenvolumen, Business-Komplexität und Performance-Anforderungen:
| Pattern | Fact-Rows | Dimensions | Komplexität | Performance | Ideal für |
|---|---|---|---|---|---|
| Simple Star | < 5M | 3-8 Dims | Niedrig | Gut | Standard BI, Dashboards, Prototypen |
| Multiple Facts | 5M – 50M | 5-15 Dims | Mittel | Sehr Gut | Enterprise BI, unterschiedliche Granularitäten |
| Conformed Dims | > 50M | 10-30 Dims | Hoch | Optimal | Data Warehouse, Multi-Subject-Area, Enterprise |
Legende:
- Fact-Rows: Anzahl Transaktionszeilen in der größten Fact-Tabelle
- Dimensions: Anzahl separater Dimension-Tabellen im Modell
- Komplexität: Entwicklungsaufwand und Wartungs-Overhead
- Performance: Expression-Geschwindigkeit und Memory-Effizienz
Wie funktioniert Methode 1: Simple Star Schema in Qlik?
Das Problem
Flache Tabellen-Strukturen funktionieren bei kleinen Datenmengen, werden aber bei Growth schnell zum Performance-Problem. Redundante Daten verbrauchen Memory und Aggregationen müssen über alle Spalten iterieren statt nur über relevante Facts.
Die Lösung
Eine zentrale Fact-Tabelle (transaktionale Daten) umgeben von mehreren Dimension-Tabellen (Master-Data). Jede Dimension hat einen Primary Key, Facts haben Foreign Keys zu den Dimensions.
// Schritt 1: Fact-Tabelle definieren (Granularität = ein Sales Record)
Sales_Fact:
LOAD
SalesID, // Primary Key der Transaktion
CustomerID, // FK → Customer_Dim
ProductID, // FK → Product_Dim
Date(SalesDate) as DateID, // FK → Date_Dim
EmployeeID, // FK → Employee_Dim
SalesAmount, // Measure: Was wird aggregiert
Quantity, // Measure: Was wird aggregiert
Discount, // Measure: Was wird aggregiert
CommissionRate // Measure: Was wird aggregiert
FROM [lib://Data/sales_transactions.csv];
// Schritt 2: Customer Dimension (alle Kunden-Attribute)
Customer_Dim:
LOAD DISTINCT
CustomerID, // Primary Key
CustomerName,
CustomerSegment, // Hier: Premium, Standard, Basic
CustomerRegion,
CustomerCountry,
CustomerCreditLimit,
CustomerSignupDate
FROM [lib://Data/customers.csv]; // Separate Master-Data Quelle
// Schritt 3: Product Dimension (alle Produkt-Attribute)
Product_Dim:
LOAD DISTINCT
ProductID, // Primary Key
ProductName,
ProductCategory, // Hier: Electronics, Clothing, Books
ProductSubCategory,
ProductBrand,
ProductUnitPrice,
ProductCost,
ProductLaunchDate
FROM [lib://Data/products.csv]; // Separate Master-Data Quelle
// Schritt 4: Employee Dimension (alle Mitarbeiter-Attribute)
Employee_Dim:
LOAD DISTINCT
EmployeeID, // Primary Key
EmployeeName,
EmployeeDepartment, // Hier: Sales, Marketing, Support
EmployeeTitle,
EmployeeHireDate,
EmployeeManager
FROM [lib://Data/employees.csv]; // Separate Master-Data Quelle
// Schritt 5: Date Dimension (Zeit-Hierarchien für bessere Navigation)
Date_Dim:
LOAD
DateID,
Year(DateID) as Year,
Month(DateID) as Month,
MonthName(DateID) as MonthName,
Quarter(DateID) as Quarter,
Week(DateID) as Week,
WeekDay(DateID) as WeekDay,
Day(DateID) as Day
RESIDENT Sales_Fact;
// Hier: Generiert aus Sales-Daten, alternativ: Master Calendar
Erklärung der Strategie:
- Fact-Granularität: Ein Record pro Transaktion/Event. Enthält nur Keys (für Joins) und Measures (für Aggregation).
- Dimension-Denormalisierung: Alle Attribute einer Business-Entity in einer Tabelle (Customer*). Wenige Rows, viele Spalten.
- Natural Keys: Business-Keys (CustomerID, ProductID) statt technische Surrogate Keys für bessere Verständlichkeit.
Performance-Kontext:
- 5M Facts + 4 Dimensions: Sum(SalesAmount) 3-5s vs Denormalized 15-25s
- Memory-Reduktion: 60-80% weniger RAM durch eliminierte Redundanz
- Development-Speed: 2-3x schnellere Expression-Entwicklung durch klare Struktur
⚠️ Die 3 häufigsten Fehler (und Lösungen)
Fehler 1: Measures in Dimension-Tabellen
- Symptom: Aggregationen ergeben falsche Summen, Measures werden doppelt gezählt
- Ursache: Numerische Werte (Prices, Amounts) wurden in Dimensions statt Facts platziert
- Lösung: Regel: Was aggregiert wird gehört in Facts, was beschreibt gehört in Dimensions
- Code: ProductUnitPrice in Product_Dim OK, SalesAmount nur in Sales_Fact
Fehler 2: Zu granulare Dimensions (Snowflake statt Star)
- Symptom: Viele kleine Dimension-Tabellen, komplexe Joins, schlechte Performance
- Ursache: Region → Country → Continent als separate Tabellen statt denormalisiert
- Lösung: Denormalisieren Sie Hierarchien in eine Dimension-Tabelle
- Code: Customer_Dim mit CustomerCountry UND CustomerContinent, nicht separate Country_Dim
Fehler 3: Business-Logik in Facts statt Dimensions
- Symptom: Calculated Fields überall im Code, schwer wartbar, inkonsistent
- Ursache: Derived Attributes (CustomerSegment, ProductCategory) werden in Expressions berechnet
- Lösung: Business-Logik ins Skript, Ergebnisse in Dimensions speichern
- Code:
If(SalesAmount > 10000, 'Premium', 'Standard') as CustomerSegmentin Customer_Dim
Best Practices
- Fact-Table Granularity Rule: Eine Zeile = eine Business-Transaktion. Niemals voraggregiert (das macht Qlik zur Laufzeit). Test: Können Sie aus jeder Fact-Zeile eine Rechnung/Order/Event rekonstruieren? Dann ist Granularität korrekt.
- Dimension Completeness: Jede Dimension muss ALL möglichen Attribute der Business-Entity enthalten. Nicht über mehrere Tabellen verteilen. CustomerSegment, CustomerRegion, CustomerCredit alle in Customer_Dim.
- Surrogate vs Natural Keys: Nutzen Sie Business-Keys (CustomerID aus ERP) statt technische (AutoIncrement). Bessere Debuggability und Business-User können Daten verstehen. Surrogate nur bei Slowly Changing Dimensions nötig.
- Date Dimension Standardization: Immer separate Date-Dimension mit vollständigen Hierarchien (Year, Quarter, Month, Week). Nie Date-Parsing in Expressions. Zentrale Date-Logik (Fiscal Year, Holiday Calendar) in Dimension vorbereiten.
✓ Checkpoint: Warum sollten Hierarchien (Region → Country → Continent) in einer Dimension-Tabelle stehen statt in separaten Tabellen?
Antwort anzeigen
Separate Hierarchie-Tabellen erzeugen Snowflake Schema → mehr Joins → schlechtere Performance. Qlik optimiert für Star Schema mit wenigen großen Dimensionen. Denormalisierte Hierarchien in einer Tabelle ermöglichen außerdem bessere Drill-Down Performance und einfachere Expression-Syntax.
Bei sehr komplexen Multi-Subject-Areas siehe Multiple Facts Pattern.
→ Nächster Schritt: Bei verschiedenen Granularitäten (Order-Level und OrderLine-Level) brauchen Sie Multiple Facts. Multiple Facts Star Schema implementieren.
Wie funktioniert Methode 2: Multiple Facts Star Schema in Qlik?
Das Problem
Business-Prozesse haben verschiedene Granularitäten: Order-Header (1x pro Bestellung) vs OrderLines (Nx pro Bestellung) vs Payments (Mx pro Bestellung). Eine einzige Fact-Tabelle kann nicht alle Business-Questions optimal beantworten.
Die Lösung
Mehrere Fact-Tabellen mit unterschiedlichen Granularitäten, die sich gemeinsame Dimension-Tabellen teilen. Jede Fact-Tabelle optimiert für spezifische Business-Fragen.
// Fact 1: Order Header (Granularität = eine Bestellung)
OrderHeader_Fact:
LOAD
OrderID, // PK für diesen Fact
CustomerID, // FK → Customer_Dim
EmployeeID, // FK → Employee_Dim
Date(OrderDate) as DateID, // FK → Date_Dim
OrderTotalAmount, // Measure: Gesamt-Bestellwert
OrderShippingCost, // Measure: Versandkosten
OrderDiscount, // Measure: Gesamt-Rabatt
OrderItemCount // Measure: Anzahl Positionen
FROM [lib://Data/orders.csv];
// Fact 2: Order Lines (Granularität = eine Bestellposition)
OrderLine_Fact:
LOAD
OrderLineID, // PK für diesen Fact
OrderID, // FK → OrderHeader_Fact (Drill-Through)
ProductID, // FK → Product_Dim
CustomerID, // FK → Customer_Dim (redundant aber performance-optimal)
Date(OrderDate) as DateID, // FK → Date_Dim (redundant)
LineQuantity, // Measure: Menge dieser Position
LineUnitPrice, // Measure: Einzelpreis
LineAmount, // Measure: Zeilensumme
LineDiscountPercent // Measure: Rabatt %
FROM [lib://Data/order_lines.csv];
// Fact 3: Payments (Granularität = eine Zahlung)
Payment_Fact:
LOAD
PaymentID, // PK für diesen Fact
OrderID, // FK → OrderHeader_Fact
CustomerID, // FK → Customer_Dim (redundant)
Date(PaymentDate) as PaymentDateID, // FK → Date_Dim
PaymentAmount, // Measure: Zahlungsbetrag
PaymentMethod, // Dimension: Credit Card, Bank Transfer
PaymentStatus // Dimension: Completed, Pending, Failed
FROM [lib://Data/payments.csv];
// Shared Dimensions (von allen Facts genutzt)
Customer_Dim:
LOAD DISTINCT
CustomerID, // Shared PK
CustomerName,
CustomerSegment,
CustomerRegion
FROM [lib://Data/customers.csv];
Product_Dim:
LOAD DISTINCT
ProductID, // Shared PK
ProductName,
ProductCategory,
ProductBrand
FROM [lib://Data/products.csv];
// Advanced: Date Dimension mit Role-Playing für verschiedene Date-Arten
Date_Dim:
LOAD
DateID,
Year(DateID) as Year,
Month(DateID) as Month,
Quarter(DateID) as Quarter,
WeekDay(DateID) as WeekDay
// Generiert alle Daten von Min bis Max aus allen Facts
WHERE DateID >= Date(Floor(MinDate)) AND DateID <= Date(Ceil(MaxDate));
Erklärung der Strategie:
- Granularitäts-Optimierung: Jeder Fact auf optimaler Ebene für typische Business-Questions.
- Controlled Redundancy: CustomerID in allen Facts für Performance, auch wenn durch OrderID ableitbar.
- Shared Dimensions: Eine Customer_Dim für alle Facts → konsistente Navigation und Filtering.
Performance-Kontext:
- Order-Level-Analysis (Revenue per Customer): OrderHeader_Fact 2-4s vs OrderLine_Fact 8-15s
- Product-Level-Analysis (Units Sold): OrderLine_Fact 3-6s vs OrderHeader_Fact unmöglich
- Payment-Analysis (Collection Performance): Payment_Fact 1-3s vs berechnet aus Orders 10-20s
⚠️ Die 3 häufigsten Fehler (und Lösungen)
Fehler 1: Inconsistent Dimensions zwischen Facts
- Symptom: CustomerSegment in OrderHeader_Fact anders als in Payment_Fact
- Ursache: Jede Fact-Tabelle holt Customer-Daten aus verschiedenen Quellen/Zeitpunkten
- Lösung: Eine zentrale Customer_Dim-Tabelle, alle Facts referenzieren diese
- Code: Nie Customer-Attribute direkt in Facts laden, immer via Customer_Dim
Fehler 2: Over-Normalization – zu viele granulare Facts
- Symptom: 15+ Fact-Tabellen für jeden Mini-Prozess, komplexe Expressions
- Ursache: Jede Datenbank-Tabelle wird zu separatem Fact ohne Business-Kontext
- Lösung: Konsolidieren Sie Facts nach Business-Prozessen, nicht technischen Tabellen
- Code: OrderLines + OrderCharges + OrderTaxes → ein OrderLine_Fact mit berechneten Totals
Fehler 3: Fehlende Bridge-Tabellen bei Many-to-Many
- Symptom: Falsche Aggregationen bei Kunden mit mehreren Adressen oder Produkten mit mehreren Kategorien
- Ursache: M:N-Beziehungen wurden nicht als separate Link-Tables modelliert
- Lösung: Bridge-Tables für M:N, Allocation-Factors für korrekte Verteilung
- Code: Customer_Address_Bridge mit Weight-Faktoren für Primary/Secondary Address
Best Practices
- Fact-Consolidation-Rule: Maximal 5-8 Fact-Tabellen pro Subject-Area. Mehr verwirrt Business-User und erschwert Cross-Fact-Analysis. Regel: Ein Fact pro Major Business Process (Sales, Purchases, Production, Service).
- Redundant Foreign Keys: CustomerID in allen Facts auch wenn über OrderID ableitbar. Performance-Gain überwiegt Normalisierung. Ausnahme: High-Cardinality Keys (OrderID in Payment) nur wenn wirklich benötigt.
- Date Role-Playing: Eine Date_Dim, aber mehrere Rollen (OrderDate, ShipDate, PaymentDate). Verwenden Sie Aliase in Expressions:
Sum({<OrderDate={'2024'}>} Amount)vsSum({<PaymentDate={'2024'}>} Amount). - Fact-to-Fact Relationships: Dokumentieren Sie bewusst wie Facts zusammenhängen (Order → OrderLine → Payment). Bridge-Tabellen für M:N, Drill-Through-Keys für 1:N. Niemals direkte Associations zwischen Facts ohne Bridge.
✓ Checkpoint: Warum sollte CustomerID sowohl in OrderHeader_Fact als auch in OrderLine_Fact stehen, obwohl es über OrderID ableitbar ist?
Antwort anzeigen
Performance und Flexibility. Direkte CustomerID in OrderLine_Fact ermöglicht schnelle Customer-to-Product-Analysis ohne Join über OrderHeader. Qlik kann außerdem bessere Indexing und Memory-Optimization durchführen. Der Memory-Overhead ist minimal verglichen mit dem Performance-Gain bei komplexen Expressions.
Für Enterprise-Scale mit 50+ Facts siehe Conformed Dimensions Pattern.
→ Nächster Schritt: Bei Enterprise-Umgebungen mit vielen Subject-Areas brauchen Sie Conformed Dimensions. Conformed Dimensions implementieren.
Was sind Conformed Dimensions in Methode 3?
Das Problem
Enterprise-Umgebungen haben multiple Subject-Areas (Sales, Marketing, Finance, Operations) mit eigenen Fact-Tabellen. Ohne Koordination entstehen inkonsistente Dimension-Definitionen → Business-User sehen verschiedene «Wahrheiten» je nach Datenbereich.
Die Lösung
Zentrale, standardisierte Dimension-Tabellen die von allen Subject-Areas geteilt werden. Conformed Dimensions gewährleisten einheitliche Business-Sicht und ermöglichen Cross-Subject-Area-Analysis.
// Conformed Dimension 1: Master Customer (für alle Subject Areas)
Customer_Conformed:
LOAD
CustomerID, // Standardized Business Key
CustomerName,
CustomerSegment, // Consistent: Premium, Gold, Silver, Bronze
CustomerRegion, // Consistent: North, South, East, West
CustomerCountry, // Consistent: ISO Country Codes
CustomerTier, // Business Rule: Based on 12-month Revenue
CustomerSignupDate,
CustomerStatus, // Active, Inactive, Suspended
CustomerCreditRating, // A, B, C, D (Enterprise-wide Standard)
CustomerIndustryCode, // NAICS Standard Classification
// Calculated Fields für Enterprise Consistency
If(CustomerTier = 'Enterprise', 1, 0) as IsEnterpriseCustomer,
If(Year(CustomerSignupDate) = Year(Today()), 1, 0) as IsNewCustomer
FROM [lib://MasterData/Customer_Master.qvd] (qvd);
// Subject Area 1: Sales Facts
Sales_Fact:
LOAD
SalesID,
CustomerID, // References Customer_Conformed
ProductID, // References Product_Conformed
Date(SalesDate) as DateID, // References Date_Conformed
SalesRepID, // References Employee_Conformed
SalesAmount,
SalesQuantity,
SalesDiscount
FROM [lib://Sales/sales_transactions.qvd] (qvd);
// Subject Area 2: Marketing Facts
Campaign_Fact:
LOAD
CampaignID,
CustomerID, // Same Customer_Conformed as Sales
Date(CampaignDate) as DateID, // Same Date_Conformed as Sales
CampaignType,
CampaignCost,
CampaignImpressions,
CampaignClicks,
CampaignConversions
FROM [lib://Marketing/campaigns.qvd] (qvd);
// Subject Area 3: Service Facts
Service_Fact:
LOAD
ServiceTicketID,
CustomerID, // Same Customer_Conformed
ProductID, // Same Product_Conformed
Date(ServiceDate) as DateID, // Same Date_Conformed
ServiceRepID, // References Employee_Conformed
ServiceType,
ServiceDuration,
ServiceCost,
ServiceSatisfactionScore
FROM [lib://Service/service_tickets.qvd] (qvd);
// Conformed Product Dimension (shared across all Subject Areas)
Product_Conformed:
LOAD
ProductID, // Standardized across all systems
ProductName,
ProductCategory, // L1: Electronics, Clothing, Books
ProductSubCategory, // L2: Smartphones, Laptops, Accessories
ProductBrand,
ProductLaunchDate,
ProductStatus, // Active, Discontinued, Phase-Out
ProductProfitMargin, // Calculated by Finance team
// Calculated Business Rules
If(ProductProfitMargin > 0.4, 'High Margin',
If(ProductProfitMargin > 0.2, 'Medium Margin', 'Low Margin')) as ProductProfitSegment
FROM [lib://MasterData/Product_Master.qvd] (qvd);
// Conformed Date Dimension (enterprise calendar)
Date_Conformed:
LOAD
DateID,
Year(DateID) as Year,
Month(DateID) as Month,
Quarter(DateID) as Quarter,
Week(DateID) as Week,
WeekDay(DateID) as WeekDay,
// Enterprise-specific Business Calendar
If(Month(DateID) >= 7, Year(DateID), Year(DateID)-1) as FiscalYear, // Fiscal Year starts July
If(WeekDay(DateID) >= 1 and WeekDay(DateID) <= 5, 1, 0) as IsBusinessDay,
If(Match(DateID, '2024-01-01', '2024-07-04', '2024-12-25'), 1, 0) as IsHoliday
FROM [lib://MasterData/Calendar_Master.qvd] (qvd);
// Conformed Employee Dimension
Employee_Conformed:
LOAD
EmployeeID,
EmployeeName,
EmployeeDepartment, // Sales, Marketing, Service, Finance
EmployeeTitle,
EmployeeRegion, // Same regions as Customer_Conformed
EmployeeHireDate,
EmployeeManager,
EmployeeStatus // Active, On Leave, Terminated
FROM [lib://MasterData/Employee_Master.qvd] (qvd);
Erklärung der Strategie:
- Single Source of Truth: Eine Customer_Conformed für Sales, Marketing, Service → einheitliche Customer-Sicht.
- Cross-Subject Analysis: Customer Revenue (Sales) vs Marketing Spend (Campaigns) vs Service Cost (Support) → ROI-Analysis möglich.
- Business Rule Centralization: FiscalYear-Definition, CustomerTier-Logic zentral in Dimensions → keine Code-Duplikation.
Performance-Kontext:
- Cross-Subject-Expressions: Customer LTV (3 Facts) 8-15s vs separate Models 45-90s
- Consistent Aggregations: CustomerSegment-Definitions identisch across all Apps
- Memory-Efficiency: Shared Dimensions 40-60% weniger Memory als duplicate Dimensions
⚠️ Die 3 häufigsten Fehler (und Lösungen)
Fehler 1: Dimension-Proliferation – zu viele «Conformed» Varianten
- Symptom: Customer_Sales, Customer_Marketing, Customer_Service als separate Dimensionen
- Ursache: Jedes Team erstellt eigene Customer-Definition weil gemeinsame zu komplex
- Lösung: Eine echte Customer_Conformed + Subject-Area-spezifische Attribute in Facts oder Bridge-Tables
- Code: Customer_Marketing_Attributes als separate Tabelle, nicht Customer_Marketing_Dim
Fehler 2: Governance-Vakuum – keine zentrale Dimension-Ownership
- Symptom: Conformed Dimensions werden inkonsistent von verschiedenen Teams modifiziert
- Ursache: Keine klare Verantwortlichkeit für Master-Data-Management
- Lösung: Data Governance Board definiert Dimension-Owner pro Conformed Dimension
- Code: Customer_Conformed owned by Sales Ops, Product_Conformed owned by Product Management
Fehler 3: Over-Conforming – zu viele Attribute in Conformed Dimensions
- Symptom: Customer_Conformed hat 50+ Spalten, wird unhandlich und langsam
- Ursache: Jedes Subject-Area-Team fügt «ihre» Customer-Attribute hinzu
- Lösung: Core Conformed (10-15 Attribute) + Subject-Area-Extensions (separate Tables)
- Code: Customer_Core_Conformed (Name, Segment, Region) + Customer_Sales_Extension (Territory, Rep)
Best Practices
- Dimension-Ownership-Matrix: Definieren Sie explizit wer welche Conformed Dimension maintained (Customer → Sales Ops, Product → Product Mgmt, Employee → HR). Change-Requests gehen über Dimension-Owner. Prevents Chaos und Inconsistencies.
- Core vs Extended Attributes: Conformed Dimensions enthalten nur universell relevante Attribute (Name, Status, Hierarchy). Subject-Area-spezifische Attribute in Extension-Tables oder direkt in Facts. Keeps Dimensions focused und maintainable.
- Version-Control für Dimensions: Conformed Dimensions sind kritische Enterprise-Assets. Git-basierte Version-Control, Change-Approval-Process, Rollback-Capability. Jeden Change tracken mit Business-Justification.
- Cross-Subject-Validation: Automated Tests dass Customer-Revenue (Sales) + Customer-Cost (Service) + Customer-Acquisition-Cost (Marketing) = schlüssige Customer-P&L. Business-Logic-Consistency across Subject-Areas validieren.
✓ Checkpoint: Warum sollten FiscalYear-Definitionen in der Date_Conformed stehen statt in jeder App separat berechnet werden?
Antwort anzeigen
Consistency und Performance. Wenn Sales-App FiscalYear anders berechnet als Finance-App entstehen unterschiedliche «YTD»-Zahlen → Business-Confusion. Zentrale Definition in Conformed Dimension gewährleistet enterprise-wide Consistency. Performance-Bonus: Berechnung einmal im ETL statt bei jeder Expression.
Für vollständige Enterprise-Implementation siehe Data Governance Frameworks.
→ Nächster Schritt: Conformed Dimensions erfordern Enterprise Data Governance. Data Governance Framework implementiert Standards und Qualitätssicherung.
Wie vergleicht man die Leistung aller Star Schema-Patterns?
Diese Benchmarks basieren auf typischen Enterprise-Datenvolumina (Standard-Hardware: 32 GB RAM, SSD, optimierte QVD-Loads).
| Pattern | Expressions (5M Facts) | Cross-Subject-Analysis | Memory (Peak) | Development-Speed | Maintenance | Enterprise-Ready |
|---|---|---|---|---|---|---|
| Denormalized Flat | 15-25s | Nicht möglich | 3,2 GB | Schnell | Hoch | Nein |
| Simple Star | 3-6s | Begrenzt | 1,8 GB | Mittel | Mittel | Für kleinere Orgs |
| Multiple Facts | 2-4s | Gut | 2,1 GB | Mittel | Mittel-Hoch | Ja |
| Conformed Dims | 2-3s | Excellent | 1,9 GB | Langsam | Niedrig | Optimal |
Legende:
- Expressions: Durchschnittliche Zeit für Sum(Amount) by Customer, Product für 5M Fact-Rows
- Cross-Subject-Analysis: Fähigkeit Customer-LTV über Sales + Marketing + Service zu berechnen
- Memory (Peak): Maximaler RAM-Verbrauch während Load + erste Expression-Berechnung
- Development-Speed: Zeit von Requirements zu funktionsfähiger App
- Maintenance: Langfristiger Aufwand für Änderungen, neue Requirements, Debugging
Interpretation: Conformed Dimensions haben höchste Initial-Complexity aber beste Long-Term-Performance und Maintainability. Multiple Facts sind Sweet-Spot für mittlere Enterprise-Umgebungen. Simple Star für Teams die schnell starten wollen.
Wie löse ich häufige Probleme im Star Schema in Qlik?
Alphabetischer Index:
- Aggregationen ergeben falsche Summen
- Circular References trotz Star Schema
- Facts verbinden sich nicht mit Dimensions
- Performance schlechter nach Star Schema Conversion
- Synthetic Keys zwischen Facts und Dimensions
- Wrong Granularity – zu hohe oder niedrige Aggregation
Wie beeinflussen Aggregationen die Summen im Star Schema in Qlik?
Symptom: Sum(SalesAmount) in Star Schema ist anders als in der ursprünglichen Flat Table
Häufigste Ursachen:
- Measures in Dimensions statt Facts → Lösung: Numerische Werte nur in Fact-Tables, Dimensions nur descriptive Attribute
- Many-to-Many ohne Bridge-Table → Lösung: M:N-Beziehungen über separate Bridge-Tables modellieren
- Duplicate Records in Facts → Lösung: DISTINCT oder GROUP BY in Fact-Load, prüfen auf echte Duplicates
Debug-Schritte:
- Vergleichen Sie Row-Count:
TRACE NoOfRows('Sales_Fact');vs Original-Table - Testen Sie mit einfachem
Sum(SalesAmount)ohne Dimensions → sollte identisch sein - Prüfen Sie ob Measures versehentlich in Dimension-Tabellen gelandet sind
Code-Fix:
// Wrong: Amount in Dimension
Customer_Dim: LOAD CustomerID, CustomerName, CustomerRevenue FROM customers.csv;
// Correct: Only descriptive attributes in Dimensions
Customer_Dim: LOAD CustomerID, CustomerName, CustomerSegment FROM customers.csv;
// Revenue calculated from Facts: Sum(SalesAmount)
Wie verbindet man Facts mit Dimensions im Star Schema in Qlik?
Symptom: Fact- und Dimension-Tabellen stehen isoliert im Datenmodell, keine Associations
Häufigste Ursachen:
- Key-Field-Name-Mismatch → Lösung: CustomerID in Facts muss exakt CustomerID in Dimensions heißen
- Data-Type-Mismatch → Lösung: String vs Number Keys können nicht automatisch verknüpft werden
- Key-Values nicht vorhanden → Lösung: Orphaned Records in Facts ohne entsprechende Dimension-Records
Debug-Schritte:
- Prüfen Sie Field-Namen:
TRACE "Fact Fields: " & FieldName(1, 'Sales_Fact'); - Testen Sie Key-Overlap:
Count(DISTINCT CustomerID)in beiden Tabellen - Checken Sie Data-Types mit Sample-Werten
Code-Fix:
// Ensure consistent data types and field names
Sales_Fact:
LOAD
Text(CustomerID) as CustomerID, // Force to text
SalesAmount
FROM sales.csv;
Customer_Dim:
LOAD
Text(CustomerID) as CustomerID, // Same type as Facts
CustomerName
FROM customers.csv;
Warum ist die Performance nach der Star Schema Conversion schlechter?
Symptom: Expressions dauern länger als vorher mit denormalisierter Tabelle
Häufigste Ursachen:
- Zu viele kleine Dimensions → Lösung: Konsolidieren Sie verwandte Dimensionen (Snowflake → Star)
- Non-optimized QVD Loads → Lösung: Prüfen Sie dass alle Tabellen als optimized QVDs geladen werden
- Over-Normalization → Lösung: Denormalisieren Sie Hierarchien in Dimensions
Debug-Schritte:
- Messen Sie Memory-Verbrauch vor/nach:
DocumentSize() - Profiling: Welche spezifischen Expressions sind langsamer geworden?
- Prüfen Sie QVD-Load-Times: «optimized» vs «non-optimized» im Log
Code-Fix:
// Consolidate related dimensions
Customer_Dim:
LOAD
CustomerID,
CustomerName,
CustomerRegion, // Denormalized instead of separate Region_Dim
CustomerCountry, // Denormalized instead of separate Country_Dim
CustomerContinent // Full hierarchy in one table
FROM customers.csv;
Siehe auch: QVD Performance Optimization für Memory-optimierte Star Schemas
Was sind die nächsten Schritte für das Star Schema in Qlik?
Sie können jetzt performante, saubere Star Schemas aufbauen die Enterprise-Anforderungen erfüllen. Für Production-Ready Implementation vertiefen Sie diese Themen:
1. Advanced Modeling: Star Schemas sind die Basis für komplexere Patterns. Fact vs Dimension Design Decisions zeigt Ihnen wie Sie optimale Business-Entity-Zuordnungen treffen.
2. Performance-Maximierung: Saubere Modelle brauchen optimierte Load-Patterns. QVD-Optimierung für Star Schemas erreicht maximale Memory-Effizienz und Load-Geschwindigkeit.
3. Enterprise-Governance: Conformed Dimensions erfordern Data Governance. Enterprise Data Governance Framework etabliert Standards, Quality-Gates und Change-Management für skalierbare Star Schema-Architekturen.
Was sind die nächsten Schritte im Kurs zu Star Schema in Qlik?
Phase 1 & 2 abgeschlossen! Sie haben die Grundlagen (Artikel 1-5) und erweiterte Datenverarbeitung (Artikel 6-10) gemeistert.
Kommende Phasen:
- Phase 3 (Artikel 11-15): Data Modeling Concepts
- Phase 4 (Artikel 16-20): Advanced Development
- Phase 5 (Artikel 21-28): Enterprise & Operations
Verwandte Themen: