TIETOKANTOJEN PERUSTEET

Relaatiotietokannan suunnittelu riippuvuuksiin perustuen

Sisältö:
Eroon toistuvasta tiedosta
Taulurakenteiden suunnittelu
Funktionaaliset riippuvuudet
Avaimen määrääminen
Riippuvuuksien päättely
Boyce-Codd normaalimuoto
Attribuuttien uudelleenryhmitys Boyce-Codd normaalimuodossa oleviksi kaavioiksi
Oheismateriaali:

Laine: Luku 7 (sivut 134-140)
Ramakrishnan&Gehrke: luvut 19.1-19.4, sivut 605-615
Elmasri&Navathe: luku 10, sivut 293-331.

Eroon toistuvasta tiedosta

Relaatiotietokantojen suunnittelun pääperiaatteena on tiedon toiston välttäminen. Kukin tieto pitäisi tallentaa vain kertaalleen. Tiedon toistumisesta aiheutuvia ongelmia ovat

Tarkastellaan pientä esimerkkitaulua

Työ ttNro nimi s_aika oNro oNimi osSijainti
10 M.Seppä 1.3.59 3 myynti Helsinki
20 D.Leivo 4.5.40 3 myynti Helsinki
30 S.Koivu 8.6.66 4 hallinto Espoo
40 B.Oja 2.4.65 4 hallinto Espoo
50 O.Itä 1.2.55 6 tuotanto Espoo

Tässä taulussa osastojen 3 ja 4 nimi sekä sijaintipaikka on tallennettu kahteen kertaan. Jos osasto3 muuttaisi Helsingistä Espooseen, pitäisi muutos tehdä kahdelle taulun riville eli ylläpito muodostuu työläämmäksi. Tietenkin näin pienessä taulussa toiston tuomat ongelmat ovat varsin vähäisiä, mutta suuremmissa ne vastaavasti moninkertaistuvat. Hankalampi ongelma on se, että jos työntekijä O.Itä päättäisi lähteä yrityksestä ja hänen rivinsä poistettaisiin, poistuisi samalla tieto siitä, että tuotanto-osastokin on olemassa. Uutta osastoa ei voida myöskään lisätä, ellei sinne heti sijoiteta jotain työntekijää.

Rakenteeltaan parempaan tietokantaan päästään suunnittelemalla taulurakenne paremmin tilanteeseen sopivaksi. Yllä olevan esimerkin tapauksessa toistosta päästään eroon seuraavilla tauluilla

Työntekijä ttNro nimi s_aika oNro
10 M.Seppä 1.3.59 3
20 D.Leivo 4.5.40 3
30 S.Koivu 8.6.66 4
40 B.Oja 2.4.65 4
50 O.Itä 1.2.55 6

Osasto oNro oNimi osSijainti
3 myynti Helsinki
4 hallinto Espoo
6 tuotanto Espoo

Nyt osastoja voi lisätä ilman, että niihin sijoitetaan työntekijää. Työntekijän poisto ei hävitä osastoa missään tilanteessa ja osaston muuttaessa riittää tehdä muutos yhdelle riville.

Tiedon toiston välttäminen on hyvä asia tietokannan tilantarpeen ja ylläpidon kannalta. Kyselyjen tehokkuutta toisteinen tieto voi kuitenkin parantaa.

Taulurakenteiden suunnittelu

Tällä kurssilla käsitellään vain taulurakenteiden suunnittelua ja sitäkin johdantoluonteisesti siten, että vain pieni mutta keskeinen osa relaatiomalliin liittyvästä suunnitteluteoriasta tulee katetuksi.

Relaatiotietokantojen suunnitteluteoriassa relaatiokaavion hyvyys määritellään tietojen välisiin riippuvuuksiin perustuen. Riippuvuustyyppejä on määritelty useita, mutta tärkeimpiä niistä ovat funktionaaliset riippuvuudet (functional dependency).

Funktionaaliset riippuvuudet

Funktionaalisella riippuvuudella tarkoitetaan sitä, että sarakkeen arvon avulla pystytään selvittämään yksikäsitteinen arvo sarakkeesta funtionaalisesti riippuvalle sarakkeelle. Esimerkiksi henkilötunnuksen perusteella saadaan selville yksikäsitteinen nimi, syntymäaika, osoite, yms. Sama muodollisemmin:

Attribuutti B on funktionaalisesti riippuva attribuutista A (A määrää funktionaalisesti B:n, merkitään A->B), jos ja vain jos kaikissa relaatiokaavion R ilmentymissä kuvaus A:n arvojoukolta B:n arvojoukolle on funktionaalinen. 

Kuvaus A:n arvojoukolta B:n arvojoukolle on funktionaalinen, jos jokainen A:n arvo kuvautuu yhdelle B:n arvolle eli, jos riveillä r ja s attribuutilla A on sama arvo (r.A=s.A), niin näillä riveillä täytyy myös B-attribuuteilla olla keskenään sama arvo (r.B=s.B).

Riippuvuudessa A->B kutsutaan attribuuttia A määrääjäksi. A voi olla yksittäinen attribuutti tai kokoelma attribuutteja. Kun riippuvuuksia määritellään, pyritään määrääjiksi löytämään minimaaliset attribuuttiyhdistelmät. Määrääjä on minimaalinen, jos siinä ei ole turhia attribuutteja. Esimerkiksi riippuvuudessa  Ax->B attribuutti x on turha, mikäli  A->B. Relaatiokaavioon liittyvät riippuvuudet voidaan aina esittää siten, että kussakin riippuvuudessa oikealla puolella, siis riippuvana, on vain yksi attribuutti.

Avaimen määrääminen

Relaation avain määritellään riippuvuuksien avulla seuraavasti

Sarakeyhdistelmä A on relaatiokaavion R avain, jos se määrää funktionaalisesti kaikki relaatiokaavion attribuutit eikä ole olemassa sellaista A:n osajoukkoa, jolla olisi tämä sama ominaisuus.

Funtionaalisten riippuvuuksien perusteella voidaan täten selvittää, mitkä sarakkeet muodostavat relaation avaimen. Avaimen saa selville seuraavalla algoritmilla:

Ota avainehdokkaaksi K kaikki attribuutit, jotka eivät esiinny riippuvuuksissa oikealla puolella eivätkä ole siis riippuvia muista. Kunnes K määrää funktionaalisesti kaikki kaavion attribuutit, yhdistä K:hon määrääjä sellaisesta riippuvuudesta, jossa määräytyvä attribuutti ei kuulu K:hon. Kun attribuuttijoukkoa K:ta ei enää tarvitse täydentää, on avain löytynyt.

Yllä olevassa voidaan riippuvuuksia soveltaa eri järjestyksissä ja näin saadaan vaihtoehtoisia avaimia.

Riippuvuuksien päättely

Annetusta joukosta riippuvuuksia voidaan päätellä uusia riippuvuuksia. Päättely perustuu kolmeen päättelysääntöön, ns. Armstrongin aksiomiin

refleksiivisyys Jos XÊ Y, niin X->Y

eli X määrää funktionaalisesti kaikki osajoukkonsa, Tällaisia riippuvuuksia kutsutaan triviaaleiksi eikä niitä kirjata kartoituksessa.
laajennettavuus Jos X->Y niin XZ->YZ

eli voimassaolevan  riippuvuuden kummallekin puolelle voidaan lisätä sama attribuuttiyhdistelmä ja saadaan uusi riippuvuus 
transitiivisuus Jos X->Y ja Y->Z, niin  X->Z

eli funktionaaliset riippuvuudet ovat transitiivisia

Mille tahansa riippuvuusjoukolle voidaan määritellä minimaalinen joukko riippuvuuksia, josta on pääteltävissä samat riippuvuudet kuin annetusta riippuvuusjoukosta. Kartoitettaessa relaatiokaavioon liittyviä riippuvuuksia on tavoitteena löytää minimaalinen riippuvuusjoukko. Minimaalisessa riippuvuusjoukossa ei ole riippuvuuksia, jotka voidaan päätellä muista riippuvuuksista. On olemassa algoritmeja, jotka laskevat annetulle riippuvuusjoukolle minimaalisen riippuvuusjoukon.

Riippuvuudet heijastavat tietokannan kohdealueella vallitsevia lainalaisuuksia. Niitä ei voi määrätä tarkastelemalla vain tiettyä kaavion ilmentymää vaan niitä määrättäessä pitää ajatella tilannetta missä tahansa kaavion ilmentymässä.

Tarkastellaan esimerkkikaaviota Ostos ja siihen liittyviä mahdollisia riippuvuuksia. Alla olevassa taulukossa punertavalla värillä merkityt vaihtoehdot hylätään. Jäljelle jäävien riippuvuuksien joukko on minimaalinen.

Ostos(tuotenumero, tuotenimi, listahinta, ostajan_nimi, alennusprosentti, maksettuhinta,ostopäivä)
tuotenumero->tuotenimi Tuotenumeroon liittyy yksi tuotenimi. OK
tuotenumero->listahinta Tuotteella on vain yksi listahinta. OK
tuotenumero->ostajan_nimi Tuotteella on vain yksi ostaja. EI
tuotenumero->alennusprosentti Alennusprosentti on tuotekohtainen.
EHKÄ, oletetaaan kuitenkin, että näin ei ole
tuotenumero->maksettuhinta Tuotteella on vain yksi maksettu hinta. EI, riippuvuus olisi voimassa, jos alennusprosentti olisi tuotekohtainen
tuotenumero->ostopäivä Tuotetta voi ostaa vain yhtenä päivänä. EI 
tuotenimi->tuotenumero Tuotenimi on yksikäsitteinen. EHKÄ,
Oletetaan, ettei tämä ole voimassa, jolloin kaaviossa ei ole mielekkäitä riippuvuuksia, joissa tuotenimi olisi määrääjä
ostajan_nimi->tuotenumero Ostaja ostaa vain yhtä tuotetta. EI 
ostajan_nimi->alennusprosentti Alennusprosentti on ostajakohtainen. EHKÄ, oletetaan näin olevan
alennusprosentti-> jotain Alennusprosentin perusteella ei saada selville jonkin muun sarakkeen arvo. EI
listahinta-> jotain Listahinnan perusteella saadaan selville 
maksettuhinta-> jotain Maksetun hinnan perusteella saadaan selville jonkin muun sarakkeen arvo. EI
listahinta,alennusprosentti-> maksettuhinta Maksettu hinta on laskettavissa listahinnan ja alennusprosentin avulla. OK 

Boyce-Codd normaalimuoto

Tietojen yhteenkuuluvuus voidaan määritellä riippuvuuksien avulla. Relaatiomalliin liittyvässä suunnitteluteoriassa on määritelty useita ns. normaalimuotoja, joihin kuhunkin liittyy erilaiset säännöt. Tällä kurssilla tarkastellaan normaalimuodoista vain Boyce-Codd normaalimuotoa. Normaalimuoto määritellään seuraavasti:

Relaatiokaavio on Boyce-Codd -normaalimuodossa, jos ja vain jos relaatiokaavioon ei liity yhtään sellaista funktionaalista riippuvuutta, jossa määrääjä ei sisältäisi relaation avainta.

Kun tietokannan relaatiot ovat kaikki Boyce-Codd normaalimuodossa, ei tietokannassa ole lainkaan toisteista tietoa. Boyce-Codd normaalimuoto ei kuitenkaan ole aina saavutettavissa. Hieman lievemmässä kolmannessa normaalimuodossa sallitaan Boyce-Codd normaalimuodossa sallittujen riippuvuuksien lisäksi sellaiset riippuvuudet, joissa riippuva attribuutti kuuluu johonkin avaimeen. Kaavion jako tällaisiin osakaavioihin on aina saavutettavissa. Esimerkiksi kaavio

Osoite(Postinumero,Kaupunki,Katuosoite), jossa riippuvuudet ovat

Postinumero->Kaupunki ja Kaupunki, Katuosoite -> Postinumero

ei ole Boyce-Codd -normaalimuodossa sillä avaimet tässä kaaviossa ovat {Postinumero,Katuosoite} ja {Kaupunki,Katuosoite} eikä Postinumero sisällä näistä kumpaakaan. Sen sijaan riippuvuuden Postinumero->Kaupunki riippuva attribuutti Kaupunki kuuluu avaimeen {Kaupunki,Katuosoite}, joten relaatiokaavio on kolmannessa normaalimuodossa.

Boyce-Codd normaalimuodon tarkistamiseksi on siis ensiksi määriteltävä relaation avaimet ja sen jälkeen tarkistettava rikkooko jokin relaatiokaavioon liittyvä riippuvuus Boyce-Codd normaalimuodon ehdon.

Kaavion Ostos riippuvuuksissa oikealla puolella eivät esiinny tuotenumero , ostajan_nimi eikä ostopäivä . Siispä K on aluksi { tuotenumero,ostajan_nimi ja ostopäivä }. K:sta riippuvien attribuuttien joukko sisältää refleksiivisyyssäännön mukaan attribuutit itsensä sekä transitiivisuuden perusteella kaikki sellaiset attribuutit, jotka riippuvat näistä. K:sta riippuvia ovat siis tuotenumerosta riippuvat tuotenimi ja listahinta sekä ostajan_nimestä riippuva alennusprosentti . Listahinta ja alennusprosentti puolestaan määräävät yhdessä maksuhinnan eli kaikki relaatiokaavion attribuutit kuuluvat K:n perusteella määräytyviin attribuutteihin. K on siis tämän kaavion ainoa avain, koska siihen ei tarvinnut lisätä mitään.

Yksikään kaavioon Ostos liittyvistä riippuvuuksista ei sisällä avainta K, joten kaavio ei ole Boyce-Codd normaalimuodossa. Attribuutit on siis uudelleenjärjesteltävä sellaisiksi relaatioiksi, joissa Boyce-Codd normaalimuodon vaatimukset ovat voimassa. Seuraavat relaatiot täyttävät ehdon

  1. Tuote( tuotenumero , tuotenimi, listahinta)    
  2. Ostaja( ostajan_nimi , alennusprosentti)
  3. Alennus( listahinta, alennusprosentti ,maksuhinta)
  4. Ostos( tuotenumero,ostajan_nimi,ostopäivä )

Näistä kolmas (Alennus) on laskettavissa oleva funktio eikä sitä ole tarpeen tallentaa tietokantaan.

Attribuuttien uudelleenryhmitys Boyce-Codd normaalimuodossa oleviksi kaavioiksi

Boyce-Codd normaalimuodossa oleva tietokantakaavio voidaan määrätä minimaalisen riippuvuusjoukon perusteella seuraavasti:

  1. Ryhmittele riippuvuudet ryhmiin yhteisen määrääjän perusteella
  2. Muodosta kutakin ryhmää kohden relaatiokaavio, johon otat kaikki ryhmän riippuvuuksissa esiintyvät attribuutit
  3. Jos relaatiokaavion avain ei sisälly muodostettuihin relaatioihin, muodosta siihen kuuluvista attribuuteista oma relaatio.
  4. Karsi mahdolliset saman asian toisteiset esitykset.
  5. Anna muodostuneille relaatiokaavioille nimet. Jos niille löytyy nimet ja luonnollinen merkitys jakoa voi pitää onnistuneena.

Kaavion Ostos uudelleenjärjestelyn tuloksena syntyneistä kaavioista a, b ja c määräytyvät kohdan 2 perusteella ja d kohdan 3 perusteella. Niille löytyi myös luonnolliset nimet.

Esimerkki:

Aiemmin oli esillä ongelmallinen taulu Työ

Työ ttNro nimi s_aika oNro oNimi osSijainti
10 M.Seppä 1.3.59 3 myynti Helsinki
20 D.Leivo 4.5.40 3 myynti Helsinki
30 S.Koivu 8.6.66 4 hallinto Espoo
40 B.Oja 2.4.65 4 hallinto Espoo
50 O.Itä 1.2.55 6 tuotanto Espoo

Tähän tauluun liittyen voidaan löytää riippuvuudet

ttNro ->  nimi,

ttNro -> s_aika

ttNro -> oNro

oNro -> oNimi

oNro -> osSijainti

Riippuvuuksien perusteella taulun avain on sarake ttNro . Taulu ei ole Boyce-Codd normaalimuodossa. Siinä esiintyy siis toistoa, kuten aiemmin todettiin. Kun riippuvuudet ryhmitellään yhteisen määrääjän perusteella, saadaan ryhmät:

ttNro ->  nimi,

ttNro -> s_aika

ttNro -> oNro

ja

oNro -> oNimi

oNro -> osSijainti.

Näiden perusteella määräytyvät kaaviot

kaavio_1 (ttNro,  nimi, s_aika, oNro) ja

kaavio_2 (oNro, oNimi, osSijainti).

Kun kaavioille annetaan uudet nimet, päädytään aiemmin esillä olleisiin tauluihin

Työntekijä (ttNro,  nimi, s_aika, oNro) ja

Osasto(oNro, oNimi, osSijainti).

Esimerkki:

Opintosuoritusote sisältää seuraavat tiedot

Oletetaan, että kaikki opiskelijoiden suoritusotteisiin tarvittavat tiedot talletettaisiin yhteen relaatioon (ns. universaalirelaatio-oletus). Määritellään tässä relaatiossa voimassa olevat funktionaaliset riippuvuudet

Opiskelijan_henkilötunnus -> Opiskelijanumero Henkilöllä voi olla vain yksi opiskelijanumero
Opiskelijanumero -> Opiskelijan_henkilötunnus  Opiskelijanumero henkilökohtainen
Opiskelijanumero -> OpiskelijanNimi Opiskelijanumeroon liittyy yksi nimi (1)
Opiskelijanumero -> OpiskelijanOsoite Opiskelijanumeroon liittyy yksi osoite (1)
Opiskelijanumero -> OpiskelijanKirjoilletuloPvm Opiskelijanumeroon liittyy yksi kirjoilletulopäivä (1)
Opiskelijanumero -> PääOpinto-oikeudenKoulutusohjelma Opiskelijalla on pääopinto-oikeus yhteen koulutusohjelmaan (1)
Opiskelijanumero ->  PääOpinto-oikeudenTiedekunta Opiskelijalla on pääopintooikeus yhteen tiedekuntaan. Tämä on pääteltävissä.
Opiskelijanumero -> PääOpinto-oikeudenPääaine Opiskelijalla on pääopistoikeus yhteen pääaineeseen. Tämä on pääteltävissä
PääOpinto-oikeudenKoulutusohjelma-> PääOpinto-oikeudenTiedekunta Koulutusohjelma kuuluu yhteen tiedekuntaan
PääOpinto-oikeudenKoulutusohjelma-> PääOpinto-oikeudenPääaine Koulutusohjelmalla on yksi pääaine
SuorituksenKoodi -> KurssinNimi Kurssikoodiin liittyy yksi kurssin nimi
SuorituksenKoodi -> SuorituksenLaitos Kurssikoodit ovat laitoskohtaisia
Opiskelijanumero, SuorituksenKoodi -> Suorituspäivä Kurssista kirjataan kullekin vain yksi suorituskerta (1)
Opiskelijanumero, SuorituksenKoodi -> Arvosana Kurssista kirjataan kullekin vain yksi arvosana (1)
Opiskelijanumero, SuorituksenKoodi -> SuorituksenLaajuus Kurssin voi suorittaa erikokoisena

(1) Myös riippuvuudet joissa henkilötunnus määrää näissä riippuvuuksissa oikealla olevan attribuutin ovat voimassa. Tässä on valittu nämä keskeisimmiksi joten henkilötunnukseen perustuvat riippuvuudet jäävät pääteltäviksi

Kun punaisella merkityt karsitaan, jää jäljelle minimaalinen joukko riippuvuuksia. Näiden perusteella saadaan relaatiolle avaimet {Opiskelijanumero, SuorituksenKoodi} ja {Opiskelijan_henkilötunnus, SuorituksenKoodi}.

Relaatio ei ole Boyce-Codd normaalimuodossa, koska esimerkiksi riippuvuudessa 'SuorituksenKoodi  -> SuorituksenLaitos' määrääjä ei sisällä kumpaakaan avaimista.

Tehdään riippuvuuksien ryhmittely yhteisen määrääjän perustella ja muodostetaan relaatiokaaviot ryhmiin kuuluvista attribuuteista. Tuloksena saadaan kaaviot

Kaavio 1 Opiskelijanumero
Opiskelijan_henkilötunnus
OpiskelijanNimi
OpiskelijanOsoite
OpiskelijanKirjoilletuloPvm
PääOpinto-oikeudenKoulutusohjelma
Kaavio 2 Opiskelijanumero
Opiskelijan_henkilötunnus
Kaavio 3 PääOpinto-oikeudenKoulutusohjelma
PääOpinto-oikeudenTiedekunta
PääOpinto-oikeudenPääaine
Kaavio 4 SuorituksenKoodi 
KurssinNimi
SuorituksenLaitos
Kaavio 5 Opiskelijanumero
SuorituksenKoodi
Suorituspäivä
Arvosana
SuorituksenLaajuus

Saatuja kaavioita tarkastelemalla havaitaan, että Kaavio 2 on projektio Kaavioista 1, joten se voidaan toisteisena jättää pois. Sarakkeet voidaan myös nimetä uudelleen. Seuraavassa taulukossa taulut on nimetty ja muutama sarake uudelleennimetty. Taulukkoon on merkitty myös kaavioiden pääavaimet. Nämä kaaviot ovat kaikki Boyce-Codd normaalimuodossa.

Opiskelija Opiskelijanumero
Henkilötunnus
Nimi
Osoite
KirjoilletuloPvm
PääOpinto-oikeudenKoulutusohjelma
Koulutusohjelma Koulutusohjelma
Tiedekunta
Pääaine
Kurssi KurssiKoodi
KurssinNimi
VastuuLaitos
Suoritus Opiskelijanumero
KurssiKoodi
Suorituspäivä
Arvosana
SuorituksenLaajuus

 


Harri Laine: Tietokantojen perusteet, Helsingin yliopisto, Tietojenkäsittelytieteen laitos, 2005