LERNPFADE & KURSE

Fact vs Dimension – Design-Entscheidungen richtig treffen

Autor

Qlik Doktor

Oktober 6, 2025 · 7 Min. Lesezeit

📚 Qlik Sense Kurs – Artikel 11 von 28

Vorheriger Artikel: Star Schema in Qlik – Performance & Klarheit
Nächster Artikel: Link Tables für Many-to-Many Beziehungen

Fact vs Dimension – Design-Entscheidungen

Was ist der Unterschied zwischen Fact und Dimension? Facts enthalten transaktionale, messbare Daten (Umsätze, Mengen) – sie beantworten «Was ist passiert?». Dimensionen enthalten beschreibende Daten (Kunde, Produkt) – sie beantworten «Wer/Was/Wo/Wann?».

Was lernst Du über Fact vs Dimension und Design-Entscheidungen?

Nach diesem Guide kannst Du:

  1. Entscheiden ob Daten in eine Fact- oder Dimension-Tabelle gehören
  2. Die richtige Granularität für Facts definieren
  3. Performance-optimale Datenmodelle designen

Zeitinvestition: 15 Min Lesen + 2 Std Hands-on
Voraussetzung: Kenntnisse in Star Schema
Quick Win: In 10 Minuten weißt Du wie Du jede Tabelle richtig klassifizierst

Die Entscheidung: Fact oder Dimension?

Das Problem: Du hast eine Tabelle mit Umsatzdaten geladen und bist Dir nicht sicher: Solltest Du alle Felder in einer Tabelle lassen oder aufteilen in Facts und Dimensionen?

Die Lösung: Nutze einen einfachen Decision Tree: Sind die Daten transaktional und ändern sich häufig? → Fact. Beschreiben sie Entitäten und sind relativ stabil? → Dimension.

Wie wendet man Decision Tree in der Praxis an?

Stelle Dir diese drei Fragen:

1. Sind die Daten transaktional?

  • Ja → Wahrscheinlich eine Fact-Tabelle
  • Nein → Weiter zu Frage 2

2. Enthalten die Daten numerische Werte die aggregiert werden?

  • Ja (Sum, Avg, Count) → Fact-Tabelle
  • Nein → Dimension-Tabelle

3. Wie viele Zeilen hat die Tabelle?

  • Millionen von Zeilen → Fact-Tabelle
  • Tausende bis Hunderttausende → Dimension-Tabelle

Wie klassifiziert man Umsatzdaten in einem Beispiel?

// Original-Tabelle: Sales.csv
// OrderID, CustomerID, CustomerName, Region, ProductID, ProductName,
// Category, Amount, Quantity, OrderDate

// Was gehört wohin?

Analyse:

  • OrderID: Eindeutiger Schlüssel → Fact (Primary Key)
  • CustomerID: Referenz → Fact (Foreign Key zur Dimension)
  • CustomerName, Region: Beschreibend → Dimension
  • ProductID: Referenz → Fact (Foreign Key zur Dimension)
  • ProductName, Category: Beschreibend → Dimension
  • Amount, Quantity: Measures zum Aggregieren → Fact
  • OrderDate: Zeitstempel der Transaktion → Fact

Wie wählt man die richtige Struktur für Fact und Dimension aus?

// Fact-Tabelle: Nur Transaktionen + Keys + Measures
Facts_Sales:
LOAD
    OrderID,              // Primary Key
    CustomerID,           // Foreign Key
    ProductID,            // Foreign Key
    Date(OrderDate) as OrderDate,  // Foreign Key zur Date-Dimension
    Amount,               // Measure
    Quantity              // Measure
FROM [DataSales.csv]
(ooxml, embedded labels);

Erklärung: Die Fact-Tabelle enthält nur das Skelett der Transaktion – Schlüssel und Zahlen. Keine beschreibenden Texte.

// Dimension: Kunden-Attribute
Dim_Customer:
LOAD DISTINCT
    CustomerID,           // Primary Key
    CustomerName,
    Region,
    Country,
    City
FROM [DataSales.csv]
(ooxml, embedded labels);

Erklärung: Die Dimension enthält alle Informationen ÜBER den Kunden. Einmal pro Kunde, nicht bei jeder Bestellung wiederholt.

// Dimension: Produkt-Attribute
Dim_Product:
LOAD DISTINCT
    ProductID,            // Primary Key
    ProductName,
    Category,
    SubCategory,
    Brand
FROM [DataSales.csv]
(ooxml, embedded labels);

Erklärung: Auch hier: Alle Informationen ÜBER das Produkt, einmal pro Produkt.

Performance-Tipp: Mit dieser Aufteilung sparst Du 40-60% Speicher! Die Namen «Samsung Galaxy» und «Electronics» werden nicht millionenfach wiederholt, sondern stehen nur einmal in der Dimension.

Wie verstehe und wähle ich die richtige Granularität?

Die Granularität bestimmt den «Detail-Level» Deiner Fact-Tabelle. Das ist eine der wichtigsten Design-Entscheidungen!

Faustregel: Lade Daten so detailliert wie möglich (atomic level). Aggregieren kannst Du später immer noch – aber aus aggregierten Daten kannst Du keine Details mehr rekonstruieren!

Was sind die Granularitäts-Levels im Beispiel von Fact vs Dimension?

Option 1: Order-Level (Bestellungs-Ebene)

// Ein Record = eine Bestellung
Facts_Orders:
LOAD
    OrderID,              // Key
    CustomerID,
    OrderDate,
    OrderTotalAmount,     // Summe aller Positionen
    OrderItemCount        // Anzahl Artikel
FROM Orders;

Was Du damit analysieren kannst: Umsatz pro Bestellung, Durchschnittliche Bestellgröße
Was NICHT geht: Welche Produkte wurden in dieser Bestellung gekauft?

Option 2: Order-Line-Level (Positions-Ebene)

// Ein Record = eine Position in einer Bestellung
Facts_OrderLines:
LOAD
    OrderLineID,          // Eindeutiger Key
    OrderID,              // Bestellungs-Referenz
    ProductID,            // Welches Produkt?
    CustomerID,
    OrderDate,
    LineAmount,           // Betrag dieser Position
    LineQuantity          // Menge dieser Position
FROM OrderLines;

Was Du damit analysieren kannst: Alles von Option 1 (durch Aggregation) PLUS Produktanalysen, Cross-Selling, Warenkorbanalysen
Trade-off: Mehr Zeilen = mehr Speicher (aber dafür maximale Flexibilität)

Option 3: Tages-Aggregat (voraggregiert)

// Ein Record = ein Produkt pro Tag
Facts_DailySales:
LOAD
    ProductID,
    Date,
    Sum(Amount) as DailyAmount,
    Sum(Quantity) as DailyQuantity
FROM OrderLines
GROUP BY ProductID, Date;

Was Du damit analysieren kannst: Tagesumsätze, Trends
Was NICHT geht: Kundenanalysen, einzelne Bestellungen

Best Practice: Starte mit der detailliertesten Ebene (Order-Line). Wenn Performance-Probleme auftreten, kannst Du später immer noch eine aggregierte Tabelle zusätzlich (!) erstellen.

Wie vermeidet man typische Fehler bei Fact vs Dimension Design-Entscheidungen?

⚠️ Fehler 1: Measures in Dimensionen

Symptom: Deine Summen stimmen nicht, Zahlen werden mehrfach gezählt.

Falsch:

Dim_Product:
LOAD
    ProductID,
    ProductName,
    Category,
    AveragePrice,         // ← FALSCH! Das ist ein Measure
    TotalSold             // ← FALSCH! Das ist ein Measure
FROM Products;

Richtig:

Dim_Product:
LOAD
    ProductID,
    ProductName,
    Category,
    StandardPrice         // ← OK: Ein fester Attributwert, kein Aggregat
FROM Products;

// Im Frontend berechnest Du dann:
// Durchschnittspreis: Avg(Price)
// Gesamtverkauf: Sum(Quantity)

Warum ist das wichtig? Wenn Du Measures in Dimensionen packst, werden sie bei Joins vervielfacht und Deine Summen sind falsch.

⚠️ Fehler 2: Zu viele Felder in Facts

Symptom: Synthetic Keys ($Syn-Tabellen) im Datenmodell, Performance-Probleme.

Falsch:

Facts_Sales:
LOAD
    OrderID,
    CustomerID,
    CustomerName,         // ← Redundant! Gehört in Dimension
    Region,               // ← Redundant! Gehört in Dimension
    ProductID,
    ProductName,          // ← Redundant! Gehört in Dimension
    Amount
FROM Sales;

Richtig:

Facts_Sales:
LOAD
    OrderID,
    CustomerID,           // Nur die ID
    ProductID,            // Nur die ID
    Amount
FROM Sales;

// Namen und Attribute kommen aus den Dimensionen

Warum ist das wichtig? Wenn CustomerName sowohl in Facts als auch in der Customer-Dimension vorkommt, erstellt Qlik einen Synthetic Key. Das ist ineffizient und kann zu Problemen führen.

⚠️ Fehler 3: Falsche Granularität

Symptom: Du kannst nicht alle Business-Fragen beantworten oder hast explodierende Datenmengen.

Problem: Du lädst Daten auf Order-Ebene, brauchst aber Produkt-Details:

// Zu grob!
Facts_Orders:
LOAD
    OrderID,
    OrderTotalAmount      // Nur Gesamtsumme, keine Produkt-Info
FROM Orders;

// Frage: "Welche Produkte wurden am meisten verkauft?"
// Antwort: Unmöglich zu beantworten!

Lösung: Lade auf der detailliertesten benötigten Ebene:

// Richtig detailliert
Facts_OrderLines:
LOAD
    OrderLineID,
    OrderID,
    ProductID,            // Jetzt kannst Du nach Produkt analysieren
    LineAmount,
    LineQuantity
FROM OrderLines;

Was sind die Unterschiede bei der Kombination von Granularitäten in Advanced Patterns?

Manchmal hast Du Daten mit verschiedenen Detail-Levels. Beispiel: Budget ist auf Regions-Ebene, Sales auf Kunden-Ebene.

Die Herausforderung: Wie vergleichst Du Budget (pro Region) mit Sales (pro Kunde)?

Wie verwendet man Generic Keys in der Lösung?

// Sales auf Kunden-Ebene
Facts_Sales:
LOAD
    OrderID,
    CustomerID & '|Customer' as SalesKey,  // Generic Key mit Typ-Kennzeichen
    ProductID,
    Date(OrderDate) as OrderDate,
    Amount,
    Quantity
FROM Sales;

// Budget auf Regions-Ebene
CONCATENATE(Facts_Sales)
LOAD
    BudgetID,
    Region & '|Region' as SalesKey,        // Generic Key mit Typ-Kennzeichen
    ProductID,
    Date(BudgetMonth) as OrderDate,
    BudgetAmount as Amount,
    Null() as Quantity,                    // Kein Quantity bei Budget
    1 as IsBudget                          // Flag zur Unterscheidung
FROM Budget;

Erklärung: Durch das Anhängen von ‚|Customer‘ bzw. ‚|Region‘ machst Du die Keys eindeutig. So können beide Granularitäten koexistieren.

// Erweiterte Customer-Dimension
Dim_Customer:
LOAD
    CustomerID & '|Customer' as SalesKey,  // Passend zum Fact
    CustomerID,
    CustomerName,
    Region,
    Country
FROM Customers;

// Regions-Level hinzufügen
CONCATENATE(Dim_Customer)
LOAD DISTINCT
    Region & '|Region' as SalesKey,        // Passend zum Budget-Fact
    Region,
    Country
RESIDENT Dim_Customer;

Erklärung: Die Dimension enthält jetzt sowohl Kunden-Einträge (detailliert) als auch Regions-Einträge (aggregiert). So können beide Fact-Granularitäten damit arbeiten.

Ergebnis: Du kannst jetzt Sales und Budget vergleichen, obwohl sie unterschiedliche Granularität haben. Qlik aggregiert automatisch richtig!

Wie beeinflussen Deine Entscheidungen die Performance?

Deine Design-Entscheidungen haben massiven Einfluss auf Performance:

Design Ladezeit (1M Zeilen) Speicher Expression-Speed
Star Schema (Facts + Dims) 15-25 Sek ~150-200 MB 0.5-2 Sek
Denormalized (eine Tabelle) 8-12 Sek ~400-600 MB 0.3-1 Sek
Snowflake (über-normalisiert) 25-40 Sek ~180-250 MB 1-4 Sek

Empfehlung: Star Schema ist der beste Kompromiss – akzeptable Ladezeit, optimaler Speicher, gute Performance. Für weitere Details siehe Star Schema in Qlik.

Welche Naming Conventions verbessern die Übersicht in Fact vs Dimension?

Klare Namen helfen Dir und Deinem Team sofort zu erkennen was was ist:

// Facts immer mit "Facts_" prefixen
Facts_Sales:
Facts_Inventory:
Facts_Budget:

// Dimensionen immer mit "Dim_" prefixen
Dim_Customer:
Dim_Product:
Dim_Calendar:

Vorteile:

  • Im Datenmodell-Viewer sofort erkennbar was Facts und was Dims sind
  • Beim Debuggen schneller navigieren
  • Neue Team-Mitglieder verstehen die Struktur sofort

Checkliste: Ist Dein Design optimal?

Prüfe Dein Datenmodell mit diesen Fragen:

✓ Facts:

  • [ ] Enthält nur Keys, Measures und Timestamps?
  • [ ] Keine redundanten Attribute (Namen, Beschreibungen)?
  • [ ] Granularität so detailliert wie für Analysen nötig?
  • [ ] Measures sind numerisch und aggregierbar?

✓ Dimensionen:

  • [ ] Enthält nur beschreibende Attribute?
  • [ ] Keine Measures (Sum, Avg, Count)?
  • [ ] Primary Key ist eindeutig (keine Duplikate)?
  • [ ] Hierarchien sind denormalisiert (Region + Country + Continent in einer Tabelle)?

✓ Assoziationen:

  • [ ] Facts und Dims verbinden sich über IDs?
  • [ ] Keine Synthetic Keys?
  • [ ] Keine Circular References?

Was sind die nächsten Schritte bei Fact vs Dimension – Design-Entscheidungen?

Du hast jetzt die Grundlagen für saubere Fact/Dimension-Designs. Als nächstes:

1. Many-to-Many Beziehungen: Wenn ein Kunde mehrere Adressen hat oder ein Produkt mehrere Kategorien – wie modellierst Du das? Link Tables für Many-to-Many zeigt Dir die Lösung.

2. Historisierung: Kunde war früher «Bronze» und ist jetzt «Gold» – wie behältst Du die Historie? Slowly Changing Dimensions erklärt wie’s geht.

3. Temporale Daten: Wie modellierst Du Gültigkeitszeiträume und Point-in-Time-Analysen? Temporale Daten & IntervalMatch ist der nächste Schritt.

Welche verwandten Themen gibt es im Kurs zu Fact vs Dimension?

Slug: qlik-fact-dimension-design
Keywords: Qlik Sense Facts, Qlik Dimensions, Datenmodellierung Qlik, Star Schema Facts, Granularität Qlik, Fact Tables Qlik, Dimension Tables Qlik, Qlik Datenmodell Design, Qlik Performance Optimization, Qlik Best Practices