SQL Academy · Lektion

Fakta- og dimensionstabeller

Byggeklodserne i et data warehouse

Lektion 2 af 413 trin

Fakta- og dimensionstabeller er en gratis SQL Academy-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i SQL Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. SQL Academy-kurset indeholder 4 lektioner i alt.

Hvad er et datavarehus?

Et datavarehus er et centralt lager, der er udviklet til rapportering og analytiske forespørgsler. I modsætning til en transaktionsdatabase, der er optimeret til hurtige skrivninger, er et datavarehus indrettet til hurtige læsninger på tværs af store mængder historiske data.

Den mest almindelige måde at organisere et datavarehus på er med et stjerneskema, som opdeler data i to tabeltyper: faktatabeller og dimensionstabeller.

Definition af faktatabeller

En faktatabel gemmer målbare, kvantitative hændelser — det, du vil analysere. Hver række repræsenterer én forekomst af en forretningshændelse, f.eks. et salg, en visning af en webside eller en supportsag.

Faktatabeller er typisk omfattende (mange rækker) og smalle (få kolonner), hvor de fleste kolonner enten er fremmednøgler til dimensionstabeller eller numeriske mål som quantity eller revenue.

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,
  unit_price   NUMERIC(10, 2) NOT NULL,
  total_amount NUMERIC(12, 2) NOT NULL
);

Definition af dimensionstabeller

En dimensionstabel gemmer beskrivende attributter, der giver kontekst til hvert faktum. Eksempler omfatter en produkt-dimension (navn, kategori, mærke) eller en dato-dimension (dag, måned, kvartal, år).

Dimensionstabeller er normalt korte (færre rækker), men brede (mange beskrivende kolonner). De kobles til faktatabellen ved hjælp af surrogatnøgler som heltal.

CREATE TABLE dim_product (
  product_key  SERIAL PRIMARY KEY,
  product_name VARCHAR(200) NOT NULL,
  category     VARCHAR(100),
  brand        VARCHAR(100),
  unit_cost    NUMERIC(10, 2)
);

CREATE TABLE dim_customer (
  customer_key SERIAL PRIMARY KEY,
  full_name    VARCHAR(200) NOT NULL,
  email        VARCHAR(200),
  country      VARCHAR(100),
  segment      VARCHAR(50)
);

Datodimensionen

Datodimensionen er den mest almindelige dimension i ethvert datavarehus. I stedet for at gemme et råt TIMESTAMP i faktatabellen gemmer du en heltalsnøgle, der refererer til en på forhånd oprettet kalendertabel.

Det gør det muligt for forespørgsler at filtrere eller gruppere efter regnskabskvartal, ugedag, helligdagsmarkeringer og andre kalenderattributter uden datoberegninger på forespørgselstidspunktet.

CREATE TABLE dim_date (
  date_key       INT PRIMARY KEY,  -- e.g. 20240315
  full_date      DATE NOT NULL,
  day_of_week    VARCHAR(10),
  day_of_month   INT,
  month_num      INT,
  month_name     VARCHAR(20),
  quarter        INT,
  year           INT,
  is_holiday     BOOLEAN DEFAULT FALSE,
  fiscal_quarter INT
);

-- Sample row
INSERT INTO dim_date VALUES
  (20240315, '2024-03-15', 'Friday', 15, 3, 'March', 1, 2024, FALSE, 2);

Mønsteret for stjerneskemaet

Når du tegner et diagram med én faktatabel i midten og dimensionstabeller, der stråler ud fra den, ligner det en stjerne — deraf navnet stjerneskema.

Fremmednøgler i faktatabellen peger på primærnøglerne i hver dimension. Forespørgsler kobler typisk faktatabellen til én eller flere dimensioner for at føje beskrivende kontekst til de rå tal.

-- Join fact to two dimensions to enrich a sales report
SELECT
  dp.product_name,
  dp.category,
  SUM(fs.quantity)     AS total_units_sold,
  SUM(fs.total_amount) AS total_revenue
FROM fact_sales fs
JOIN dim_product  dp ON dp.product_key  = fs.product_key
JOIN dim_date     dd ON dd.date_key     = fs.date_key
WHERE dd.year = 2024
GROUP BY dp.product_name, dp.category
ORDER BY total_revenue DESC;

Surrogatnøgler vs. naturlige nøgler

Dimensionstabeller bruger surrogatnøgler — syntetiske heltal, der genereres af databasen og er uafhængige af enhver forretningsmæssig betydning. Naturlige nøgler (f.eks. en produkt-SKU eller en kundes e-mailadresse) kan ændre sig over tid, mens surrogatnøgler aldrig gør.

Surrogatnøgler afskærmer faktatabellen fra ændringer i opstrøms systemer og gør sammenkoblinger hurtigere, fordi sammenligninger af heltal er billigere end sammenligninger af strenge.

-- Surrogate key approach: integer join is fast
SELECT fs.sale_id, dc.full_name, fs.total_amount
FROM fact_sales fs
JOIN dim_customer dc ON dc.customer_key = fs.customer_key
WHERE dc.country = 'Germany'
LIMIT 10;

-- Natural key approach (avoid in warehouses): slower string join
-- JOIN dim_customer dc ON dc.email = fs.customer_email

Granularitet: Detaljeringsniveauet i en faktatabel

Granulariteten i en faktatabel beskriver præcis, hvad én række repræsenterer. Før du bygger et datavarehus, skal du fastslå granulariteten — f.eks. én række pr. individuel varelinje på en salgsordre.

En veldefineret granularitet forhindrer tvetydige aggregeringer. Hvis forskellige rækker repræsenterer forskellige hændelser, er resultaterne af SUM og COUNT meningsløse.

-- Grain: one row per product per order line
-- Each row = one line item sold in one transaction
SELECT
  sale_id,
  date_key,
  product_key,
  quantity,
  unit_price,
  total_amount
FROM fact_sales
WHERE date_key = 20240315
ORDER BY sale_id;

Additive, semi-additive og ikke-additive mål

Fakta findes i tre varianter afhængigt af, hvordan de kan aggregeres:

  • Additive — kan summeres på tværs af alle dimensioner (f.eks. revenue og quantity).
  • Semi-additive — kan summeres på tværs af nogle dimensioner, men ikke alle (f.eks. kan en kontos balance summeres på tværs af kunder, men ikke over tid).
  • Ikke-additive — kan ikke summeres meningsfuldt (f.eks. unit_price og ratio). Brug AVG eller andre aggregeringsfunktioner i stedet.
SELECT
  dd.month_name,
  SUM(fs.total_amount)         AS total_revenue,   -- additive
  AVG(fs.unit_price)           AS avg_unit_price,   -- non-additive: use AVG
  SUM(fs.quantity)             AS total_units       -- additive
FROM fact_sales fs
JOIN dim_date dd ON dd.date_key = fs.date_key
WHERE dd.year = 2024
GROUP BY dd.month_name, dd.month_num
ORDER BY dd.month_num;

Langsomt skiftende dimensioner (SCD type 1 og 2)

Dimensionsattributter ændrer sig over tid — en kunde flytter til et andet land, og et produkt skifter kategori. Langsomt skiftende dimensioner (SCD) håndterer disse ændringer:

  • Type 1 — Overskriv den gamle værdi. Enkelt, men historikken går tabt.
  • Type 2 — Tilføj en ny række med en ny surrogatnøgle og gyldighedsdatoer. Bevarer hele historikken, så historiske fakta stadig peger på den korrekte version af dimensionen.
-- SCD Type 2: add a new version of the row
ALTER TABLE dim_customer ADD COLUMN valid_from DATE;
ALTER TABLE dim_customer ADD COLUMN valid_to   DATE;
ALTER TABLE dim_customer ADD COLUMN is_current BOOLEAN DEFAULT TRUE;

-- Expire the old row
UPDATE dim_customer
SET is_current = FALSE,
    valid_to   = CURRENT_DATE - INTERVAL '1 day'
WHERE email = 'anna@example.com' AND is_current = TRUE;

-- Insert the updated version
INSERT INTO dim_customer (full_name, email, country, segment, valid_from, valid_to, is_current)
VALUES ('Anna Muller', 'anna@example.com', 'Austria', 'Premium', CURRENT_DATE, '9999-12-31', TRUE);

Degenerative dimensioner

Nogle gange behøver en dimensionsattribut ikke sin egen tabel. En degenereret dimension er en dimensionsnøgle, der ligger direkte i faktatabellen uden en tilsvarende dimensionstabel.

Klassiske eksempler er ordrenumre, fakturanumre eller supportsags-id'er. De giver kontekst til at gå ned i detaljerne, men har ingen andre beskrivende kolonner, der er værd at gemme i en separat tabel.

-- order_number is a degenerate dimension:
-- it lives in the fact table, no dim_order table needed
CREATE TABLE fact_order_lines (
  line_id      SERIAL PRIMARY KEY,
  order_number VARCHAR(20) NOT NULL,  -- degenerate dimension
  date_key     INT NOT NULL,
  product_key  INT NOT NULL,
  customer_key INT NOT NULL,
  quantity     INT NOT NULL,
  line_total   NUMERIC(12, 2) NOT NULL
);

SELECT order_number, SUM(line_total) AS order_total
FROM fact_order_lines
GROUP BY order_number
ORDER BY order_total DESC
LIMIT 5;

Forespørgsler i det fulde stjerneskema

Når du samler det hele, kobler en typisk forespørgsel i et datavarehus faktatabellen til flere dimensioner, anvender filtre på dimensionsattributter og aggregerer mål fra faktatabellen.

Optimeringsprogrammet kan håndtere disse flervejs-sammenkoblinger effektivt, fordi fremmednøglerne i faktatabellen er indekserede, og dimensionstabellerne er relativt små.

SELECT
  dd.year,
  dd.quarter,
  dp.category,
  dc.country,
  SUM(fs.quantity)     AS units_sold,
  SUM(fs.total_amount) AS revenue
FROM fact_sales fs
JOIN dim_date     dd ON dd.date_key     = fs.date_key
JOIN dim_product  dp ON dp.product_key  = fs.product_key
JOIN dim_customer dc ON dc.customer_key = fs.customer_key
WHERE dd.year IN (2023, 2024)
  AND dp.category = 'Electronics'
GROUP BY dd.year, dd.quarter, dp.category, dc.country
ORDER BY dd.year, dd.quarter, revenue DESC;

Hurtigt tjek: Fakta vs. dimension

Kontrollér din forståelse af forskellene mellem fakta- og dimensionstabeller i et stjerneskema.

Opsummering af lektionen

I denne lektion har du lært de grundlæggende byggesten i et datavarehuss stjerneskema:

  • Faktatabeller indeholder målbare hændelser (salg, klik, transaktioner) med numeriske mål og fremmednøgler.
  • Dimensionstabeller giver beskrivende kontekst (hvem, hvad, hvor, hvornår) ved hjælp af surrogatnøgler.
  • Granulariteten definerer præcis, hvad én faktarække repræsenterer — fastslå den, før du bygger.
  • Mål er additive, semi-additive eller ikke-additive, hvilket afgør, hvordan du aggregerer dem.
  • SCD type 2 bevarer historiske dimensionsværdier ved at tilføje nye rækker med gyldighedsdatoer.
  • Degenerative dimensioner ligger i faktatabellen, når de ikke har yderligere attributter, der skal beskrives.

En forståelse af fakta- og dimensionstabeller er grundlaget for at bygge hurtige, skalerbare og analytisk stærke datavarehuse.

Gratis at komme i gang

Lær SQL med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
46
Lektioner
183

Ofte stillede spørgsmål

Er lektionen “Fakta- og dimensionstabeller” gratis?

Ja — hele teksten til “Fakta- og dimensionstabeller” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af SQL Academy-kurset, skal du opgradere til CoddyKit PRO. SQL Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Fakta- og dimensionstabeller”?

Byggeklodserne i et data warehouse Du øver dig i SQL Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på SQL Academy?

Der kræves ingen tidligere erfaring. SQL Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.

Hvor lang tid tager lektionen “Fakta- og dimensionstabeller”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne SQL Academy-lektion?

Ja. Alle SQL Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. OLTP vs. OLAP
  2. Fakta- og dimensionstabeller
  3. Stjerne- og snefnugsskemaer
  4. Skriv analytiske forespørgsler
← Tilbage til SQL Academy