-- ============================================================ -- Tierarztpraxis DWH — Snowflake Schema (PostgreSQL) -- Kapitel 19: Data Warehousing -- Erweiterung des Star Schema: dim_tier normalisiert -- ============================================================ -- Snowflake: dim_tier wird in Unter-Dimensionen zerlegt -- dim_tier → dim_tierart + dim_rasse + dim_besitzer DROP TABLE IF EXISTS fakt_behandlung_sf CASCADE; DROP TABLE IF EXISTS dim_tier_sf CASCADE; DROP TABLE IF EXISTS dim_tierart CASCADE; DROP TABLE IF EXISTS dim_rasse CASCADE; DROP TABLE IF EXISTS dim_besitzer CASCADE; -- ============================================================ -- Normalisierte Unter-Dimensionen -- ============================================================ CREATE TABLE dim_tierart ( tierart_id SERIAL PRIMARY KEY, tierart VARCHAR(30) NOT NULL UNIQUE ); CREATE TABLE dim_rasse ( rasse_id SERIAL PRIMARY KEY, rasse VARCHAR(50) NOT NULL, tierart_id INT REFERENCES dim_tierart ); CREATE TABLE dim_besitzer ( besitzer_id SERIAL PRIMARY KEY, name VARCHAR(80) NOT NULL, ort VARCHAR(50) ); -- Normalisierte Tierdimension (Snowflake) CREATE TABLE dim_tier_sf ( tier_id SERIAL PRIMARY KEY, name VARCHAR(50), geschlecht CHAR(1), rasse_id INT REFERENCES dim_rasse, besitzer_id INT REFERENCES dim_besitzer ); -- Faktentabelle (identisch zu Star, nur FK auf dim_tier_sf) CREATE TABLE fakt_behandlung_sf ( behandlung_id SERIAL PRIMARY KEY, zeit_id INT NOT NULL REFERENCES dim_zeit, tier_id INT NOT NULL REFERENCES dim_tier_sf, tierarzt_id INT NOT NULL REFERENCES dim_tierarzt, diagnose_id INT NOT NULL REFERENCES dim_diagnose, praxis_id INT NOT NULL REFERENCES dim_praxis, kosten NUMERIC(10,2) NOT NULL, dauer_min INT, medikamente INT DEFAULT 0 ); -- ============================================================ -- Daten fuellen -- ============================================================ INSERT INTO dim_tierart (tierart) VALUES ('Hund'), ('Katze'), ('Schildkroete'), ('Wellensittich'), ('Kaninchen'), ('Pferd'); INSERT INTO dim_rasse (rasse, tierart_id) VALUES ('Labrador', (SELECT tierart_id FROM dim_tierart WHERE tierart='Hund')), ('Schaeferhund', (SELECT tierart_id FROM dim_tierart WHERE tierart='Hund')), ('Golden Retriever', (SELECT tierart_id FROM dim_tierart WHERE tierart='Hund')), ('Boxer', (SELECT tierart_id FROM dim_tierart WHERE tierart='Hund')), ('Perser', (SELECT tierart_id FROM dim_tierart WHERE tierart='Katze')), ('Europaeisch Kurzhaar',(SELECT tierart_id FROM dim_tierart WHERE tierart='Katze')), ('Maine Coon', (SELECT tierart_id FROM dim_tierart WHERE tierart='Katze')), ('Griechische', (SELECT tierart_id FROM dim_tierart WHERE tierart='Schildkroete')), ('Standard', (SELECT tierart_id FROM dim_tierart WHERE tierart='Wellensittich')), ('Zwergkaninchen', (SELECT tierart_id FROM dim_tierart WHERE tierart='Kaninchen')), ('Hannoveraner', (SELECT tierart_id FROM dim_tierart WHERE tierart='Pferd')), ('Haflinger', (SELECT tierart_id FROM dim_tierart WHERE tierart='Pferd')); INSERT INTO dim_besitzer (name, ort) VALUES ('Hans Berger', 'Juckstadt'), ('Anna Waldner', 'Juckstadt'), ('Tom Fuchs', 'Juckstadt'), ('Lisa Meier', 'Bellhausen'), ('Eva Braun', 'Bellhausen'), ('Sara Klein', 'Bellhausen'), ('Karl Reiter', 'Reitdorf'), ('Maria Hof', 'Reitdorf'); INSERT INTO dim_tier_sf (name, geschlecht, rasse_id, besitzer_id) SELECT t.name, t.geschlecht, r.rasse_id, b.besitzer_id FROM dim_tier t JOIN dim_rasse r ON r.rasse = t.rasse JOIN dim_besitzer b ON b.name = t.besitzer; -- Fakten kopieren (gleiche Daten, anderer FK) INSERT INTO fakt_behandlung_sf (zeit_id, tier_id, tierarzt_id, diagnose_id, praxis_id, kosten, dauer_min, medikamente) SELECT f.zeit_id, tsf.tier_id, f.tierarzt_id, f.diagnose_id, f.praxis_id, f.kosten, f.dauer_min, f.medikamente FROM fakt_behandlung f JOIN dim_tier t ON t.tier_id = f.tier_id JOIN dim_tier_sf tsf ON tsf.name = t.name; -- ============================================================ -- Vergleichsabfrage: Star vs. Snowflake -- ============================================================ -- Star: 1 JOIN fuer Tierart -- SELECT t.tierart, SUM(f.kosten) -- FROM fakt_behandlung f JOIN dim_tier t ON ... -- Snowflake: 3 JOINs fuer Tierart -- SELECT ta.tierart, SUM(f.kosten) -- FROM fakt_behandlung_sf f -- JOIN dim_tier_sf t ON f.tier_id = t.tier_id -- JOIN dim_rasse r ON t.rasse_id = r.rasse_id -- JOIN dim_tierart ta ON r.tierart_id = ta.tierart_id -- GROUP BY ta.tierart;