Tilbake
6.2
Relasjonsdatabaser og datamodellering

6.2 Relasjonsdatabaser og datamodellering

Forstå relasjonsdatabasemodellen, fremmednøkler, relasjonstyper og ER-diagrammer.

60 min
7 oppgaver
FremmednøkkelRelasjonER-diagramEntitet
Du leser den tradisjonelle versjonen
Din fremgang i kapitlet
0 / 7 oppgaver

Relasjonsdatabaser og datamodellering

I forrige kapittel ble vi kjent med grunnleggende databasebegreper. Nå skal vi dykke dypere inn i relasjonsdatabasemodellen – den modellen som ligger til grunn for de fleste databaser i verden. Vi skal lære hvordan tabeller kobles sammen, hvilke typer relasjoner som finnes, og hvordan vi planlegger en database ved hjelp av ER-diagrammer.

God datamodellering er noe av det viktigste du kan lære om databaser. En godt designet database er enkel å jobbe med, rask å søke i og lett å utvide. En dårlig designet database fører derimot til dupliserte data, inkonsistens og ytelsessproblemer som er vanskelige å rette opp i etterkant. Derfor bruker man alltid tid på å planlegge databasestrukturen grundig før man begynner å lage tabeller og fylle inn data.

Fremmednøkkel (Foreign Key)

En fremmednøkkel er en kolonne i en tabell som inneholder verdier som refererer til primærnøkkelen i en annen tabell. Fremmednøkler er limet som holder en relasjonsdatabase sammen – de oppretter koblinger mellom tabeller. Fremmednøkler sikrer referanseintegritet, som betyr at databasen hindrer deg i å opprette referanser til rader som ikke eksisterer. For eksempel kan du ikke registrere en karakter for elev_id 99 hvis det ikke finnes noen elev med id 99 i elevtabellen.

Det finnes tre grunnleggende typer relasjoner mellom tabeller i en relasjonsdatabase:

1. En-til-en (1:1)

Hver rad i tabell A er koblet til nøyaktig én rad i tabell B, og omvendt. Denne typen er relativt sjelden.

Eksempel: Hver elev har nøyaktig ett elevkort, og hvert elevkort tilhører nøyaktig én elev.

elevidfornavnetternavnkortidelevidkortnummerutstedtdato
1EmmaHansen11EK-2024-0012024-08-15
2OliverJohansen22EK-2024-0022024-08-15

2. En-til-mange (1:N)


Én rad i tabell A kan kobles til mange rader i tabell B, men hver rad i tabell B kobles til bare én rad i tabell A. Dette er den vanligste relasjonstypen.
Eksempel: Én klasse har mange elever, men hver elev tilhører bare én klasse.

klasseidklassenavnelevidfornavnklasseid
110A1Emma1
210B2Oliver1
3Nora2

Fremmednøkkelen klasse_id ligger på mange-siden (i elevtabellen).

3. Mange-til-mange (M:N)

Mange rader i tabell A kan kobles til mange rader i tabell B. Denne relasjonstypen krever alltid en koblingstabell.
Eksempel: En elev kan ha mange fag, og et fag kan ha mange elever.
Denne relasjonen kan ikke løses med bare en fremmednøkkel – vi trenger en koblingstabell mellom de to:
eleverelevfagfag

✏️Eksempel: Mange-til-mange med koblingstabell

La oss se på forholdet mellom elever og fag:

Tabell: elever

elevidfornavnetternavn
1EmmaHansen
2OliverJohansen
3NoraOlsen

Tabell: fag
fagidfagnavn
1Matematikk
2Norsk
3Naturfag

Koblingstabell: elevfag
elevidfagid
11
12
13
21
22
32
33

Her kan vi lese at:
- Emma (elev
id 1) tar matematikk, norsk og naturfag
- Oliver (elevid 2) tar matematikk og norsk
- Nora (elev
id 3) tar norsk og naturfag
Koblingstabellen har en sammensatt primærnøkkel bestående av begge fremmednøklene (elev_id + fag_id). Den kan også utvides med ekstra kolonner, for eksempel karakter eller termin.

Før du oppretter en database, bør du planlegge strukturen visuelt. Et ER-diagram (Entity-Relationship-diagram) er et standardverktøy for dette. ER-diagrammer viser:

- Entiteter (ting vi lagrer informasjon om) som rektangler
- Attributter (egenskaper) som ovaler koblet til entiteten
- Relasjoner som linjer mellom entiteter med markeringer for relasjonstype

Kråkefotsnotasjon (Crow's Foot)

Den mest brukte notasjonen for ER-diagrammer i praksis er kråkefotsnotasjon. Her brukes symboler på linjene mellom tabellene:

- | (strek) = nøyaktig én
- O (sirkel) = null (valgfri)
- < (kråkefot/gaffel) = mange

Kombinasjoner:
- ||——|| = en-til-en (begge obligatoriske)
- ||——O< = en-til-mange (mange-siden er valgfri)
- ||——|< = en-til-mange (mange-siden er obligatorisk)
- >O——O< = mange-til-mange (begge sider valgfrie)

Eksempel: ER-diagram for skoledatabase

┌──────────┐         ┌──────────┐
│  Klasse  │ 1     N │   Elev   │
│──────────│─────────│──────────│
│ klasse_id│         │ elev_id  │
│ navn     │         │ fornavn  │
└──────────┘         │ etternavn│
                     │ klasse_id│
                     └──────────┘
                          │
                          │ N
                     ┌──────────┐
                     │ Elev_Fag │
                     │──────────│
                     │ elev_id  │
                     │ fag_id   │
                     │ karakter │
                     └──────────┘
                          │
                          │ N
                     ┌──────────┐
                     │   Fag    │
                     │──────────│
                     │ fag_id   │
                     │ fagnavn  │
                     │ laerer   │
                     └──────────┘

Her ser vi at Klasse har en en-til-mange-relasjon med Elev (én klasse har mange elever), og Elev har en mange-til-mange-relasjon med Fag (via koblingstabellen Elev_Fag).

Når vi har planlagt databasestrukturen, er neste steg å opprette tabellene med SQL. Kommandoen CREATE TABLE brukes til å definere en ny tabell med kolonner, datatyper og begrensninger.

Her er SQL-koden for skoledatabasen:

-- Opprett tabellen for klasser
CREATE TABLE klasser (
    klasse_id INTEGER PRIMARY KEY AUTOINCREMENT,
    klassenavn TEXT NOT NULL
);

-- Opprett tabellen for elever
CREATE TABLE elever (
    elev_id INTEGER PRIMARY KEY AUTOINCREMENT,
    fornavn TEXT NOT NULL,
    etternavn TEXT NOT NULL,
    fodselsdato DATE,
    klasse_id INTEGER,
    FOREIGN KEY (klasse_id) REFERENCES klasser(klasse_id)
);

-- Opprett tabellen for fag
CREATE TABLE fag (
    fag_id INTEGER PRIMARY KEY AUTOINCREMENT,
    fagnavn TEXT NOT NULL,
    laerer TEXT
);

-- Opprett koblingstabellen for elever og fag
CREATE TABLE elev_fag (
    elev_id INTEGER,
    fag_id INTEGER,
    karakter INTEGER,
    termin TEXT,
    PRIMARY KEY (elev_id, fag_id),
    FOREIGN KEY (elev_id) REFERENCES elever(elev_id),
    FOREIGN KEY (fag_id) REFERENCES fag(fag_id)
);

La oss bryte ned de viktigste elementene:

- INTEGER PRIMARY KEY AUTOINCREMENT – Oppretter en primærnøkkel som automatisk øker med 1 for hver ny rad
- TEXT NOT NULL – Kolonnen lagrer tekst og kan ikke være tom
- FOREIGN KEY ... REFERENCES ... – Oppretter en fremmednøkkel som refererer til en annen tabell
- PRIMARY KEY (elev_id, fag_id) – Sammensatt primærnøkkel som sikrer at kombinasjonen av elev og fag er unik

✏️Eksempel: Datamodell for en nettbutikk

La oss modellere en enkel nettbutikk med kunder, produkter og bestillinger.

Entiteter og attributter:
- Kunde: kundeid, fornavn, etternavn, epost, telefon
- Produkt: produkt
id, produktnavn, beskrivelse, pris, antallpaalager
- Bestilling: bestillingid, kundeid, bestillingsdato, totalpris, status
- Bestillingslinje: bestillingid, produktid, antall, linjepris

Relasjoner:
- Kunde → Bestilling: En-til-mange (én kunde kan ha mange bestillinger)
- Bestilling → Bestillingslinje: En-til-mange (én bestilling kan ha mange produkter)
- Produkt → Bestillingslinje: En-til-mange (ett produkt kan være i mange bestillinger)

CREATE TABLE kunder (
    kunde_id INTEGER PRIMARY KEY AUTOINCREMENT,
    fornavn TEXT NOT NULL,
    etternavn TEXT NOT NULL,
    epost TEXT UNIQUE NOT NULL,
    telefon TEXT
);

CREATE TABLE produkter (
    produkt_id INTEGER PRIMARY KEY AUTOINCREMENT,
    produktnavn TEXT NOT NULL,
    beskrivelse TEXT,
    pris REAL NOT NULL,
    antall_paa_lager INTEGER DEFAULT 0
);

CREATE TABLE bestillinger (
    bestilling_id INTEGER PRIMARY KEY AUTOINCREMENT,
    kunde_id INTEGER NOT NULL,
    bestillingsdato DATE DEFAULT CURRENT_DATE,
    totalpris REAL,
    status TEXT DEFAULT 'ny',
    FOREIGN KEY (kunde_id) REFERENCES kunder(kunde_id)
);

CREATE TABLE bestillingslinjer (
    bestilling_id INTEGER,
    produkt_id INTEGER,
    antall INTEGER NOT NULL,
    linjepris REAL NOT NULL,
    PRIMARY KEY (bestilling_id, produkt_id),
    FOREIGN KEY (bestilling_id) REFERENCES bestillinger(bestilling_id),
    FOREIGN KEY (produkt_id) REFERENCES produkter(produkt_id)
);

Her ser vi mange-til-mange-relasjonen mellom bestillinger og produkter løst gjennom koblingstabellen bestillingslinjer. En bestilling kan inneholde mange produkter, og et produkt kan inngå i mange bestillinger.

📝Oppgave 6.2.1

Hva er en fremmednøkkel?

📝Oppgave 6.2.2

Hvilken relasjonstype finnes mellom tabellene «klasser» og «elever» hvis hver elev tilhører nøyaktig én klasse, men en klasse kan ha mange elever?

📝Oppgave 6.2.3

Hvordan implementeres en mange-til-mange-relasjon i en relasjonsdatabase?

📝Oppgave 6.2.4

Gitt følgende SQL:

CREATE TABLE elever (
    elev_id INTEGER PRIMARY KEY AUTOINCREMENT,
    fornavn TEXT NOT NULL,
    etternavn TEXT NOT NULL,
    klasse_id INTEGER,
    FOREIGN KEY (klasse_id) REFERENCES klasser(klasse_id)
);

Hva betyr NOT NULL for kolonnene fornavn og etternavn?

📝Oppgave 6.2.5

Tegn et ER-diagram (eller beskriv det med tekst) for en enkel kino-database. Kinoen trenger å holde oversikt over filmer (tittel, sjanger, lengde, aldersgrense), saler (salnummer, antall plasser) og forestillinger (dato, klokkeslett). Identifiser entiteter, attributter, primærnøkler og relasjoner mellom tabellene.

📝Oppgave 6.2.6

Skriv SQL-kode (CREATE TABLE) for kino-databasen fra forrige oppgave. Inkluder passende datatyper, primærnøkler, fremmednøkler og NOT NULL-begrensninger der det er relevant.

📝Oppgave 6.2.7

Du har tabellene forfattere og boker. En forfatter kan skrive mange bøker, og en bok kan ha flere forfattere (samarbeid). Hvilken relasjonstype er dette, og hvordan løses det?

Oppsummering

I dette kapittelet har du lært:

- Relasjonsmodellen: tabeller koblet med nøkler.
- Fremmednoekkel: refererer til primærnøkkelen i en annen tabell.
- Relasjonstyper: en-til-en, en-til-mange og mange-til-mange.
- Koblingstabell: løser mange-til-mange-relasjoner.
- ER-diagram: modellerer datastrukturer (kraakefotsnotasjon).

Noekkelbegreper


BegrepForklaring
FremmednoekkelKolonne som refererer til en annen tabells primaernoekkel
ER-diagramDiagram som modellerer entiteter og relasjoner
KoblingstabellTabell som løser mange-til-mange-relasjoner

Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.