Ausblick & Weiterführende Themen
Fast geschafft...
In den vorherigen Kapiteln hast du die Grundlagen relationaler Datenbanken mit PostgreSQL kennengelernt. Du kannst jetzt:
- ✅ Datenbanken modellieren und entwerfen
- ✅ Tabellen erstellen und Beziehungen definieren
- ✅ Daten einfügen, ändern und löschen
- ✅ Komplexe Abfragen mit Joins und Aggregationen schreiben
- ✅ Datenintegrität mit Constraints sicherstellen
- ✅ Transaktionen für sichere Datenoperationen nutzen
Doch die Welt der Datenbanken ist viel größer als das, was wir bisher gesehen haben. In diesem abschließenden Kapitel werfen wir einen Blick über den Tellerrand und schauen uns weiterführende Themen an, die in professionellen Umgebungen wichtig sind.
Wichtiger Hinweis
In diesem Kapitel wird ein Ausblick auf weiterführende Themen gegeben. Alle Code Snippets können wie bisher ausgeführt und getestet werden. Eine detailierte Beschreibung und Erklärung der einzelnen Themen gibt es in diesem Kapitel nicht. Trotzdem kann jeder versuchen den Code nachzuvollziehen und gegebenenfalls mittels Recherche eine Erklärung zu finden.
Datenbank-Setup
Für die folgenden Beispiele erstellen wir eine E-Commerce/Online-Shop-Datenbank. In dieser Datenbank werden Produkte, Bestellungen und Lagerbestände verwaltet.
-- Datenbank erstellen
CREATE DATABASE shop_db;
-- Zur Datenbank wechseln
\c shop_db
-- Tabelle: Produkte
CREATE TABLE produkte (
produkt_id SERIAL PRIMARY KEY,
produktname VARCHAR(200) NOT NULL,
kategorie VARCHAR(100),
preis NUMERIC(10, 2) NOT NULL CHECK (preis >= 0),
lagerbestand INTEGER NOT NULL DEFAULT 0 CHECK (lagerbestand >= 0),
aktiv BOOLEAN DEFAULT TRUE,
erstellt_am TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
letzte_aenderung TIMESTAMP
);
-- Tabelle: Bestellungen
CREATE TABLE bestellungen (
bestell_id SERIAL PRIMARY KEY,
kunde VARCHAR(200) NOT NULL,
bestelldatum TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
status VARCHAR(50) DEFAULT 'offen',
gesamtbetrag NUMERIC(12, 2)
);
-- Tabelle: Bestellpositionen
CREATE TABLE bestellpositionen (
position_id SERIAL PRIMARY KEY,
bestell_id INTEGER REFERENCES bestellungen(bestell_id) ON DELETE CASCADE,
produkt_id INTEGER REFERENCES produkte(produkt_id),
menge INTEGER NOT NULL CHECK (menge > 0),
einzelpreis NUMERIC(10, 2) NOT NULL
);
-- Testdaten: Produkte
INSERT INTO produkte (produktname, kategorie, preis, lagerbestand) VALUES
('Laptop ThinkPad X1', 'Elektronik', 1299.99, 15),
('Wireless Mouse MX3', 'Zubehör', 79.99, 50),
('USB-C Hub 7-Port', 'Zubehör', 49.99, 30),
('Monitor 27" 4K', 'Elektronik', 449.99, 8),
('Mechanische Tastatur', 'Zubehör', 129.99, 20),
('Webcam HD Pro', 'Elektronik', 89.99, 0),
('Laptop-Tasche Premium', 'Zubehör', 59.99, 25);
-- Testdaten: Bestellungen
INSERT INTO bestellungen (kunde, status, gesamtbetrag) VALUES
('Anna Schmidt', 'abgeschlossen', 1429.98),
('Thomas Weber', 'in_bearbeitung', 179.98),
('Lisa Miller', 'offen', 449.99);
-- Testdaten: Bestellpositionen
INSERT INTO bestellpositionen (bestell_id, produkt_id, menge, einzelpreis) VALUES
(1, 1, 1, 1299.99), -- Anna: Laptop
(1, 2, 1, 79.99), -- Anna: Mouse
(1, 3, 1, 49.99), -- Anna: Hub
(2, 2, 1, 79.99), -- Thomas: Mouse
(2, 5, 1, 129.99), -- Thomas: Tastatur
(3, 4, 1, 449.99); -- Lisa: Monitor
Views (Sichten)
Eine View ist eine virtuelle Tabelle, die auf einer oder mehreren echten Tabellen basiert. Views speichern keine eigenen Daten, sondern definieren eine gespeicherte Abfrage, die bei jedem Aufruf ausgeführt wird. Allgemein lautet der Syntax
CREATE VIEW view_name AS
SELECT spalte1, spalte2, ...
FROM tabelle
WHERE bedingung;
Betrachten wir das ganze anhand eines Beispiels.
View für verfügbare Produkte
Wir erstellen eine View, die nur verfügbare Produkte zeigt (auf Lager und aktiv):
CREATE VIEW verfuegbare_produkte AS
SELECT
produkt_id,
produktname,
kategorie,
preis,
lagerbestand
FROM produkte
WHERE aktiv = TRUE
AND lagerbestand > 0
ORDER BY produktname;
Anschließend können wir die View verwenden:
-- View verwenden wie eine normale Tabelle
SELECT * FROM verfuegbare_produkte;
produkt_id | produktname | kategorie | preis | lagerbestand
------------+-----------------------+------------+---------+--------------
7 | Laptop-Tasche Premium | Zubehör | 59.99 | 25
1 | Laptop ThinkPad X1 | Elektronik | 1299.99 | 15
5 | Mechanische Tastatur | Zubehör | 129.99 | 20
4 | Monitor 27" 4K | Elektronik | 449.99 | 8
3 | USB-C Hub 7-Port | Zubehör | 49.99 | 30
2 | Wireless Mouse MX3 | Zubehör | 79.99 | 50
(6 rows)
weitere Beispiele
Eine komplexere View kann mehrere Tabellen kombinieren:
CREATE VIEW bestelluebersicht AS
SELECT
b.bestell_id,
b.kunde,
b.bestelldatum,
b.status,
COUNT(bp.position_id) AS anzahl_artikel,
SUM(bp.menge * bp.einzelpreis) AS gesamtbetrag
FROM bestellungen b
LEFT JOIN bestellpositionen bp ON b.bestell_id = bp.bestell_id
GROUP BY b.bestell_id, b.kunde, b.bestelldatum, b.status
ORDER BY b.bestelldatum DESC;
SELECT * FROM bestelluebersicht;
bestell_id | kunde | bestelldatum | status | anzahl_artikel | gesamtbetrag
------------+--------------+----------------------------+----------------+----------------+--------------
3 | Lisa Miller | 2025-11-26 09:45:08.313595 | offen | 1 | 449.99
2 | Thomas Weber | 2025-11-26 09:45:08.313595 | in_bearbeitung | 2 | 209.98
1 | Anna Schmidt | 2025-11-26 09:45:08.313595 | abgeschlossen | 3 | 1429.97
(3 rows)
Views haben wir nahezu alles im Leben Vor- und Nachteile. Diese wind nachfolgend aufgelistet.
View löschen
Views können natürlich auch wieder gelöscht werden mit folgendem Syntax:
DROP VIEW IF EXISTS verfuegbare_produkte;
DROP VIEW IF EXISTS bestelluebersicht;
DROP VIEW
DROP VIEW
Stored Procedures & Functions
Stored Procedures (gespeicherte Prozeduren) und Functions sind vordefinierte SQL-Programme, die in der Datenbank gespeichert werden.
Die Unterschiede zwischen Prozeduren und Funktionen sind:
Funktion für Produktverfügbarkeit
CREATE OR REPLACE FUNCTION ist_verfuegbar(p_produkt_id INTEGER, p_menge INTEGER)
RETURNS BOOLEAN AS $$
BEGIN
RETURN EXISTS (
SELECT 1
FROM produkte
WHERE produkt_id = p_produkt_id
AND aktiv = TRUE
AND lagerbestand >= p_menge
);
END;
$$ LANGUAGE plpgsql;
Verwendung:
-- Prüfen, ob 10 Stück Laptop verfügbar sind
SELECT produktname, ist_verfuegbar(produkt_id, 10) AS verfuegbar
FROM produkte;
produktname | verfuegbar
-----------------------+------------
Laptop ThinkPad X1 | t
Wireless Mouse MX3 | t
USB-C Hub 7-Port | t
Monitor 27" 4K | f
Mechanische Tastatur | t
Webcam HD Pro | f
Laptop-Tasche Premium | t
(7 rows)
Procedure für Bestellung erstellen
CREATE OR REPLACE PROCEDURE erstelle_bestellung(
p_kunde VARCHAR,
p_produkt_id INTEGER,
p_menge INTEGER
)
LANGUAGE plpgsql AS $$
DECLARE
v_bestell_id INTEGER;
v_preis NUMERIC;
BEGIN
-- Preis holen
SELECT preis INTO v_preis FROM produkte WHERE produkt_id = p_produkt_id;
-- Bestellung erstellen
INSERT INTO bestellungen (kunde, status, gesamtbetrag)
VALUES (p_kunde, 'offen', v_preis * p_menge)
RETURNING bestell_id INTO v_bestell_id;
-- Bestellposition erstellen
INSERT INTO bestellpositionen (bestell_id, produkt_id, menge, einzelpreis)
VALUES (v_bestell_id, p_produkt_id, p_menge, v_preis);
-- Lagerbestand reduzieren
UPDATE produkte
SET lagerbestand = lagerbestand - p_menge
WHERE produkt_id = p_produkt_id;
RAISE NOTICE 'Bestellung % fuer Kunde % erstellt', v_bestell_id, p_kunde;
END;
$$;
Verwendung:
CALL erstelle_bestellung('Max Mustermann', 1, 2);
HINWEIS: Bestellung 4 fuer Kunde Max Mustermann erstellt
Trigger
Ein Trigger ist ein automatisch ausgeführtes SQL-Programm, das bei bestimmten Ereignissen (INSERT, UPDATE, DELETE) aktiviert wird.
Typische Anwendungsfälle sind:
- Automatische Protokollierung von Änderungen
- Datenkonsistenz durch automatische Updates
- Durchsetzung von Geschäftsregeln
- Audit-Trails und Logging
Automatische Zeitstempel-Aktualisierung
-- Trigger-Function erstellen
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.letzte_aenderung = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Trigger erstellen
CREATE TRIGGER produkt_update_timestamp
BEFORE UPDATE ON produkte
FOR EACH ROW
EXECUTE FUNCTION update_timestamp();
Wirkung: Jedes Mal, wenn ein Produkt geändert wird, wird automatisch letzte_aenderung aktualisiert.
-- Produkt aktualisieren
UPDATE produkte SET preis = 1199.99 WHERE produkt_id = 1;
-- Zeitstempel wurde automatisch gesetzt
SELECT produktname, preis, letzte_aenderung FROM produkte WHERE produkt_id = 1;
produktname | preis | letzte_aenderung
--------------------+---------+----------------------------
Laptop ThinkPad X1 | 1199.99 | 2025-11-26 09:55:40.404667
(1 row)
weitere Beispiele
Ein praktischeres Beispiel: Lagerbestand automatisch reduzieren, wenn eine Bestellposition erstellt wird.
-- Trigger-Function erstellen
CREATE OR REPLACE FUNCTION reduziere_lagerbestand()
RETURNS TRIGGER AS $$
BEGIN
UPDATE produkte
SET lagerbestand = lagerbestand - NEW.menge
WHERE produkt_id = NEW.produkt_id;
-- Warnung, wenn Lagerbestand niedrig wird
IF (SELECT lagerbestand FROM produkte WHERE produkt_id = NEW.produkt_id) < 5 THEN
RAISE NOTICE 'Warnung: Niedriger Lagerbestand fuer Produkt %', NEW.produkt_id;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Trigger erstellen
CREATE TRIGGER nach_bestellposition_einfuegen
AFTER INSERT ON bestellpositionen
FOR EACH ROW
EXECUTE FUNCTION reduziere_lagerbestand();
Wirkung: Bei jeder neuen Bestellposition wird automatisch der Lagerbestand reduziert.
-- Vor der Bestellung
SELECT produktname, lagerbestand FROM produkte WHERE produkt_id = 4;
produktname | lagerbestand
----------------+--------------
Monitor 27" 4K | 8
(1 row)
-- Neue Bestellung erstellen
INSERT INTO bestellungen (kunde, status) VALUES ('Peter Klein', 'offen');
INSERT INTO bestellpositionen (bestell_id, produkt_id, menge, einzelpreis)
VALUES (4, 4, 4, 449.99);
-- Nach der Bestellung
SELECT produktname, lagerbestand FROM produkte WHERE produkt_id = 4;
HINWEIS: Warnung: Niedriger Lagerbestand fuer Produkt 4
produktname | lagerbestand
----------------+--------------
Monitor 27" 4K | 5
(1 row)
Typische Befehle im Zusammen hang mit Trigger sind:
JSON-Support in PostgreSQL
PostgreSQL bietet native Unterstützung für JSON-Daten, was flexible, semi-strukturierte Datenspeicherung ermöglicht.
Produkte mit flexiblen Attributen
CREATE TABLE produkte_extended (
produkt_id SERIAL PRIMARY KEY,
produktname VARCHAR(200) NOT NULL,
kategorie VARCHAR(100),
preis NUMERIC(10, 2) NOT NULL,
attribute JSONB -- Flexible zusätzliche Produkteigenschaften
);
INSERT INTO produkte_extended (produktname, kategorie, preis, attribute) VALUES
('Laptop ThinkPad X1', 'Elektronik', 1299.99,
'{"bildschirm": "14 Zoll", "prozessor": "Intel i7", "ram_gb": 16, "ssd_gb": 512, "farben": ["Schwarz", "Silber"]}'::jsonb),
('Wireless Mouse MX3', 'Zubehör', 79.99,
'{"dpi": 4000, "kabellos": true, "batterielaufzeit_tage": 70, "farben": ["Schwarz", "Weiß", "Grau"]}'::jsonb),
('Monitor 27" 4K', 'Elektronik', 449.99,
'{"aufloesung": "3840x2160", "bildwiederholrate_hz": 60, "panel_typ": "IPS", "hdr": true}'::jsonb);
JSON-Abfragen:
-- Zugriff auf JSON-Felder
SELECT produktname, attribute->>'bildschirm' AS bildschirm, attribute->>'prozessor' AS prozessor
FROM produkte_extended
WHERE attribute ? 'bildschirm'; -- Nur Produkte mit Bildschirm-Attribut
produktname | bildschirm | prozessor
--------------------+------------+-----------
Laptop ThinkPad X1 | 14 Zoll | Intel i7
(1 row)
-- Nach JSON-Werten filtern
SELECT produktname, attribute->>'ram_gb' AS ram
FROM produkte_extended
WHERE (attribute->>'ram_gb')::integer >= 16;
produktname | ram
--------------------+-----
Laptop ThinkPad X1 | 16
(1 row)
-- JSON-Array durchsuchen
SELECT produktname, attribute->'farben' AS verfuegbare_farben
FROM produkte_extended
WHERE attribute->'farben' ? 'Schwarz'; -- Produkte in Schwarz
produktname | verfuegbare_farben
--------------------+-----------------------------
Laptop ThinkPad X1 | ["Schwarz", "Silber"]
Wireless Mouse MX3 | ["Schwarz", "Weiß", "Grau"]
(2 rows)
Wann JSON verwenden?
Vorteile:
- ✅ Flexibel für unterschiedliche Datenstrukturen
- ✅ Keine Schema-Änderungen nötig
- ✅ Ideal für externe APIs und Logs
Nachteile:
- ❌ Weniger performant als normale Spalten
- ❌ Schwieriger zu normalisieren
- ❌ Integritätsprüfungen komplizierter
Faustregel: Verwende JSON für optionale, flexible Daten, aber nicht für kritische Geschäftslogik.
So accurate..!!😓
byu/Abhi_mech007 inProgrammerHumor
Backup & Recovery
Datenbanken speichern oft geschäftskritische Daten. Bei Hardware-Ausfällen, Software-Fehlern oder menschlichen Fehlern ist ein Backup essentiell.
Typische PostgreSQL Backup-Methoden sind:
Backup mit pg_dump verwenden
Folgende Befehle müssen im Terminal (macOS) oder in der Powershell/CMD (Windows) eingegeben werden. Port (hier 5433) und Server (hier localhost) müssen gegebenenfalls angepasst werden.
Gesamte Datenbank sichern:
pg_dump -h localhost -p 5433 -U postgres shop_db > shop_db_backup.sql
Nur Struktur (ohne Daten):
pg_dump -h localhost -p 5433 -U postgres --schema-only shop_db > struktur.sql
Nur Daten (ohne Struktur):
pg_dump -h localhost -p 5433 -U postgres --data-only shop_db > daten.sql
Bestimmte Tabelle sichern:
pg_dump -h localhost -p 5433 -U postgres -t produkte shop_db > produkte_backup.sql
Wiederherstellen:
psql -h localhost -p 5433 -U postgres shop_db < shop_db_backup.sql
Zusammenfassung 📌
In diesem Kapitel haben wir einen Ausblick auf weiterführende Datenbankthemen erhalten:
- Views – Virtuelle Tabellen für vereinfachte Abfragen
- Stored Procedures & Functions – Wiederverwendbare SQL-Programme
- Trigger – Automatische Aktionen bei Datenänderungen
- JSON-Support – Flexible, semi-strukturierte Daten
- Backup & Recovery – Datensicherung und -wiederherstellung
Abschließende Gedanken 🎉
Datenbanken sind das Herzstück fast jeder modernen Anwendung. Egal ob Web-App, Mobile-App, Desktop-Software oder Data Science – überall werden Daten gespeichert, verwaltet und analysiert.
Das relationale Modell mit SQL ist seit über 50 Jahren der Standard und wird auch in absehbarer Zukunft wichtig bleiben. Die Konzepte, die du gelernt hast – Normalisierung, Beziehungen, Joins, Transaktionen – sind universell anwendbar und werden dich in deiner gesamten IT-Karriere begleiten.
Glückwunsch! 🎉
Du hast das Ende dieses Kurses erreicht und alle wichtigen Grundlagen zu Datenbanken und SQL gelernt!
Das hast du gemeistert:
- ✅ Datenmodellierung und ER-Diagramme
- ✅ SQL-Grundlagen (SELECT, INSERT, UPDATE, DELETE)
- ✅ Komplexe Abfragen mit Joins und Aggregationen
- ✅ Datenintegrität mit Constraints
- ✅ Transaktionen und ACID-Prinzipien
- ✅ Fortgeschrittene Konzepte und Ausblick
Nutze dieses Wissen als Startpunkt für deine eigenen Datenbankprojekte!
Viel Erfolg auf deiner Reise in die Welt der Datenbanken! 🚀