Ster- en sneeuwvlokschema's
Modelleer gegevens voor snelle analyses
Ster- en sneeuwvlokschema's is een gratis SQL Academy-les op CoddyKit. Dit is les 3 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject SQL Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus SQL Academy bevat in totaal 4 lessen.
Wat is een datawarehouseschema?
In een transactionele (OLTP-)database normaliseer je gegevens om redundantie te voorkomen. In een datawarehouse denormaliseer je gegevens vaak bewust — je ruilt opslagruimte in voor querysnelheid. Twee klassieke patronen voor het indelen van datawarehousetabellen zijn het sterschema en het sneeuwvlokschema.
Beide draaien rond een centrale feittabel met daaromheen dimensietabellen. Het verschil is hoever je die dimensies normaliseert.
Feittabellen en dimensietabellen
Een feittabel bevat meetbare gebeurtenissen — verkopen, klikken en verzendingen. De tabel is omvangrijk (veel rijen) en bevat numerieke meetwaarden plus vreemde sleutels naar dimensies.
Een dimensietabel beschrijft de context van elke gebeurtenis: wie, wat, wanneer en waar. Dimensies zijn kleiner (minder rijen), maar bevatten meer beschrijvende kolommen.
CREATE TABLE fact_sales (
sale_id SERIAL PRIMARY KEY,
date_key INT NOT NULL,
product_key INT NOT NULL,
customer_key INT NOT NULL,
store_key INT NOT NULL,
quantity INT NOT NULL,
revenue NUMERIC(12, 2) NOT NULL
);
CREATE TABLE dim_product (
product_key SERIAL PRIMARY KEY,
product_name VARCHAR(200),
category VARCHAR(100),
brand VARCHAR(100),
unit_price NUMERIC(10, 2)
);Het sterschema
In een sterschema is elke dimensietabel rechtstreeks verbonden met de feittabel. Teken de relaties op papier en het ziet eruit als een ster — de feittabel is het middelpunt en de dimensies zijn de punten.
Dimensietabellen zijn volledig gedenormaliseerd: alle beschrijvende attributen staan in één tabel, ook als sommige attributen in meerdere rijen worden herhaald.
-- Star schema: all product info in one flat dimension table
CREATE TABLE dim_product (
product_key SERIAL PRIMARY KEY,
product_name VARCHAR(200),
category_name VARCHAR(100), -- denormalized
subcategory VARCHAR(100), -- denormalized
brand_name VARCHAR(100), -- denormalized
brand_country VARCHAR(100), -- denormalized
unit_price NUMERIC(10, 2)
);
CREATE TABLE dim_date (
date_key INT PRIMARY KEY, -- e.g. 20240315
full_date DATE,
year INT,
quarter INT,
month INT,
month_name VARCHAR(20),
week INT,
day_of_week VARCHAR(10)
);Query voor het sterschema
Dankzij de vlakke dimensietabellen zijn query's eenvoudig. Je koppelt de feittabel aan een of meer dimensies en aggregeert de gegevens. Er zijn geen extra koppelingen via ketens van genormaliseerde tabellen.
Daarom leveren sterschema's snelle analytische query's — de koppelingsgrafiek is ondiep.
SELECT
d.year,
d.quarter,
p.category_name,
SUM(f.revenue) AS total_revenue,
SUM(f.quantity) AS units_sold
FROM fact_sales f
JOIN dim_date d ON d.date_key = f.date_key
JOIN dim_product p ON p.product_key = f.product_key
WHERE d.year = 2024
GROUP BY d.year, d.quarter, p.category_name
ORDER BY d.quarter, total_revenue DESC;Het sneeuwvlokschema
Een sneeuwvlokschema normaliseert dimensietabellen verder door ze op te splitsen in subdimensies. In plaats van bijvoorbeeld category_name en brand_name op te slaan in dim_product, maak je afzonderlijke tabellen dim_category en dim_brand.
Het resulterende diagram ziet eruit als een sneeuwvlok — vertakkende armen van gerelateerde tabellen.
-- Snowflake schema: product dimension is normalized
CREATE TABLE dim_brand (
brand_key SERIAL PRIMARY KEY,
brand_name VARCHAR(100),
brand_country VARCHAR(100)
);
CREATE TABLE dim_category (
category_key SERIAL PRIMARY KEY,
category_name VARCHAR(100),
subcategory VARCHAR(100)
);
CREATE TABLE dim_product (
product_key SERIAL PRIMARY KEY,
product_name VARCHAR(200),
category_key INT REFERENCES dim_category(category_key),
brand_key INT REFERENCES dim_brand(brand_key),
unit_price NUMERIC(10, 2)
);Query's op een sneeuwvlokschema
Voor het opvragen van gegevens uit een sneeuwvlokschema zijn meer joins nodig om dimensiegegevens die over meerdere tabellen zijn verdeeld weer samen te voegen. De query-optimizer moet de extra niveaus doorlopen, wat vergeleken met een sterschema extra latentie kan veroorzaken.
De genormaliseerde dimensies zijn echter kleiner en consistent — als je een merknaam in één rij van dim_brand bijwerkt, wordt die wijziging automatisch overal toegepast.
SELECT
d.year,
c.category_name,
b.brand_name,
SUM(f.revenue) AS total_revenue
FROM fact_sales f
JOIN dim_date d ON d.date_key = f.date_key
JOIN dim_product p ON p.product_key = f.product_key
JOIN dim_category c ON c.category_key = p.category_key
JOIN dim_brand b ON b.brand_key = p.brand_key
WHERE d.year = 2024
GROUP BY d.year, c.category_name, b.brand_name
ORDER BY total_revenue DESC;Surrogaatsleutels versus natuurlijke sleutels
Dimensietabellen gebruiken meestal een surrogaatssleutel — een door het datawarehouse gegenereerd geheel getal (bijvoorbeeld SERIAL) — in plaats van een natuurlijke sleutel uit het bronsysteem.
Surrogaatsleutels blijven stabiel, ook wanneer de bron verandert. Ze zijn compact voor grote feitentabellen en ondersteunen langzaam veranderende dimensies waarvan de geschiedenis moet worden bijgehouden.
-- Surrogate key (product_key) vs natural key (sku)
INSERT INTO dim_product (product_name, category_key, brand_key, unit_price)
VALUES ('Wireless Headphones', 3, 7, 89.99);
-- product_key is assigned by SERIAL -- the natural key (SKU) lives elsewhere
-- Natural key would be:
-- INSERT INTO dim_product (sku, product_name, ...)
-- VALUES ('WH-1000XM5', 'Wireless Headphones', ...);
-- Risky: SKU can be reused or reassigned by the source systemDe datumdimensie
De datumdimensie is bijzonder — deze is vrijwel altijd aanwezig en wordt meestal vooraf gevuld met datums voor vele jaren. Door afgeleide kenmerken (jaar, kwartaal, maandnaam, boekhoudperiode, feestdagmarkering) in de dimensietabel op te slaan, hoef je ze niet opnieuw te berekenen wanneer je een query uitvoert.
-- Populate dim_date for one year using generate_series
INSERT INTO dim_date (date_key, full_date, year, quarter, month, month_name, week, day_of_week)
SELECT
TO_CHAR(d, 'YYYYMMDD')::INT AS date_key,
d AS full_date,
EXTRACT(YEAR FROM d)::INT AS year,
EXTRACT(QUARTER FROM d)::INT AS quarter,
EXTRACT(MONTH FROM d)::INT AS month,
TO_CHAR(d, 'Month') AS month_name,
EXTRACT(WEEK FROM d)::INT AS week,
TO_CHAR(d, 'Day') AS day_of_week
FROM generate_series('2024-01-01'::DATE, '2024-12-31'::DATE, '1 day') AS d;Langzaam veranderende dimensies (SCD Type 2)
Wat gebeurt er wanneer een klant van stad verhuist of een product van categorie verandert? Je moet de geschiedenis bijhouden. SCD Type 2 voegt voor elke wijziging een nieuwe dimensierij toe en sluit de vorige rij af met een einddatum. De rij in de feitentabel verwijst nog steeds naar de oude dimensiesleutel, waardoor de historische nauwkeurigheid behouden blijft.
-- SCD Type 2 customer dimension
CREATE TABLE dim_customer (
customer_key SERIAL PRIMARY KEY,
customer_id INT NOT NULL,
customer_name VARCHAR(200),
city VARCHAR(100),
country VARCHAR(100),
valid_from DATE NOT NULL,
valid_to DATE,
is_current BOOLEAN DEFAULT TRUE
);
-- When a customer moves, close old row and insert new one:
UPDATE dim_customer
SET valid_to = CURRENT_DATE - 1, is_current = FALSE
WHERE customer_id = 42 AND is_current = TRUE;
INSERT INTO dim_customer (customer_id, customer_name, city, country, valid_from, is_current)
VALUES (42, 'Alice Muller', 'Berlin', 'Germany', CURRENT_DATE, TRUE);Sterschema versus sneeuwvlokschema — afwegingen
Geen van beide schema's is altijd beter. Kies op basis van je prioriteiten:
- Ster — minder joins, snellere query's, eenvoudiger ETL en hogere opslagkosten. Het meest geschikt voor analysetools die veel lezen (Tableau, Power BI).
- Sneeuwvlok — genormaliseerde dimensies, minder redundantie en eenvoudiger dimensies bijwerken, maar meer joins. Beter wanneer dimensies groot zijn of worden gedeeld door meerdere feitentabellen.
-- Checking how much storage the denormalized category column costs
-- in a large dim_product (star schema) vs a separate dim_category (snowflake)
SELECT
COUNT(*) AS total_products,
COUNT(DISTINCT category_name) AS unique_categories,
pg_size_pretty(
SUM(pg_column_size(category_name))
) AS category_storage
FROM dim_product;Galaxyschema (feitenconstellatie)
Wanneer een datawarehouse meerdere feitentabellen bevat die dimensietabellen delen, heet het resultaat een galaxyschema (of feitenconstellatie). Een datawarehouse voor detailhandel kan bijvoorbeeld afzonderlijke feitentabellen voor verkopen en retouren bevatten, die allebei verwijzen naar dim_product en dim_date.
Gedeelde dimensies zorgen voor consistente filters en maken vergelijkingen tussen feiten eenvoudig.
CREATE TABLE fact_returns (
return_id SERIAL PRIMARY KEY,
date_key INT NOT NULL REFERENCES dim_date(date_key),
product_key INT NOT NULL REFERENCES dim_product(product_key),
customer_key INT NOT NULL,
quantity INT NOT NULL,
refund_amount NUMERIC(12, 2) NOT NULL
);
-- Cross-fact query: net revenue = sales - refunds
SELECT
d.year,
d.month,
SUM(s.revenue) AS gross_revenue,
SUM(r.refund_amount) AS total_refunds,
SUM(s.revenue) - COALESCE(SUM(r.refund_amount), 0) AS net_revenue
FROM dim_date d
LEFT JOIN fact_sales s ON s.date_key = d.date_key
LEFT JOIN fact_returns r ON r.date_key = d.date_key
WHERE d.year = 2024
GROUP BY d.year, d.month
ORDER BY d.month;Sterschema versus sneeuwvlokschema
Toets je begrip van ster- en sneeuwvlokschema's.
Lesoverzicht
In deze les heb je twee fundamentele ontwerppatronen voor datawarehouses verkend:
- Sterschema — een centrale feitentabel, omringd door vlakke, gedenormaliseerde dimensietabellen. Minder joins, snellere query's en iets meer opslag.
- Sneeuwvlokschema — dimensietabellen worden verder genormaliseerd tot subdimensies. Minder redundantie en eenvoudiger bijwerken, maar er zijn meer joins nodig.
- Feitentabellen bevatten meetbare gebeurtenissen; dimensietabellen bieden context (wie, wat, wanneer, waar).
- Surrogaatsleutels beschermen de historische nauwkeurigheid en ontkoppelen het datawarehouse van wijzigingen in het bronsysteem.
- SCD Type 2 houdt de dimensiegeschiedenis bij door nieuwe rijen met geldigheidsdatums toe te voegen in plaats van oude rijen te overschrijven.
- Wanneer meerdere feitentabellen dimensies delen, wordt het ontwerp een galaxyschema (feitenconstellatie).
Kies een ster voor eenvoud en snelheid; kies een sneeuwvlok wanneer dimensies groot zijn, vaak worden bijgewerkt of door veel feitentabellen worden gedeeld.
Leer SQL met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 46
- Lessen
- 183
Veelgestelde vragen
Is de les “Ster- en sneeuwvlokschema's” gratis?
Ja — de volledige tekst van “Ster- en sneeuwvlokschema's” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus SQL Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus SQL Academy bevat in totaal 4 lessen.
Wat leer ik in “Ster- en sneeuwvlokschema's”?
Modelleer gegevens voor snelle analyses Je oefent met SQL Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met SQL Academy te beginnen?
Ervaring vooraf is niet nodig. SQL Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.
Hoe lang duurt de les “Ster- en sneeuwvlokschema's”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over SQL Academy?
Ja. Elke les over SQL Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- OLTP versus OLAP
- Fact- en dimensietabellen
- Ster- en sneeuwvlokschema's
- Analytische query's schrijven