Relasjonsmodellen
Den formelle modellen bak SQL: tabeller med skjema, tupler over domener, og nøkler som binder alt sammen.
Codd 1970 — én datatype, én operasjonsfamilie
Før 1970 var data lagret i hierarkiske og nettverkbaserte modeller, der applikasjonen måtte kjenne den fysiske layouten — pekere, lister, tre-traverseringer. Bytter man indeks eller filformat, må alle programmer skrives om.
Edgar F. Codd publiserte i 1970 artikkelen «A Relational Model of Data for Large Shared Data Banks» hos IBM. Innsikten var radikalt enkel:
All data er bare tabeller. Spørringer er funksjoner som tar tabeller inn og gir tabeller ut. Brukeren beskriver hva som skal hentes — systemet finner ut hvordan.
Det er denne deklarative tankegangen som gjør at SQL kan optimaliseres, indekser kan endres, og maskinvare kan byttes ut — uten at applikasjonen merker noe. Codd fikk Turing-prisen for arbeidet.
SQL er den deklarative overflaten. Relasjonsalgebra (kapittel 2B) er det formelle fundamentet — det er det optimalisatoren faktisk manipulerer når den planlegger en spørring.
Tabell, attributt, tuppel, domene
En relasjon er en tabell. Hver kolonne er et attributt med et tilhørende domene (mengden av lovlige verdier). Hver rad er et tuppel.
| ID | name | dept_name | salary |
|---|---|---|---|
| 10101 | Srinivasan | Comp. Sci. | 65 000 |
| 22222 | Einstein | Physics | 95 000 |
| 33456 | Gold | Physics | 87 000 |
| 76766 | Crick | Biology | 72 000 |
instructor med 4 attributter og 4 tupler. ID (markert) er primærnøkkel.Atomiske domener (1. normalform)
Codd krevde at alle attributtverdier er atomiske — de betraktes som udelelige enheter. Det er ikke lov å lagre {555-1234, 555-9999} som én verdi i kolonnen phone. Lister, sett, og nestede strukturer skal flates ut til egne tabeller. Dette er kjernen i 1. normalform (1NF).
Hvis verdier kan være sammensatte, mister du muligheten til å skrive enkle predikater (WHERE phone = '555-1234') og må i stedet manipulere indre struktur — akkurat det Codd ville unngå.
Egenskapene som følger av at relasjoner er mengder
- Ingen duplikater — to identiske rader er per definisjon én rad.
- Ingen rekkefølge — du kan ikke spørre etter «den tredje raden».
- Ingen kolonnerekkefølge i ren teori — i praksis har SQL en, men spørringer bør referere til kolonner ved navn.
SQL bruker multimengder (bags) — duplikater er tillatt med mindre du sier DISTINCT. Det er en praktisk avvik fra Codds rene mengdedefinisjon, men semantikken må du være våken på.
tags som en kommaseparert streng "matte,db,vår26". Hvorfor bryter dette med relasjonsmodellen, og hva er den vanlige løsningen?article_tag(article_id, tag) — én rad per kombinasjon.Strukturen er stabil — innholdet er ikke
instructor(ID, name, dept_name, salary). Endres sjelden. Tilsvarer en typedefinisjon i et programmeringsspråk.INSERT, UPDATE, DELETE. Tilsvarer en verdi av en variabel.Ofte bruker vi samme navn — «instructor» — for både skjema og instans, og lar konteksten avgjøre. Når det er viktig, sier vi eksplisitt «instructor-skjemaet» eller «en instans av instructor».
Notasjon
Et relasjonsskjema skrives R(A1, A2, …, An), der Ai er attributter. Et tuppel t ∈ R har én verdi per attributt. t[Ai] er verdien til attributt Ai i tuplet t.
instructor, og ikke en del av en bestemt instans?ID, name, dept_name, salary), domener (heltall, tekst, tekst, kroner) og constraints (ID er primærnøkkel) er skjema. Konkrete tupler — at Einstein finnes med ID 22222 — er instans.Hva som identifiserer en rad
Vi må kunne skille tupler. Nøkler formaliserer hvilke attributtkombinasjoner som er garantert unike.
Supernøkkel
En mengde attributter K ⊆ R er en supernøkkel hvis ingen to tupler i noen lovlig instans kan ha samme verdi på alle attributter i K. Formelt: for alle t1 ≠ t2, t1[K] ≠ t2[K].
I instructor(ID, name, dept_name, salary) er {ID} en supernøkkel. Det er {ID, name} også — alle supersett av en supernøkkel er supernøkler. Men {name} alene er ikke, fordi to professorer kan hete det samme.
Kandidatnøkkel
En minimal supernøkkel: ingen ekte delmengde av den er supernøkkel. Hvis {ID} er supernøkkel, er {ID, name} ikke kandidat — du kan fjerne name og fortsatt ha unikhet.
En relasjon kan ha flere kandidatnøkler. person(ssn, fødselsdato, navn, …) kan ha både {ssn} og — hvis det er garantert — {fødselsdato, navn} som kandidater.
Primærnøkkel
Den kandidatnøkkelen designeren velger som primær identifikator. Markeres med understreking i skjema: instructor(ID, name, dept_name, salary). Bør være kort, stabil (sjelden endring), og helst syntetisk (autoincrement, UUID).
Adresse er en dårlig primærnøkkel — den endrer seg når folk flytter. Personnummer fungerer i Norge (stabilt), men er sensitivt og finnes ikke alltid. I praksis lager man oftest en syntetisk id-kolonne.
Visualisering — supernøkkel ⊃ kandidat ⊃ primær
section(course_id, sec_id, semester, year, building, room, time_slot): hvorfor er ikke {course_id} alene en kandidatnøkkel?{course_id, sec_id, semester, year} for å garantere unikhet.name. Kan vi konkludere med at name er en supernøkkel?Pekere mellom tabeller
En fremmednøkkel er en attributtmengde A i relasjon r1 som refererer til primærnøkkelen B i relasjon r2. Krav: for hvert tuppel i r1 må verdien av A finnes som verdi av B i r2 — eller være NULL.
| dept_name | building | budget |
|---|---|---|
| Comp. Sci. | Taylor | 100 000 |
| Physics | Watson | 70 000 |
| Biology | Watson | 90 000 |
| ID | name | dept_name | salary |
|---|---|---|---|
| 10101 | Srinivasan | Comp. Sci. | 65 000 |
| 22222 | Einstein | Physics | 95 000 |
| 33456 | Gold | Physics | 87 000 |
Fremmednøkkel: instructor.dept_name → department.dept_name
Skjemadiagram
Et skjemadiagram tegner relasjoner som bokser, primærnøkler understreket, og fremmednøkler som piler.
Referanseintegritet og hva som skjer ved sletting
Når du sletter et tuppel i den refererte tabellen (department), må DBMS-en bestemme hva som skal skje med tupler som peker til det. Standardalternativene i SQL:
- RESTRICT (eller NO ACTION) — slett blokkeres. Standard i mange DBMS.
- CASCADE — referanser slettes med. Brukes ofte ved komposisjon (en ordrelinje gir ikke mening uten ordren).
- SET NULL — fremmednøkkelen settes til NULL. Krever at kolonnen ikke er
NOT NULL. - SET DEFAULT — settes til default-verdi (sjeldnere brukt).
Fremmednøkkel-constraints er et spesialtilfelle av referanseintegritets-constraints, der det refererte attributtet må være primærnøkkel. Den generelle varianten (henvist attributt trenger ikke være primærnøkkel) støttes sjelden direkte av kommersielle DBMS.
orders(order_id, customer_id, …) og order_lines(order_id, line_no, product, …) hvor order_lines.order_id refererer til orders.order_id. Hvilken delete-strategi er mest naturlig her?Hva DBMS-en garanterer
Integritetskrav er regler som alle instanser må oppfylle. De er en del av skjemaet, og DBMS-en håndhever dem ved hver oppdatering.
salary INT, email LIKE '%@%', CHECK(salary >= 0)).UNIQUE garanterer at kandidatnøkler faktisk er unike på tvers av instansen.start_date < end_date, discount <= price). Uttrykkes via CHECK, TRIGGER eller assertions.Når «ukjent» roter alt til
NULL er en spesialverdi som betyr «ukjent» eller «ikke aktuelt». Den hører ikke til noe domene, og oppfører seg derfor unormalt i sammenligninger.
Sammenligning med NULL gir ikke FALSE — den gir UNKNOWN
Predikatet salary > 50000 evaluerer til UNKNOWN hvis salary IS NULL. Det er heller ikke TRUE og ikke FALSE — det er en tredje sannhetsverdi. Derfor får SQL en treverdig logikk.
| T | F | U | |
|---|---|---|---|
| T | T | F | U |
| F | F | F | F |
| U | U | F | U |
| T | F | U | |
|---|---|---|---|
| T | T | T | T |
| F | T | F | U |
| U | T | U | U |
WHERE filtrerer bort UNKNOWN
SQL beholder bare rader der WHERE-predikatet er TRUE. UNKNOWN behandles som FALSE i dette filteret. Derfor er resultatet av SELECT * FROM emp WHERE bonus > 0 ikke komplementært til SELECT * FROM emp WHERE bonus <= 0 — rader med bonus = NULL mangler i begge.
x = NULL er alltid UNKNOWN — også når x selv er NULL. Bruk derfor alltid x IS NULL / x IS NOT NULL for å teste for fravær.
Konsekvenser i praksis
- Aggregater hopper over NULL —
AVG(salary)teller bare ikke-NULL rader. Unntak:COUNT(*)teller alle rader. - NOT IN ⟵⟶ NULL —
x NOT IN (1, 2, NULL)blir UNKNOWN selv nårx = 3. Klassisk kilde til «manglende rader». - UNIQUE-constraint tillater normalt flere NULL-verdier (de regnes ikke som «like»).
emp(name, dept) har 5 rader; én har dept = NULL. Hva returnerer SELECT name FROM emp WHERE dept <> 'HR'?NULL <> 'HR' er UNKNOWN, og UNKNOWN filtreres bort. Vil du ha NULL med, må du skrive WHERE dept IS NULL OR dept <> 'HR'.employee_phone-tabell heller enn nullbar phone. NULL er likevel uunngåelig for ekte valgfri informasjon (utløpsdato før den er satt, partneradresse i CV-er, osv.).Du bør nå kunne …
- … forklare hvorfor relasjonsmodellen vant fram (deklarativ tilgang, separasjon av logisk og fysisk lag).
- … definere relasjon, tuppel, attributt, domene, og hvorfor atomiske domener er viktig.
- … skille skjema fra instans.
- … identifisere supernøkler, kandidatnøkler og primærnøkler i et gitt skjema.
- … tegne et skjemadiagram med fremmednøkler og argumentere for delete-strategi.
- … forklare entitets- og referanseintegritet.
- … resonnere om NULL og treverdig logikk.
Med modellen på plass kan vi nå snakke om operasjoner på relasjoner — det formelle språket SQL bygger på. Gå videre til 2B · Relasjonsalgebra.