15 Views

15.1 Was ist eine View?

Eine View ist eine gespeicherte Datenbankabfrage, die wie eine virtuelle Tabelle verwendet werden kann. Views bieten mehrere Vorteile:

15.1.1 Wie lege ich eine View an?

Eine View wird mit CREATE VIEW erstellt:

-- Einfache View
CREATE VIEW mitarbeiter_kontakte AS
SELECT 
    mitarbeiter_id,
    vorname,
    nachname,
    email,
    telefon
FROM mitarbeiter;

-- View mit Joins
CREATE VIEW bestelluebersicht AS
SELECT 
    b.bestellnummer,
    k.name AS kundenname,
    b.datum,
    b.status,
    SUM(bp.menge * bp.einzelpreis) AS gesamtbetrag
FROM bestellungen b
JOIN kunden k ON b.kunden_id = k.kunden_id
JOIN bestellpositionen bp ON b.bestell_id = bp.bestell_id
GROUP BY b.bestell_id, b.bestellnummer, k.name, b.datum, b.status;

-- View mit berechneten Feldern
CREATE VIEW produktstatistik AS
SELECT 
    kategorie,
    COUNT(*) AS anzahl_produkte,
    AVG(preis) AS durchschnittspreis,
    MIN(preis) AS min_preis,
    MAX(preis) AS max_preis
FROM produkte
GROUP BY kategorie;

15.1.2 Wie wird eine View verarbeitet?

Views werden normalerweise bei jeder Abfrage neu ausgewertet:

-- Abfrage einer View
SELECT * FROM mitarbeiter_kontakte
WHERE email LIKE '%@firma.de';

-- MySQL ersetzt dies intern durch:
SELECT 
    mitarbeiter_id,
    vorname,
    nachname,
    email,
    telefon
FROM mitarbeiter
WHERE email LIKE '%@firma.de';

-- Bedingungen werden kombiniert
SELECT * FROM bestelluebersicht
WHERE gesamtbetrag > 1000
  AND datum >= '2024-01-01';

15.1.3 Wie lösche ich eine View?

Views können mit DROP VIEW gelöscht werden:

-- Eine View löschen
DROP VIEW mitarbeiter_kontakte;

-- Sicherere Variante
DROP VIEW IF EXISTS mitarbeiter_kontakte;

-- Mehrere Views löschen
DROP VIEW 
    view1, 
    view2, 
    view3;

15.1.4 Wie ändere ich eine View?

Views können mit ALTER VIEW oder CREATE OR REPLACE VIEW geändert werden:

-- Mit ALTER VIEW
ALTER VIEW mitarbeiter_kontakte AS
SELECT 
    mitarbeiter_id,
    vorname,
    nachname,
    email,
    telefon,
    abteilung  -- Neue Spalte
FROM mitarbeiter;

-- Mit CREATE OR REPLACE
CREATE OR REPLACE VIEW mitarbeiter_kontakte AS
SELECT 
    mitarbeiter_id,
    vorname,
    nachname,
    email,
    telefon,
    abteilung
FROM mitarbeiter;

15.2 Anwendungsgebiet: Vereinfachung

Views können komplexe Abfragen vereinfachen:

-- Komplexe View definieren
CREATE VIEW produktanalyse AS
SELECT 
    p.produkt_id,
    p.bezeichnung,
    k.kategorie_name,
    p.preis,
    l.lagerbestand,
    COALESCE(b.anzahl_bestellungen, 0) AS anzahl_bestellungen,
    COALESCE(b.gesamtumsatz, 0) AS gesamtumsatz
FROM produkte p
LEFT JOIN kategorien k ON p.kategorie_id = k.kategorie_id
LEFT JOIN lagerbestand l ON p.produkt_id = l.produkt_id
LEFT JOIN (
    SELECT 
        produkt_id,
        COUNT(*) AS anzahl_bestellungen,
        SUM(menge * einzelpreis) AS gesamtumsatz
    FROM bestellpositionen
    GROUP BY produkt_id
) b ON p.produkt_id = b.produkt_id;

-- Einfache Nutzung der View
SELECT * FROM produktanalyse
WHERE lagerbestand < 10;

SELECT 
    kategorie_name,
    COUNT(*) AS anzahl_produkte,
    AVG(gesamtumsatz) AS durchschnittsumsatz
FROM produktanalyse
GROUP BY kategorie_name;

15.3 Anwendungsgebiet: Datenschutz

Views können den Zugriff auf Daten einschränken:

-- View für eingeschränkte Sicht
CREATE VIEW kunden_basis AS
SELECT 
    kunden_id,
    firma,
    ansprechpartner,
    email,
    telefon
FROM kunden;  -- versteckt sensible Daten wie Bankverbindung

-- Rechte für die View vergeben
GRANT SELECT ON kunden_basis TO 'mitarbeiter'@'localhost';

-- View mit Datenschutz für Personaldaten
CREATE VIEW mitarbeiter_oeffentlich AS
SELECT 
    mitarbeiter_id,
    CONCAT(vorname, ' ', LEFT(nachname, 1), '.') AS name,
    abteilung,
    email
FROM mitarbeiter;

15.4 Grenzen einer View

Views haben einige Einschränkungen:

  1. Performance:
-- Komplexe Views können langsam sein
CREATE VIEW umsatzanalyse AS
SELECT 
    k.land,
    k.region,
    DATE_FORMAT(b.datum, '%Y-%m') AS monat,
    COUNT(DISTINCT b.bestell_id) AS anzahl_bestellungen,
    SUM(bp.menge * bp.einzelpreis) AS umsatz
FROM bestellungen b
JOIN kunden k ON b.kunden_id = k.kunden_id
JOIN bestellpositionen bp ON b.bestell_id = bp.bestell_id
GROUP BY k.land, k.region, DATE_FORMAT(b.datum, '%Y-%m');
  1. Updatefähigkeit:
-- Diese View ist nicht updatefähig (wegen Aggregation)
CREATE VIEW kategorie_statistik AS
SELECT 
    kategorie,
    COUNT(*) AS anzahl,
    AVG(preis) AS durchschnitt
FROM produkte
GROUP BY kategorie;

-- Diese View ist updatefähig
CREATE VIEW aktive_produkte AS
SELECT *
FROM produkte
WHERE status = 'aktiv';

Praktische Tipps für Views:

  1. Dokumentation in der View-Definition:
CREATE VIEW bestellstatistik AS
    /* Diese View zeigt Bestellstatistiken pro Kunde und Monat.
       Erstellt von: Max Mustermann
       Erstellt am: 2024-01-15
       Verwendung: Monatliche Umsatzberichte */
SELECT 
    kunde_id,
    DATE_FORMAT(datum, '%Y-%m') AS monat,
    COUNT(*) AS anzahl_bestellungen,
    SUM(betrag) AS gesamtumsatz
FROM bestellungen
GROUP BY kunde_id, DATE_FORMAT(datum, '%Y-%m');
  1. Performance-Optimierung:
-- Index für häufig verwendete Bedingungen
CREATE INDEX idx_status_datum 
ON bestellungen(status, datum);

-- Materialisierte View (in MySQL durch Tabelle simuliert)
CREATE TABLE mat_bestellstatistik AS
SELECT /* View-Definition */;
  1. Wartbarkeit:
-- View in kleinere Views aufteilen
CREATE VIEW basis_kundendaten AS
SELECT /* Basisdaten */;

CREATE VIEW erweiterte_kundendaten AS
SELECT 
    k.*,
    b.anzahl_bestellungen,
    b.gesamtumsatz
FROM basis_kundendaten k
LEFT JOIN bestellstatistik b ON k.kunde_id = b.kunde_id;