Mange-til-mange relasjonar.

Biblioteksdatabasen i forrige eksempel funkar til sitt (dvs. veldig enkle) bruk, men det skal ikkje mykje kompleksitet til før det skjer seg. For eksempel: Våre venner Jarle Rasmussen og Jon Severud skreiv for noken år sidan boka Shit happens (om meningen med livet) saman. Då bryt modellen vår også saman. Husk datamodellen som vi hadde:

Datamodell, enkel biblioteksdatabase

Kva er så problemet? Jau, vi har ein kolonne i bok-tabelen som heiter forfattarnr, som refererer til FNR i forfattar-tabellen. Dette er fremmednøkkelen som gir oss relasjonen mellom bok og forfattar. Her fører vi opp nummeret til den riktige forfattaren. Boka "To henrettelser" av "Jarle Rasmussen" fekk dermed forfattarnr = 1, fordi Jarle har FNR = 1. Men når boka er skriven av to forfattarar så får vi problem fordi vi har ikkje lov til å ha fleire verdiar i "forfattarnr"-kolonnen. Vi kan heller ikkje laga ein rad til i bok-tabellen for same bok, fordi vi då hadde fått samme BNR, dvs duplikat-nøkkel. Og det har vi heller ikkje lov til. Vi kunne tenkt oss å oppretta mange kolonner i bok-tabellen: forfattarnr1, forfattarnr2 osv. Men vi veit jo ikkje kor mange forfattarar som ein kan risikera å ha på ei bok. I teorien er det ubegrensa!

Løysinga

Vi er altså nødt til å laga ein annan struktur på databasen vår.  Løysinga blir då å laga tre tabellar: dei to vi hadde, nemlig forfattar og bok, pluss ein tabell i mellom som skal halda rede på kven som har skrive kva bok. Dette er ein såkalt koblingstabell, og denne vi ha med for å kunna realisera ein mange-til-mange relasjon. Eg har kalla den "forfattarskap". Datamodellen vår ser altså slik ut:

mange til mange relasjon

Den nye tabellen inneheld bare to kolonner: "forfattar_FNR" og "bok_NBR". Som navna seier, så refererer den første til FNR i forfattar-tabellen, og den andre til BNR i bok tabellen. Begge er altså fremmednøklar. Men det ser ut til at koblingstabellen vår manglar ein nøkkel? Det er bare tilsynelatande, fordi disse to kolonnene er tilsaman ein nøkkel. Ei rad i forfattarskap-tabellen er eintydig identifisert ved FNR + BRN (forfattar + bok) Så dette er det som blir kalla ein  samansett primærnøkkel. Men NB: Vi kunne ha laga ein egen nøkkel for forfattarskap-tabellen, feks ein ID. I så fall hadde FNR og BNR blitt vanlige fremmednøklar. Men med eit lite forbehold, (Valget vårt får konsekvenser, som vi skal sjå nedanfor.) så treng vi ikkje. Vi merkjer oss også at bok-tabellen er endra fordi vi ikkje treng nokon fremmednøkkel der, så her står vi igjen med BNR og Tittel.

Eksempeldata

For å forstå korleis dette virkar i praksis er det ofte lurt å kikka på eksempeldata. Forfattar-tabellen er uendra, men bok-tabellen har fått ei kolonne mindre (fordi vi ikkje trengte FNR der, men ei ny rad til den nye boka)

FNR Fnavn Enavn Diverse info
1 Jarle Rasmussen forfattar, lærar og prest
2 Jon Severud skriv om underklassen
3 Gunnar Øyro artig, men lite produktiv
4 Albert Camus fransk forfattar og filosof

BNR tittel
1 To henrettelser
2 Alt flyter
3 Ubehaget i skolen
4 Ei Gjenreise
5 Fandens ordbok
6 Enûma Elis
7 Shit happens

Koblingstabellen må då sjå slik ut:

forfattar_FNR bok_BNR
1 1
1 2
2 3
2 4
3 5
1 7
2 7


Så kan vi laga ei spørring mot disse tabellane vha. to JOINS på denne måten:


SELECT bok.tittel, forfattar.Fnavn, forfattar.Enavn
FROM forfattar
JOIN forfattarskap
ON forfattar.FNR = forfattarskap.forfattar_FNR
join bok
on bok.BNR = forfattarskap.bok_BNR
order by tittel;

Resultatet av denne spørringen blir:

tittel			Fnavn	 Enavn
Alt flyter Jarle Rasmussen
Ei Gjenreise Jon Severud
Fandens ordbok Gunnar Øyro
Shit happens Jarle Rasmussen
Shit happens Jon Severud
To henrettelser Jarle Rasmussen Ubehaget i skolen Jon Severud

Her får vi ut sju rader som tilsvarer dei sju radene i forfattarskap, men erstatta med data som er henta frå "forfattar" og "bok". Merk at data her er sortert etter tittel. Vi får ut to rader for vår nye bok Shit happens. Å få dette ut på ei linje er nok mulig, men ikkje noke vi skal gå gjennom her.

Den oppmerksomme lesar (som har lest om Joins) vil kanskje innvenda: "men kva med boka Enûma Elis?" Dette er ei bok som ikkje har (registrert) forfattar. Den fins derfor ikkje i forfattarskap-tabellen. Vi kunne tenkt oss å leggja inn ei rad der med forfattar_FNR = NULL. Men sidan denne kolonnen er ein del av nøkkelen, så har vi ikkje lov til å leggja inn NULL-verdiar der. Tilsvarande kan vi heller ikkje leggja inn forfattarar uten bøker i denne tabellen. Og det er altså prisen vi må betala når vi har valgt å ha ein samansett nøkkel. (ref det vi sa ovenfor). Dermed er det ingen vits i å prøva med hverken LEFT- eller RIGHT JOIN her. Men det er nok også her mulig å få ut  Enûma Elis, men det må gjerast på andre måtar.