• Lærebøker
  • Python
  • GeoGebra
  • Hoderegning
  • Test deg selv

Søk i Skolesaga

Søk etter lærebøker, kapitler, trinn og verktøy

Gratis interaktive lærebøker for norsk skole.

Lærebok
PersonvernVilkår

© 2025 Skolesaga · Alle rettigheter forbeholdt

Deler av innholdet er utviklet med hjelp av AI-verktøy

IT 1Tilbake
6.5 Normalisering og databasedesign
Normalisering og databasedesign

6.5 Normalisering og databasedesign

Alle fag for VG2

Lær prinsippene for god databasedesign gjennom de tre normalformene.

60 min
7 oppgaver
NormaliseringRedundans1NF2NF
Din fremgang i kapitlet
0 / 7 oppgaver

Normalisering og databasedesign

Forestill deg at en skole lagrer all informasjon i én eneste tabell:

elev_idfornavnetternavnklasselaererfagkarakter
1EmmaHansen10AKari NordliMatematikk5
1EmmaHansen10APer HaugenNorsk4
1EmmaHansen10ALise VikNaturfag5
2OliverJohansen10AKari NordliMatematikk3
2OliverJohansen10APer HaugenNorsk4

Ser du problemene? Emmas navn og klasse gjentas for hver karakter. Hvis Emma bytter klasse, må vi oppdatere tre rader. Hva hvis vi glemmer én? Da har vi inkonsistent data. Og hva hvis vi sletter alle karakterene til en elev – forsvinner all informasjon om eleven?
Normalisering er løsningen. Det er en systematisk metode for å organisere databasetabeller slik at de unngår disse problemene. I dette kapittelet skal du lære de tre første normalformene og hvordan du bruker dem til å designe gode databaser.

Unormaliserte tabeller (som den store enkelttabellen over) fører til tre typer problemer kalt anomalier:

1. Oppdateringsanomali


Når data er duplisert og du endrer bare noen forekomster, blir dataene inkonsistente.

Eksempel: Emma Hansen bytter fra 10A til 10B. Informasjonen «10A» finnes i tre rader. Hvis vi bare oppdaterer to av dem, står det 10B i to rader og 10A i én rad – inkonsistens.

2. Innsettingsanomali


Du kan ikke lagre informasjon uten å ha tilhørende data.

Eksempel: Vi ansetter en ny lærer, Jon Hauge, som skal undervise i historie. Men vi kan ikke legge ham inn i tabellen uten å også ha en elev og en karakter, fordi alle kolonnene er i samme tabell.

3. Slettingsanomali


Sletting av data fører til utilsiktet tap av annen informasjon.

Eksempel: Hvis vi sletter alle karakterrader for Liam (den eneste eleven i 10C med naturfagskarakter), mister vi ikke bare karakteren, men potensielt informasjonen om at Lise Vik underviser i naturfag.

Alle tre anomaliene skyldes det samme grunnproblemet: data som logisk hører til forskjellige ting er blandet sammen i én tabell. Normalisering løser dette ved å dele data inn i separate, spesialiserte tabeller.

Normalisering
Normalisering er en steg-for-steg-prosess for å organisere data i en relasjonsdatabase slik at redundans (unødvendig gjentakelse av data) minimeres og dataintegriteten bevares. Normaliseringsprosessen følger en serie regler kalt normalformer (NF). Hver normalform bygger på den forrige og stiller strengere krav til tabellstrukturen. De tre første normalformene (1NF, 2NF og 3NF) er de viktigste og dekker de fleste praktiske behov.

En tabell er i første normalform (1NF) når:

1. Alle kolonner inneholder atomære verdier (udelelige enkelverdier)
2. Det finnes ingen gjentakende grupper eller kolonner
3. Hver rad er unik (tabellen har en primærnøkkel)

Eksempel: Brudd med 1NF

elevidfornavnfag
1EmmaMatematikk, Norsk, Naturfag
2OliverMatematikk, Norsk

Kolonnen fag inneholder flere verdier i én celle – det bryter med 1NF. Hvordan finner du alle elever som tar naturfag? Du kan ikke bruke WHERE fag = 'Naturfag' fordi verdien er «Matematikk, Norsk, Naturfag».

Etter 1NF


elevidfornavnfag
1EmmaMatematikk
1EmmaNorsk
1EmmaNaturfag
2OliverMatematikk
2OliverNorsk

Nå har hver celle bare én verdi, og vi kan enkelt søke:

``sql

SELECT fornavn FROM eleverfag WHERE fag = 'Naturfag';
``

Et annet eksempel: Gjentakende kolonner


elevidfornavnfag1fag2fag3
1EmmaMatematikkNorskNaturfag
2OliverMatematikkNorskNULL

Dette bryter også med 1NF – gjentakende kolonner for fag. Hva hvis en elev tar fire fag? Da må vi legge til en ny kolonne. Løsningen er å dele opp i rader, som vist over.

En tabell er i andre normalform (2NF) når:

1. Den er i 1NF
2. Alle ikke-nøkkelkolonner er fullt funksjonelt avhengige av hele primærnøkkelen

2NF er relevant for tabeller med sammensatte primærnøkler (primærnøkler som består av to eller flere kolonner). Hvis en kolonne bare avhenger av én del av nøkkelen, bør den flyttes til en egen tabell.

Eksempel: Brudd med 2NF

Tenk deg en tabell for kursregistrering med sammensatt primærnøkkel (elevid + fagid):

elevidfagidelevnavnfagnavnkarakter
11EmmaMatematikk5
12EmmaNorsk4
21OliverMatematikk3

Primærnøkkel: (elevid, fagid)
Problem: elevnavn avhenger bare av elevid (ikke av hele nøkkelen). fagnavn avhenger bare av fagid. Bare karakter avhenger av hele nøkkelen (elevid + fagid).

Etter 2NF – del opp i tre tabeller:


elever:

elevidelevnavn
1Emma
2Oliver

fag:

fagidfagnavn
1Matematikk
2Norsk

karakterer:

elevidfagidkarakter
115
124
213

Nå avhenger alle kolonner av hele primærnøkkelen i sin respektive tabell. Elevnavn lagres bare én gang, og fagnavn lagres bare én gang.

En tabell er i tredje normalform (3NF) når:

1. Den er i 2NF
2. Ingen ikke-nøkkelkolonne er avhengig av en annen ikke-nøkkelkolonne (ingen transitive avhengigheter)

Med andre ord: alle ikke-nøkkelkolonner avhenger direkte av primærnøkkelen, ikke indirekte via andre kolonner.

Eksempel: Brudd med 3NF

elevidfornavnetternavnpostnummerpoststed
1EmmaHansen0150Oslo
2OliverJohansen0150Oslo
3NoraOlsen5003Bergen

Problem: poststed avhenger av postnummer, som igjen avhenger av elev
id. Dette er en transitiv avhengighet: elevid → postnummer → poststed. Poststed avhenger ikke direkte av elevid.
Konsekvensen er at «Oslo» lagres to ganger (for postnummer 0150). Hvis postnummer 0150 bytter navn, må vi oppdatere alle rader.

Etter 3NF – skill ut poststeder:


elever:

elev_idfornavnetternavnpostnummer
1EmmaHansen0150
2OliverJohansen0150
3NoraOlsen5003

poststeder:

postnummerpoststed
0150Oslo
5003Bergen

Nå lagres hvert poststed bare én gang, og alle ikke-nøkkelkolonner avhenger direkte av primærnøkkelen i sin respektive tabell.

📜Oppsummering av normalformene
1NF – Atomære verdier: Alle kolonner inneholder bare enkelverdier, ikke lister eller grupper. Hver rad er unik.

2NF – Full funksjonell avhengighet: Alle ikke-nøkkelkolonner avhenger av hele primærnøkkelen, ikke bare en del av den. (Relevant ved sammensatte primærnøkler.)

3NF – Ingen transitive avhengigheter: Alle ikke-nøkkelkolonner avhenger direkte av primærnøkkelen, ikke av andre ikke-nøkkelkolonner.

Huskeregel: «Nøkkelen, hele nøkkelen, og ingenting annet enn nøkkelen.»
- 1NF: Dataene har en nøkkel (primærnøkkel, atomære verdier)
- 2NF: Avhenger av hele nøkkelen (ikke deler av sammensatt nøkkel)
- 3NF: Ingenting annet enn nøkkelen (ingen transitive avhengigheter)

✏️Eksempel: Fullstendig normalisering av en bibliotekdatabase
Utgangspunkt: Unormalisert tabell

utlaanidelevnavnklasseboktittelforfatterisbnutdatoinndato
1Emma Hansen10ASofies verdenJostein Gaarder978-82-03-192024-09-012024-09-15
2Emma Hansen10ABeatlesLars S. Christensen978-82-02-252024-09-10NULL
3Oliver Johansen10ASofies verdenJostein Gaarder978-82-03-192024-09-052024-09-20

Problemer:
- Emmas navn og klasse gjentas (redundans)
- «Sofies verden» med forfatter og ISBN gjentas (redundans)
- elevnavn er ikke atomært (fornavn + etternavn i én kolonne) → bryter 1NF

Steg 1: 1NF – atomære verdier
Del elevnavn i fornavn og etternavn. Fjern gjentakende data.
Steg 2: 2NF og 3NF – fjern partielle og transitive avhengigheter
``sql

CREATE TABLE elever (
elevid INTEGER PRIMARY KEY AUTOINCREMENT,

fornavn TEXT NOT NULL,

etternavn TEXT NOT NULL,
klasse TEXT
);
CREATE TABLE boker (
bokid INTEGER PRIMARY KEY AUTOINCREMENT,
tittel TEXT NOT NULL,
forfatter TEXT,

isbn TEXT UNIQUE
);
CREATE TABLE utlaan (
utlaan
id INTEGER PRIMARY KEY AUTOINCREMENT,
elevid INTEGER NOT NULL,
bok
id INTEGER NOT NULL,

utlaansdato DATE NOT NULL,
innleverings
dato DATE,
FOREIGN KEY (elevid) REFERENCES elever(elevid),
FOREIGN KEY (bokid) REFERENCES boker(bokid)
);
-- Sett inn data
INSERT INTO elever (fornavn, etternavn, klasse) VALUES
('Emma', 'Hansen', '10A'),
('Oliver', 'Johansen', '10A');

INSERT INTO boker (tittel, forfatter, isbn) VALUES
('Sofies verden', 'Jostein Gaarder', '978-82-03-19'),
('Beatles', 'Lars S. Christensen', '978-82-02-25');
INSERT INTO utlaan (elevid, bokid, utlaansdato, innleveringsdato) VALUES

(1, 1, '2024-09-01', '2024-09-15'),
(1, 2, '2024-09-10', NULL),
(2, 1, '2024-09-05', '2024-09-20');

``
Nå er data normalisert: elevinformasjon lagres bare én gang, bokinformasjon lagres bare én gang, og utlånstabellen kobler dem sammen.

Normalisering er generelt en god praksis, men det finnes situasjoner der man bevisst velger å denormalisere – altså tillate noe redundans:

Ytelseshensyn


Normaliserte databaser krever mange JOIN-operasjoner for å sette sammen data fra flere tabeller. I systemer med ekstremt mange spørringer (som sosiale medier med millioner av brukere) kan dette bli en flaskehals. Da kan man bevisst duplisere noe data for å unngå dyre JOIN-operasjoner.

Rapportering og analyse


For rapporterings-databaser (datawarehouses) er det vanlig å bruke «flate» tabeller med noe redundans, fordi det gjør spørringene enklere og raskere.

Enkle systemer


For svært enkle systemer med lite data kan full normalisering gjøre ting unødvendig komplisert.

Hovedregelen er: Start alltid med normalisering. Denormaliser bare hvis du har dokumenterte ytelsesproblemer som ikke kan løses på andre måter. Det er mye lettere å denormalisere en normalisert database enn å normalisere en rotete en.

Når du skal designe en database fra bunnen av, følg denne prosessen:

1. Forstå kravene – Hva skal systemet gjøre? Hvilke data trengs?
2. Identifiser entiteter – Hva er «tingene» vi lagrer? (Elever, bøker, bestillinger...)
3. Definer attributter – Hvilke egenskaper har hver entitet?
4. Finn relasjoner – Hvordan henger entitetene sammen?
5. Tegn ER-diagram – Visualiser strukturen
6. Normaliser – Sjekk 1NF, 2NF, 3NF og juster tabellene
7. Skriv SQL – Opprett tabellene med CREATE TABLE
8. Test med data – Sett inn testdata og kjør spørringer
9. Iterer – Juster designet basert på reelle behov

God databasedesign er en ferdighet som utvikles med praksis. Jo flere databaser du designer, jo bedre intuisjon utvikler du for hva som fungerer og hva som ikke fungerer.

Vanlige normaliseringsfeil

Pass deg for disse vanlige feilene:

1. Kommaseparerte lister i kolonner: fag = "Matte, Norsk, Naturfag" bryter med 1NF. Bruk en koblingstabell.
2. Gjentakende kolonner: telefon1, telefon2, telefon3 bryter med 1NF. Lag en egen tabell for telefonnumre.
3. Beregnede verdier lagret i tabellen: Ikke lagre alder hvis du har fodselsdato. Beregn det med SQL i stedet.
4. Miks av ulike entiteter: Ikke legg elevinfo og faginfo i samme tabell bare fordi de brukes sammen.
5. For mye normalisering: Det finnes tilfeller der det er greit å lagre noe «ekstra» data for å forenkle spørringer.

📝Oppgave 6.5.1

Hva er normalisering i databasesammenheng?

📝Oppgave 6.5.2

Denne tabellen bryter med første normalform (1NF). Hvorfor?

elev_idfornavnhobbyer
1EmmaFotball, Lesing, Sjakk
2OliverGaming, Fotball

📝Oppgave 6.5.3

Hvilken type anomali oppstår i dette scenariet?

Du har en tabell der elevnavn og klasse lagres sammen med karakterer. Emma Hansen er i klasse 10A og har tre karakterrader. Du oppdaterer klassen til 10B i to av radene, men glemmer den tredje.

📝Oppgave 6.5.4

Denne tabellen er unormalisert. Identifiser hvilke normalformer den bryter med, og vis hvordan du normaliserer den til 3NF.

bestillingidkundenavnkundeepostproduktprisantalltotalpris
1Emma Hansenemma@mail.noUSB-kabel792158
2Emma Hansenemma@mail.noMus2991299
3Oliver Johansenoliver@mail.noUSB-kabel793237

📝Oppgave 6.5.5

Hvilken normalform bryter denne tabellen med?

ansattidnavnavdelingavdelingsleder
1Kari NordliMatematikkPer Haugen
2Lise VikNaturfagTom Bakke
3Jon HaugeMatematikkPer Haugen

Primærnøkkel: ansattid. Avdelingsleder avhenger av avdeling (ikke direkte av ansatt_id).

📝Oppgave 6.5.6

Design en fullstendig normalisert database (3NF) for et treningssenter. Systemet skal håndtere:

- Medlemmer (navn, telefon, e-post, medlemstype)
- Treningsklasser (navn, beskrivelse, varighet, instruktør)
- Påmeldinger til klasser (medlem, klasse, dato, tidspunkt)
- Instruktører (navn, spesialisering, telefon)

Tegn eller beskriv tabellene med kolonner, primærnøkler, fremmednøkler og relasjonstyper. Skriv deretter CREATE TABLE-kode for alle tabellene.

📝Oppgave 6.5.7

Hva er huskeregelen for de tre første normalformene?