init at work
This commit is contained in:
Executable
+360
@@ -0,0 +1,360 @@
|
||||
#datenbank
|
||||
|
||||
➡️ [[#Zusammenfassung]]
|
||||
|
||||
---
|
||||
### 1. Grundidee: Was ist eine Materialized View?
|
||||
|
||||
Eine **Materialized View** (materialisierte Sicht) ist vereinfacht gesagt:
|
||||
|
||||
> **Eine gespeicherte Ergebnistabelle einer Abfrage**, die regelmäßig aktualisiert wird.
|
||||
|
||||
Im Unterschied zu einer „normalen“ View, die bei jedem Zugriff die zugrunde liegende Abfrage neu ausführt, werden bei einer Materialized View:
|
||||
|
||||
- die Daten der Abfrage **physisch gespeichert** (wie in einer Tabelle),
|
||||
- und später **wiederverwendet**, ohne jedes Mal die komplette Abfrage neu berechnen zu müssen.
|
||||
|
||||
Du kannst dir das vorstellen wie einen **vorgeberechneten Bericht**, der als echte Tabelle im System liegt, aber technisch aus einer oder mehreren anderen Tabellen abgeleitet ist.
|
||||
|
||||
Typische Verwendung:
|
||||
- Große Tabellen
|
||||
- Aufwendige Joins
|
||||
- Aggregationen (SUM, COUNT, AVG, …)
|
||||
- Reporting & Analytics
|
||||
|
||||
---
|
||||
|
||||
### 2. Abgrenzung zu verwandten Begriffen
|
||||
|
||||
#### 2.1 Normale View vs. Materialized View
|
||||
|
||||
**View (logische Sicht)**:
|
||||
- Ist nur eine **gespeicherte Abfrage**.
|
||||
- Speichert selbst **keine Daten**.
|
||||
- Beim SELECT auf die View wird die zugrunde liegende Abfrage jedes Mal **neu ausgeführt**.
|
||||
- Vorteil: Immer **aktuell**, kein Speicheraufwand.
|
||||
- Nachteil: Kann bei komplexen Abfragen **langsam** sein.
|
||||
|
||||
**Materialized View**:
|
||||
- Ist eine **physisch gespeicherte Tabelle**, die aus einer Abfrage berechnet wurde.
|
||||
- Beim SELECT werden die **vorgehaltenen Daten** gelesen (schnell).
|
||||
- Muss **explizit aktualisiert** („refreshed“) werden.
|
||||
- Vorteil: Schnelle Abfragen, vor allem bei komplexen Berechnungen.
|
||||
- Nachteil: Daten können **veraltet** sein, zusätzlicher Speicher & Wartung.
|
||||
|
||||
#### 2.2 Materialized View vs. Tabelle
|
||||
|
||||
**Normale Tabelle**:
|
||||
- Daten werden direkt in diese Tabelle geschrieben (INSERT, UPDATE, DELETE).
|
||||
- Struktur (Schema) ist unabhängig; die Tabelle „gehört sich selbst“.
|
||||
|
||||
**Materialized View**:
|
||||
- Wird **aus anderen Tabellen abgeleitet** (Definition durch SELECT).
|
||||
- Man schreibt normalerweise **nicht direkt** hinein, sondern nur in die Basistabellen.
|
||||
- Die Materialized View wird über einen **Refresh-Mechanismus** aktualisiert.
|
||||
|
||||
#### 2.3 Materialized View vs. Cache
|
||||
|
||||
Ein **Cache** (z. B. im Application Server):
|
||||
- Hält Daten im Speicher, typischerweise kurzfristig.
|
||||
- Wird meist von der Anwendung gesteuert.
|
||||
- Ist oft flüchtig (z. B. bei Neustart weg).
|
||||
|
||||
**Materialized View**:
|
||||
- Ist Teil der Datenbank, persistent auf Disk.
|
||||
- Wird durch die Datenbank verwaltet.
|
||||
- Kann komplexere Konsistenz- und Refresh-Strategien nutzen.
|
||||
|
||||
#### 2.4 Materialized View vs. Index
|
||||
|
||||
**Index**:
|
||||
- Beschleunigt den Zugriff auf bestehende Daten einer Tabelle.
|
||||
- Speichert typischerweise Schlüsselwerte und Zeiger auf die Tabelle.
|
||||
- Berechnet **keine neuen Inhalte**, sondern hilft, vorhandene schneller zu finden.
|
||||
|
||||
**Materialized View**:
|
||||
- Enthält **eigene Daten**, die Ergebnis einer Abfrage sind (z. B. Summen, Gruppierungen).
|
||||
- Kann zusätzlich selbst Indexe haben.
|
||||
|
||||
#### 2.5 Datenbanken und Begriffe
|
||||
|
||||
Verschiedene Systeme nutzen leicht unterschiedliche Begriffe:
|
||||
|
||||
- **PostgreSQL**: `MATERIALIZED VIEW`
|
||||
- **Oracle**: `MATERIALIZED VIEW` (sehr ausgereifte Funktionen)
|
||||
- **SQL Server**: Kein direkter Begriff, aber **Indexed Views** sind sehr ähnlich
|
||||
- **MySQL**: Keine echte Materialized View, aber man kann das Verhalten nachbauen (z. B. mit Triggern, geplanten Jobs, Tabellen)
|
||||
|
||||
---
|
||||
|
||||
### 3. Welche Probleme werden durch Materialized Views gelöst?
|
||||
|
||||
#### 3.1 Performance bei komplexen Abfragen
|
||||
|
||||
Wenn du häufig dieselbe **komplexe Abfrage** ausführst, kostet das jedes Mal viel Rechenzeit:
|
||||
|
||||
- Viele Joins über große Tabellen
|
||||
- Aggregationen (SUM, COUNT, MAX, …)
|
||||
- Filter auf komplizierten Kombinationen
|
||||
|
||||
Eine Materialized View **berechnet diese Abfrage einmal** (oder in festen Intervallen) und speichert das Ergebnis. Spätere Abfragen greifen nur noch auf die **fertige Ergebnismenge** zu.
|
||||
|
||||
**Beispiel:**
|
||||
|
||||
Du hast einen Online-Shop mit Tabellen:
|
||||
|
||||
- `orders` (Bestellungen)
|
||||
- `order_items` (Bestellpositionen)
|
||||
- `products` (Produkte)
|
||||
- `customers` (Kunden)
|
||||
|
||||
Du willst regelmäßig wissen: **Wie viel Umsatz pro Kunde pro Monat?**
|
||||
|
||||
Ohne Materialized View:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
c.customer_id,
|
||||
date_trunc('month', o.order_date) AS month,
|
||||
SUM(oi.quantity * oi.unit_price) AS revenue
|
||||
FROM customers c
|
||||
JOIN orders o ON o.customer_id = c.customer_id
|
||||
JOIN order_items oi ON oi.order_id = o.order_id
|
||||
GROUP BY c.customer_id, date_trunc('month', o.order_date);
|
||||
```
|
||||
|
||||
Diese Abfrage kann bei Millionen Zeilen **sehr langsam** sein, besonders wenn sie viele Nutzer gleichzeitig ausführen.
|
||||
|
||||
Mit Materialized View:
|
||||
|
||||
```sql
|
||||
CREATE MATERIALIZED VIEW mv_customer_monthly_revenue AS
|
||||
SELECT
|
||||
c.customer_id,
|
||||
date_trunc('month', o.order_date) AS month,
|
||||
SUM(oi.quantity * oi.unit_price) AS revenue
|
||||
FROM customers c
|
||||
JOIN orders o ON o.customer_id = c.customer_id
|
||||
JOIN order_items oi ON oi.order_id = o.order_id
|
||||
GROUP BY c.customer_id, date_trunc('month', o.order_date);
|
||||
```
|
||||
|
||||
Einfache Abfrage darauf:
|
||||
|
||||
```sql
|
||||
SELECT * FROM mv_customer_monthly_revenue
|
||||
WHERE month = '2025-01-01';
|
||||
```
|
||||
|
||||
Das ist meist **sehr schnell**, da nur noch fertige Zeilen gelesen werden.
|
||||
|
||||
#### 3.2 Entlastung der Primärtables
|
||||
|
||||
Wenn viele Nutzer komplexe Analysen auf den operativen Tabellen ausführen, kann das:
|
||||
|
||||
- den Datenbankserver stark belasten,
|
||||
- Transaktionen verlangsamen,
|
||||
- das Online-System (z. B. Shop) spürbar ausbremsen.
|
||||
|
||||
Materialized Views dienen hier als eine Art **vorgefertigtes Reporting-Layer**, das:
|
||||
|
||||
- weniger Schreiboperationen hat,
|
||||
- stark komprimiert / aggregiert sein kann,
|
||||
- unabhängig indexiert werden kann.
|
||||
|
||||
#### 3.3 Zugriff auf entfernte Daten (z. B. Data Warehouse)
|
||||
|
||||
In manchen Systemen kann eine Materialized View Daten aus **anderen Datenbanken** oder **externen Quellen** einbinden. Damit können z. B.:
|
||||
|
||||
- Daten aus mehreren Systemen
|
||||
- in einer lokal gespeicherten, performanten Sicht
|
||||
zusammengefasst werden.
|
||||
|
||||
---
|
||||
|
||||
### 4. Welche Herausforderungen und Nachteile gibt es?
|
||||
|
||||
#### 4.1 Datenaktualität (Freshness)
|
||||
|
||||
Materialized Views sind **nicht automatisch immer aktuell**.
|
||||
|
||||
Typische Arten des Refresh:
|
||||
|
||||
1. **Maneller Refresh**
|
||||
Du rufst selbst etwas auf wie:
|
||||
|
||||
```sql
|
||||
REFRESH MATERIALIZED VIEW mv_customer_monthly_revenue;
|
||||
```
|
||||
|
||||
2. **Geplanter Refresh (z. B. jede Stunde/Tageswechsel)**
|
||||
Über Scheduler/Jobs: „Führe jede Nacht um 3 Uhr einen Refresh aus“.
|
||||
|
||||
3. **On Commit / nahezu in Echtzeit** (je nach DB)
|
||||
Bei bestimmten Systemen können Materialized Views nach Änderungen an den Basistabellen automatisch aktualisiert werden.
|
||||
|
||||
**Konsequenz:**
|
||||
Es gibt immer einen Trade-off zwischen:
|
||||
|
||||
- **Aktualität** (häufig refresht → näher an „Echtzeit“)
|
||||
- **Performance/Belastung** (jeder Refresh ist teils teuer)
|
||||
|
||||
#### 4.2 Konsistenz und Komplexität
|
||||
|
||||
Bei vielen Materialized Views, die sich überlappen oder von anderen Views abhängen, kann es kompliziert werden:
|
||||
|
||||
- In welcher Reihenfolge refresht man?
|
||||
- Was passiert, wenn eine Quelle fehlerhaft ist?
|
||||
- Wie geht man mit teilweisen Refreshes um?
|
||||
|
||||
#### 4.3 Speicherbedarf
|
||||
|
||||
Materialized Views brauchen **zusätzlichen Speicher**, da sie Daten duplizieren:
|
||||
|
||||
- Daten sind in den Basistabellen vorhanden
|
||||
- plus noch einmal in den Materialized Views
|
||||
|
||||
Je nach Anzahl und Detailgrad kann das signifikant sein.
|
||||
|
||||
#### 4.4 Schreibaufwand auf Basistabellen (indirekt)
|
||||
|
||||
Wenn Materialized Views sehr häufig aktualisiert werden:
|
||||
|
||||
- können Inserts/Updates auf Basistabellen indirekt langsamer werden,
|
||||
- weil der Refresh-Prozess Ressourcen frisst (z. B. CPU, I/O, Locks).
|
||||
|
||||
Bei Systemen mit „Refresh on Commit“ müssen evtl. zusätzliche Metadaten gepflegt werden, um Änderungen nachvollziehbar zu machen.
|
||||
|
||||
#### 4.5 Komplexität im Design und Betrieb
|
||||
|
||||
- Man muss Entscheidungen treffen:
|
||||
- Welche Abfragen lohnen sich als Materialized View?
|
||||
- Wie oft sollten sie aktualisiert werden?
|
||||
- Wer ist verantwortlich für Monitoring und Fehlerbehandlung?
|
||||
|
||||
- Bei Änderungen am Schema (z. B. Spalten hinzufügen) muss oft:
|
||||
- die Materialized View angepasst
|
||||
- oder neu aufgebaut werden.
|
||||
|
||||
---
|
||||
|
||||
### 5. Praxisnahe Beispiele
|
||||
|
||||
#### 5.1 Reporting im E-Commerce
|
||||
|
||||
Stell dir einen Online-Shop vor, der täglich Tausende Bestellungen hat. Das Management möchte im Dashboard sehen:
|
||||
|
||||
- Umsatz pro Tag
|
||||
- Top-10-Produkte pro Woche
|
||||
- Anzahl neuer Kunden pro Monat
|
||||
|
||||
Ohne Materialized Views würden diese Reports bei jedem Aufruf heavy Queries auf großen Tabellen ausführen.
|
||||
|
||||
Mit Materialized Views:
|
||||
|
||||
1. `mv_daily_revenue`
|
||||
Umsätze pro Tag
|
||||
|
||||
```sql
|
||||
CREATE MATERIALIZED VIEW mv_daily_revenue AS
|
||||
SELECT
|
||||
date_trunc('day', o.order_date) AS day,
|
||||
SUM(oi.quantity * oi.unit_price) AS revenue
|
||||
FROM orders o
|
||||
JOIN order_items oi ON oi.order_id = o.order_id
|
||||
GROUP BY date_trunc('day', o.order_date);
|
||||
```
|
||||
|
||||
2. `mv_weekly_top_products`
|
||||
Top-Produkte je Woche
|
||||
|
||||
```sql
|
||||
CREATE MATERIALIZED VIEW mv_weekly_top_products AS
|
||||
SELECT
|
||||
date_trunc('week', o.order_date) AS week,
|
||||
oi.product_id,
|
||||
SUM(oi.quantity) AS total_quantity
|
||||
FROM orders o
|
||||
JOIN order_items oi ON oi.order_id = o.order_id
|
||||
GROUP BY date_trunc('week', o.order_date), oi.product_id;
|
||||
```
|
||||
|
||||
3. `mv_monthly_new_customers`
|
||||
Neue Kunden pro Monat
|
||||
|
||||
```sql
|
||||
CREATE MATERIALIZED VIEW mv_monthly_new_customers AS
|
||||
SELECT
|
||||
date_trunc('month', c.created_at) AS month,
|
||||
COUNT(*) AS new_customers
|
||||
FROM customers c
|
||||
GROUP BY date_trunc('month', c.created_at);
|
||||
```
|
||||
|
||||
Diese Views kannst du z. B. **jede Nacht** aktualisieren, da sich historische Daten nicht mehr ändern.
|
||||
|
||||
#### 5.2 Data Warehouse / BI
|
||||
|
||||
In einem Data Warehouse gibt es oft:
|
||||
|
||||
- große „Faktentabellen“ (z. B. `fact_sales` mit hunderten Millionen Zeilen),
|
||||
- Dimensionstabellen (Kunde, Produkt, Region).
|
||||
|
||||
Materialized Views können hier als **„Summary Tables“** dienen, z. B.:
|
||||
|
||||
- Verkäufe pro Region und Monat
|
||||
- Verkäufe pro Produktkategorie und Quartal
|
||||
|
||||
Analysten müssen dann nicht mehr auf die komplette Faktentabelle zugreifen, sondern nur noch auf relativ kleine, aggregierte Materialized Views.
|
||||
|
||||
#### 5.3 Teilweise Aktualisierung (Incremental Refresh)
|
||||
|
||||
Fortgeschrittene Systeme (z. B. Oracle) können Materialized Views **inkrementell** aktualisieren: Es werden nur die Änderungen seit dem letzten Stand eingerechnet, statt alles komplett neu zu berechnen. Das spart enorm Zeit und Ressourcen, ist aber vom Setup her komplexer.
|
||||
|
||||
---
|
||||
|
||||
### 6. Typische Strategien und Best Practices
|
||||
|
||||
1. **Nur für „schwere“ Abfragen nutzen**
|
||||
Materialized Views lohnen sich insbesondere, wenn:
|
||||
- die Abfrage sehr teuer ist,
|
||||
- die Daten sich nicht „jede Sekunde“ ändern,
|
||||
- die Ergebnisse häufig angefragt werden.
|
||||
|
||||
2. **Refresh-Frequenz bewusst wählen**
|
||||
- Nahe Echtzeit notwendig? → Häufigerer Refresh, mehr Last
|
||||
- Reine Reports (z. B. täglich) → nächtlicher Refresh reicht oft
|
||||
|
||||
3. **Materialized Views benennen und dokumentieren**
|
||||
- Sinnvolle Namen (`mv_...`)
|
||||
- Dokumentation: Welche Abfrage? Wie wird refresht? Wer nutzt sie?
|
||||
|
||||
4. **Indexe auf Materialized Views setzen**
|
||||
- Genau wie bei normalen Tabellen können Indexe Abfragen weiter beschleunigen:
|
||||
```sql
|
||||
CREATE INDEX idx_mv_daily_revenue_day
|
||||
ON mv_daily_revenue (day);
|
||||
```
|
||||
|
||||
5. **Monitoring**
|
||||
- Refresh-Zeiten messen
|
||||
- Fehler beim Refresh protokollieren
|
||||
- Speicherverbrauch im Blick behalten
|
||||
|
||||
---
|
||||
|
||||
### Zusammenfassung
|
||||
|
||||
- **Materialized Views** sind gespeicherte (materialisierte) Ergebnisse von Abfragen, die wie Tabellen genutzt werden können.
|
||||
- Sie dienen vor allem zur **Performance-Steigerung** bei komplexen oder häufig ausgeführten Abfragen und zur **Entlastung** der operativen Tabellen.
|
||||
- Gegenüber normalen Views:
|
||||
- **schneller** beim Lesen,
|
||||
- aber **nicht automatisch aktuell** – sie müssen refresht werden.
|
||||
- Herausforderungen:
|
||||
- Datenaktualität (wie oft refresht man?),
|
||||
- zusätzlicher Speicherverbrauch,
|
||||
- Komplexität in Design und Wartung.
|
||||
- Typische Einsatzgebiete:
|
||||
- Reporting, Analytics, Dashboards,
|
||||
- Data Warehousing,
|
||||
- Aggregationen über große Datenmengen.
|
||||
Reference in New Issue
Block a user