Hva slags relasjoner finnes i databasen?

En relasjonsdatabase er altså et slags nettverk av entiteter og attributter. Som vi så i eksempelet med kundelisten, kan det spare oss fra å føre inn den samme informasjonen mange ganger. I stedet fører vi det kun ett sted. Så kan vi heller definere relasjoner mellom ulike oppføringer.
Når vi definerer slike relasjoner, er det spesielt to ting vi må tenke på: nemlig det som kalles «kardinalitet» og «medlemskap».
Kardinaliteten er sammenhengen i relasjonen mellom entitetene. Medlemskapet handler om hvorvidt en relasjon må finnes eller ikke. Sånn, nå har du skjønt det!
Nei, da – vi skjønner at dette ikke er selvforklarende. Så la oss dykke ned i det. Vi starter med kardinalitet.

Kardinalitet

Det finnes tre former for kardinalitet i en relasjonsdatabase: En-til-en, en-til-mange og mange-til-mange. Vi tar det i tur og orden:

En-til-en

En en-til-en-relasjon indikerer at en instans (datarad) av en entitet har én – og bare én! – relasjon til en instans av en annen entitet. For eksempel:
  • Et land har en hovedstad; en hovedstad tilhører et land
  • En statsborger har et pass; et pass tilhører en statsborger
Mennesker kan ha flere statsborgerskap, men innenfor det ene landet har de bare ett pass – og motsatt, bare ett pass tilhører det ene mennesket.
Likevel: Mennesker får nye pass med noen års mellomrom, og det er historiske eksempler på land som har skiftet hovedstad. Så vi ser, med tanke på historiske data, at er nødvendig å skille entitetene.
Illustrasjonen viser eksemplene. Ordene («har», «tilhører») er der bare for å gjøre relasjonen lesbar og logisk for oss mennesker – de finnes ikke i selve databasen. De horisontale linjene mellom entitetene viser relasjonen, som opprettes i databasen. De vertikale linjene som krysser relasjonslinjen tett på entitetene, forteller databasen at relasjonen er en-til-en; at et land bare kan ha en hovedstad og en statsborger bare kan ha et pass til en hver tid.
Land, Hovedstad
Statsborger, Pass

En-til-mange

I en-til-mange relasjoner indikeres det at en instans av en entitet kan ha en relasjon til mange instanser av en annen entitet. For eksempel:
  • En person eier mange bøker; mange bøker tilhører en person
  • En resirkuleringsstasjon inneholder mange resirkuleringspunkter (som glass og metall, papir og papp, plast, kompost, rest); mange resirkuleringspunkter står på en resirkuleringsstasjon
Den siden det bare er én av (til venstre i figuren), er lik som i en-til-en-relasjoner. Den andre siden, der mange instanser kan inngå, vises med tre linjer – det som kalles «kråketær»:
Person, Bok
Resirkstasjon, Resirkpunkt

Mange-til-mange

Den siste kardinaliteten det er mange-til-mange-relasjoner. Mange-til-mange-relasjoner indikerer at mange instanser av en entitet kan ha relasjoner til mange instanser av en annen entitet. For eksempel:
  • Mange kunder kjøper mange produkter; mange produkter kjøpes av mange kunder
  • Mange forbrukere bruker mange resirkuleringspunkter; mange resirkuleringspunkter brukes av mange forbrukere
I en dagligvarebutikk er det hver dag mange kunder som kjøper melk, og mange kartonger av melk blir kjøpt av mange kunder. Det samme med brød, kaffe og alle de andre tingene vi trenger.
Vi illustrerer mange-til-mange relasjoner med kråketær i begge ender av relasjonen:
Kunde, Produkt
Forbruker, Resirkpunkt
Ved å anvende flertallsform kan vi forenkle lesingen av relasjonene uten å bruke ordet «mange»:
Kunder kjøper produkter, produkter kjøpes av kunder. Forbrukere bruker resirkuleringspunkter, resirkuleringspunkter brukes av kunder.
Henger du med? Dette var altså kardinalitet, eller sammenhengen i relasjonen mellom entitetene. La oss nå se på det andre viktige momentet i en relasjon, nemlig medlemskap.

Medlemskap

Medlemskap tilfører informasjon til kardinaliteten, og finnes i to gjensidig utelukkende varianter:
  • Obligatorisk medlemskap
  • Ikke-obligatorisk medlemskap
Her må vi også dykke litt mer ned for å forstå hva dette faktisk betyr:

Medlemskap i en-til-en relasjoner

Vi kan utvide kardinaliteten i en-til-en-relasjonene med medlemskap. For eksempel:
  • Ett og bare ett land har en hovedstad; én og bare én hovedstad tilhører ett land
  • En og bare en statsborger har et pass; ett eller null pass tilhører en statsborger
Ser du forskjellen fra tidligere? Medlemskap handler altså om hvorvidt en relasjon må finnes eller ikke.
Den første relasjonen i dette eksempelet har obligatorisk medlemskap. Alle land har hovedsteder, og alle hovedsteder tilhører et land. Denne relasjonen må altså finnes. Vi kan ikke ha et land som ikke har en hovedstad, og det eksisterer ikke en hovedstad som ikke tilhører et land.
Et obligatorisk medlemskap mellom entiteter i en relasjonsdatabase betyr at man ikke lovlig kan lagre en instans av en av entitetene uten at den har en relasjon til en instans i den andre entiteten. I dette eksempelet vil det bety at man ikke kan lagre et land i databasen uten en tilhørende hovedstad, ei heller lagre en by som en hovedstad uten at den har en relasjon til et land.
Den andre relasjonen er imidlertid ikke obligatorisk. Et menneske er en statsborger av et land, men det mennesket trenger ikke ha et pass.
Ikke-obligatoriske medlemskap forteller relasjonsdatabasen at det kan finnes relasjoner mellom instanser i entitetene, men at instanser kan lagres uten at denne relasjonen finnes for den enkelte instans – som at en statsborger kan være registrert uten at statsborgeren må ha et pass.
Vi kan illustrere dette med streker og sirkler på relasjonslinjen, utenfor linjen som indikerer relasjonens kardinalitet. Tenk på det som 1 og 0, som viser om relasjonen henholdsvis er obligatorisk eller ikke:
Land, Hovedstad
Statsborger, Pass
Vi leser: Ett og bare ett land har en og bare en hovedstad, en og bare en hovedstad tilhører ett og bare ett land. Én og bare én statsborger har null eller ett pass, ett eller null pass tilhører en og bare en statsborger.
Legg merke til nyansen i at et pass ikke kan finnes i denne databasen uten at det tilhører en statsborger.
I enkelte databaser – for eksempel relatert til logistikk og produksjon av blanke pass – kunne dette vært hensiktsmessig. Ved å legge null til medlemskapet ved statsborger entiteten i relasjonen, ville databasen kunne lagre pass som tilhører null eller en statsborger.

Medlemskap i en-til-mange-relasjoner

I neste omgang kan vi utvide kardinaliteten i en-til-mange-relasjonene med medlemskap.
  • Én og bare én person eier 0, 1 eller mange bøker; 0, 1 eller mange bøker tilhører en og bare en person
  • Én og bare én resirkuleringsstasjon inneholder ett eller mange resirkuleringspunkt, ett eller mange resirkuleringspunkt står på én og bare én resirkuleringsstasjon
Det første eksempelet er ikke-obligatorisk. Personer som finnes i databasen kan, men trenger ikke, eie en eller flere bøker. Det viser vi med null ved siden av kråketærne på mange-siden av relasjonen.
Med resirkuleringsstasjonene blir det litt annerledes. Logisk sett gir det lite mening å si at vi har en resirkuleringsstasjon uten noen returpunkter. I en relasjonsdatabase som lister opp resirkuleringsstasjoner på et sted, bør det ikke være mulig å registrere stasjoner der ingen kan levere noen form for avfall eller resirkulert materiale.
Dermed legger vi en strek til på mange-siden og sier at det kan finnes mange, og må finnes minst ett, resirkuleringspunkt hvis en resirkuleringsstasjon skal lagres i databasen. Vi gjør det tilsvarende på én-siden, og sier dermed at databasen ikke godtar lagring av resirkuleringspunkter som ikke står på en resirkuleringsstasjon.
Person, Bok
Resirkstasjon, Resirkpunkt
Vi leser: Én og bare én person eier null, én, eller mange bøker; mange, én, eller null bøker eies av én og bare én person. Én og bare én resirkuleringsstasjon inneholder ett eller mange resirkuleringspunkt, mange eller ett resirkuleringspunkt står på én og bare én resirkuleringsstasjon.
Som i eksempelet med statsborgere og pass ovenfor, gjør vi i det siste eksempelet antakelser – i dette tilfellet at vi ikke kan ha en stasjon uten punkter, og at punkter ikke kan finnes hvis de ikke står på en stasjon.
Slike regler kaller vi databasesemantikk.
Det finnes ikke formelle regler for hvordan slike regler opprettes, de er basert på logikken av hva databasen skal brukes til, og defineres av oss mennesker når databasemodelleringen starter.
Hvis vi i vårt eksempel forestiller oss at databasen er laget av en organisasjon med formål om å tilgjengeliggjøre praktisk informasjon om hvor befolkningen i et område kan levere hvilke typer avfall, gir våre avgrensninger mening. Denne organisasjonen har ikke umiddelbar nytte av å kjenne til punkter ingen kan anvende, eller områder der stasjoner kunne ha vært, hvis det ikke står noen punkter der.
For en tenkt renovasjonsbedrift, derimot, kunne det helt sikkert med hell vært av interesse å vite om både punkter som står på lager så vel som kvalifiserte områder der stasjoner kunne opprettes i fremtiden, noe som ville endret medlemskapet til ikke-obligatorisk i databasen.

Medlemskap i mange-til-mange-relasjoner

Går vi videre til mange-til-mange-relasjonene, ser vi at det samme gjentar seg der. Medlemskap fungerer altså på samme måte uavhengig av om kardinaliteten er en-til-en, en-til-mange eller mange-til-mange.
  • 0, 1 eller mange kunder kjøper 1 eller mange produkter; 1 eller mange produkter blir kjøpt av 0, 1 eller mange kunder
  • 0, 1 eller mange forbrukere bruker 0, 1 eller mange resirkuleringspunkter; 0, 1 eller mange resirkuleringspunkter brukes av 0, 1 eller mange forbrukere
Det kan finnes mange instanser av produkter i butikken som mange instanser av kunder kjøper i løpet av en dag, men det betyr ikke at alle kunder som går inn i butikken må kjøpe det produktet.
Det er ikke alle produkter som det blir solgt instanser av hver dag, men produktene må finnes for at kunde instansene skal kunne velge dem.
Tilsvarende kan vi se på resirkuleringspunktene våre. Mange forbrukere bruker mange resirkuleringspunkt og mange resirkuleringspunkt brukes av mange forbrukere, men det er ikke sånn at alle forbrukere må bruke resirkuleringspunktene, eller at alle resirkuleringspunktene må brukes av alle, eller noen av, kundene.
Dermed har vi disse nullene på kråketærne på hver side av kardinaliteten i denne relasjonen.
Kunde, Produkt
Forbruker, Resirkpunkt
Vi leser: Mange kunder kjøper ett eller mange produkt; mange produkt kjøpes av null, en, eller mange kunder. Mange forbrukere bruker null, ett, eller mange resirkuleringspunkt; mange resirkuleringspunkt brukes av null, en, eller mange forbrukere.
Igjen ser vi databasesemantiske valg, som at en kunde kjøpe et produkt. Vi skal ikke gå nærmere inn dette, men en god måte å starte utformingen av databasesemantikk er å skrive i egne ord hva databasen skal kunne vise, og dermed hva den må kunne lagre. Dette arbeidet bør starte tidlig i modelleringsprosessen.

Innsikt

Databaser og kode

Nå har du lært mye om logikken i databaser, men la oss være ærlige: Vi har gått litt rundt grøten. I en ekte database er det jo ikke egentlig noen kråketær eller bokser som vi trekker linjer mellom. I stedet er det rader og kolonner med data … og det er SQL.
SQL, eller Structured Query Language, er din beste venn når du jobber med relasjonsdatabaser i praksis. Da jobber vi i en bestemt programvare for formålet – et databasehåndteringssystem. Her kan vi sortere, utforske og for eksempel gi andre apper mulighet til å søke og hente ut data fra databasen.
For å gjøre dette, skriver vi inn kommandoer med SQL-språket. Dette er et såkalt spørrespråk, en variant av programmeringsspråk, som er laget spesifikt for å brukes med relasjonsdatabaser.
Det er ved å skrive instruksjoner i SQL at vi for eksempel henter ut eller oppdaterer oppføringer i databasen.
Kommandoene vi skriver er langt på vei helt vanlig engelsk – bare at vi så og si har byttet ut normal engelsk grammatikk med SQL sin grammatikk.
Det vi skriver inn, er kommandoer som for eksempel «Select» (for å hente ut data), «Update» (for å oppdatere data), «Delete» (for å slette data) og «Insert into» (for å legge til data) – sammen med de konkrete entitetene og attributtene vi vil velge, oppdatere, slette eller endre.
Det kan for eksempel se sånn ut: «SELECT Fornavn, Etternavn FROM Kunde;». Så vil vi som et resultat få en liste med fornavn og etternavn (attributter) fra kunde-entiteten. Kommandoene er som et spørsmål, som gir en respons. Det er derfor dette kalles «spørringer».
Vi skal ikke gå videre inn på SQL her, men da vet du hvordan dette reelt sett går for seg. For vår del er vi ikke helt ferdig med kråketærne helt ennå …