Dette er forslag til oppgavene i "Datamodellering - tips og oppgaver".
I alle oppgavene er det som regel fritt fram til å finna på meir eller mindre gode navn til entitetar (tabellar) og attributter (kolonner). Det er ofte også litt slingringsmonn med datatypane. For eksempel kan ein diskutera om eit telefonnr skal vera tall eller tekst. Noken gonger vil vi ha med "+" når vi tar med landkoden i nummeret, og då kan det funka med tekst. Også verdt å sei at alle oppgavene nok kan gjerast meir detaljerte. Men det er også mulig å tenkja seg fleire variantar som kan fungera.
Kanskje denne er litt for enkel, men slik oppgaven er gitt meiner eg at det skal vera nok med ein tabell, dvs "bilde". Så lenge vi ikkje treng å lagra informasjon om elevane, så treng vi ikkje ha egen tabell for dei. Kolonnen "elev" er derfor tenkt å innehalda fornavn og etternavn til eleven i klartekst. Hvis lærar har behov for å sortera på fornavn og etternavn uavhengig, så kunne vi i staden ha to kolonner. Men det kan godt vera at det er hensiktsmessig å ha ein elevtabell som er kobla til bilde. Ein fordel med dette er at då slepp ein å leggja inn navn på eleven for kvart bilde. Ein treng bare leggja inn elevens ID (eller elevnr). Dette vil også gi betre dataintegritet. Det er fort gjort å skriva litt feil i navn, og det vil gjera det vanskelig å søkja etter denne elevens bilder.
Her treng vi bestemt to tabellar, for vi skal lagra informasjon om både hunden og eigaren. Oppgaven seier at ein hund skal bare ha ein eigar, mens ein eigar kan ha fleire hundar. Derfor blir dette ein ein-til-mange relasjon. Då treng vi referanse til nøkkelen i tabellen "hund" ("regnr") som fremmednøkkel i tabellen "eier". Dette er altså "eier_medlemnr". Her er kjønn ein såkalt TINYINT. Den kom opp av seg sjøl då eg valgte "boolean" som blir brukt for tal som bare kan vera 0 eller 1. (sann eller falsk). Då kan vi velja "1" som kvinne og "0" som mann. Eit alternativ er å bruka ein VARCHAR(1) og sei at "F" står for ho og "M" for hann.
Det er ikkje sagt kor mange skudd ein serie kan innehalda. Dermed må vi tenkja at det kan vera så mange som helst, og det medfører at vi må ha egen tabell for skudd / treff. (Hvis det alltid var ti skudd i ein serie feks., så kunne vi ha ei kolonne for kvart skudd + ei kolonne for kvart treff.). Då blir det altså tre tabellar her: "skytter", "serie" og "skudd". Begge relasjonane blir ein-til-mange: Ein skyttar kan ha mange seriar, men ein serie tilhøyrer ein skyttar. Tilsvarande for skudd: Ein serie har som regel mange skudd, men kvart skudd tilhøyrer ein bestemt serie. På denne måten har vi ein indirekte kobling mellom skudd og skyttar, slik at vi kan finna alle skudd som ein skyttar har i databasen. NB: oppgaven har bedt oss om å lagra "alder" for kvar skyttar, men eg har valgt å heller lagra fødselsdato her. Det er lite lurt å lagra alder, sidan den endrar seg. Fødselsdato endrar seg ikkje.
Variantar: For å finna alle skudda til ein skyttar, må ein gå via skuddserie og gjera ein dobbel JOIN. Men det går an å leggja til ein direkte relasjon mellom skytter og skudd. Då vil vi ha ein fremmednøkkel "skytter_ID eller liknande i tabellen skudd. Ein kan i såfall velja å sløyfa relasjonen mellom skytter og skudd, og då vil vi tegna den i rekkefølgen skytter - skudd - skuddserie.
Denne liknar på forrige i formen: tre tabellar med ein-til-mange-relasjonar. Vi kan kanskje tenkja at det er litt rart at ein art bare kan vera i eit habitat, men slik var oppgava. Eit "habitat" i denne oppgava er jo ikkje nødvendigvis det same som det som biologane meiner med ordet, men så lenge dei som skal bruka databasen er enige om betydningen, så treng vi ikkje bekymra oss! Ein forskjell er at vi har tillatt at det kan vera ingen dyr av ein bestemt art. Dette kan jo vera ein reell situasjon for ein dyrehage, at for tida så har dei ingen løver, men det er ingen grunn til å sletta arten "løve" i databasen av den grunn.
Det interessante her er koblingen mellom gruppe og rom. Sidan vi har ein
mange-til-mange-relasjon mellom gruppe og rom, kan vi tenkja oss ein enkel
koblingstabell der vi har fremmednøklane gruppekode og romnr.
Men dette er ikkje nok, fordi den samme gruppa kan jo vera på samme
rommmet til ulike tider. Derfor har eg tatt med time (heiltall
mellom 1 og 8) og dag (heiltall mellom 1 og 5). Eg har altså tenkt
at i staden for å leggja inn dagar som tekst, så lar eg dag nr 1 stå for
mandag osv. Så var spørsmålet: korleis kan vi sørga for at det ikkje blir
dobbeltbooking? Mitt forslag er som figuren viser: vi lagar ein samansett
primænøkkel med rom_NR, time og dag. Det betyr at kombinasjonen
romnr, dag og time må vera unik. (Det er jo kravet til ein nøkkel) Det vil
sei at vi kan ikkje ha to rader som feks har romnr 1, time nr 2 på dag nr
3 (onsdag). Og dette var grunnen til at eg lot dag vera eit tal, fordi det
er lettare å skriva feil med dagnavn. Feks kunne det henda at noken skreiv
"ornsdag", mens ein annan skreiv det korrekte "onsdag". Og dermed ville vi
ha ein dobbeltbooking. (Her kunne vi riktig nok ha ein dropdown-meny i
applikasjonen som bare lar oss velja dei korrekte dagnavna.) Vidare har eg
gjort det slik at gruppekode i tabellen romtimeplan kan vera NULL, fordi
det kan jo henda at eit rom i noken timar er ledig.
Eit anna spørsmål er korleis vi kan unngå at noken skriv feil i dagnr
eller timenr? Vel, slik det står her kan ingen hindra at noken skriv inn
time 19 eller dag 11. Men det fins måtar å begrensa kva verdiar som kan
leggjast inn i ein kolonne. Ein annan måte å hindra dette er å laga egne
tabellar for time og dag, slik at time i romtimeplanen viser til tabellen
time som bare har fire rader. Her kunne vi då også putta inn informasjon
om når timen startar og sluttar osv.
Her var det presisert at det skulle vera mulig å senda post til medlemmene, og då treng vi både postnr og poststed. Det vanlige er då å ha poststed som egen tabell med nøkkelen postnummer. For store applikasjonar i verkelighetens verden må denne tabellen samstemmast med postens egen tabell, for det hender at det er endringar. Adresse er tenkt å innehalda gatenavn og nummer, men ofte blir disse splitta i to kolonner (eller til og med egen kolonne for husbokstav kan forekomma). Det som kanskje er diskutabelt her er koblingstabellen bandMedlemskap. Her har eg brukt ein samansett nøkkel med medlemsnummer og band-id. Men hvis det skal vera mulig for eit medlem å spela fleire instrument i same band, så må også instrument vera ein del av nøkkelen.
Her føles det naturlig å skilja ut "tidsskrift" som egen tabell, og knytta til tabellen "utgave". (Kanskje kunne vi ha kalt denne for "nummer"?) Grunnen er at navn og redaksjonsadresse er knytta til tidsskriftet som sådan. Dette er rimelig stabil informasjon, som ikkje endrar seg så ofte. Hvis vi har dette i samme tabell som informasjonen om årgang, nr osv, så vil den bli gjentatt mange gonger. Dette fører til unødvendig dobbeltlagring og potensielt til inkonsistens i databasen hvis feks. adressa endrar seg. Då måtte vi nemlig inn i alle radene og endra. Eg tenkte også at det var greit å ha redaktør i tabellen utgave, for det kan jo henda at ein har ulike redaktørar, og hvis vi legg denne under "tidsskrift", så har vi ingen historisk info om kven som var redaktør for eldre utgaver. I denne versjonen kan ein artikkel bare ha ein forfattar. Hvis den skal kunna ha fleire måtte vi laga ein mange-til-mange-relasjon med ein koblingstabell mellom artikkel og forfattar. Det same gjeld emne. Vi kan laga ein egen tabell for emne og knytta denne mot artikkel med ein mange-til-mange-relasjon.
Denne oppgava er ein øvelse i å sila informasjon, for teksten gir oss meir enn vi behøver. Eg har prøvt å gjera det så enkelt som mulig. Tabellen resultat fungerer som koblingstabell mellom løper og treningsøkt. Dessuten tar den vare på tida. Et spørsmål vi må stilla oss er om vi treng å ha ein attributt som fortel om eit resultat er ein rekord. Og ein tommelfingerregel er at vi ikkje skal lagra informasjon som kan reknast ut. Ein rekord er ei bestetid, og den kan vi finna. Derfor har eg ikkje tatt med rekord som egen attributt. Eit anna spørsmål er om vi skal ha koblingen mellom resultat og løype direkte, dvs om vi skal ta med fremmednøkkelen løype_NR i resultat? Eg har valgt å heller leggja den i treningsøkt, men eg trur begge deler er kurant. For å vita kva løype tida gjeld for må vi her gå veien om treningsøkt.
Ein liten rettelse først: det er kvart fly som har id av typen LN-FLK, ikkje flytypen. Derfor må fly.ID ha datatypen VARCHAR. Slik oppgava er gitt er den ganske enkel. Her treng vi entitetane fly og flytype med ein ein-til-mange-relasjon mellom, slik figuren viser. Og vi treng entiteten destinasjon. Men oppgava gir ingen grunn til å laga noken relasjon mellom fly og destinasjon. Så eg har utvida oppgava, og lagt inn flight. Om ikkje anna, så får vi her vist at det er mulig å ha fleire relasjonar mellom samme entitetar. Ein flight går jo både frå og til ein destinasjon. I verkeligheten er det neppe så enkelt som dette.
Denn liknar på oppgava med romtimeplaner. På samme måten som vi der har ein tabell for å kobla gruppe og rom, treng vi her tabellen forestilling for å kobla film med kinosal. Merk at her er det brukt datatypen DATETIME som inneheld både dato og klokkeslett. Nøkkelen i tabellen forestilling er kinosal_ID + tid. Tanken er at vi ikkje skal kunna booka same sal til same tid. (I gamle dagar då vi hadde filmrullar måtte vi kanskje ha tenkt på at ikkje same film kunne gå samtidig også, men med dagens digitale filmar trur eg ikkje det er noken begrensning) MEN det spørs om dette er godt nok, I prinsippet kan ein likevel booka same sal, bare fem minutt seinare. Så her treng vi ei betre løysing. Kan du finna det?