Luku 3 Relaatioalgebra Relaatioalgebra on yksinkertaisesti joukko relaatioiden käsittelyyn tarkoitettuja operaatioita. Vaikka yksittäiset operaatiot ovat varsin yksinkertaisia, voidaan niitä yhdistelemällä helposti tuottaa hyvinkin monimutkaisia kyselyitä vastaavia lausekkeita. Operaatiot muodostavat myös perustan SQL-kielelle, jota käsitellään tarkemmin luvussa 5. SQL:n omaksuminen ei vaadi relaatioalgebran täydellistä hallintaa, mutta ainakin karteesisen tulon käsitteeseen on syytä perehtyä. 3.1 Joukko-opilliset operaatiot Relaatioalgebra sisältää koko joukon joukko-opista tuttuja operaatioita. Ne käyttäytyvät normaalilla tavalla sillä poikkeuksella, että jotkin niistä vaativat relaatioiden yhteensopivuutta. 3.1.1 Yhdiste eli unioni Relaatioiden Relaatio 1 ja Relaatio 2 unioni Relaatio 1 Relaatio 2 sisältää ne monikot, jotka sisältyvät joko Relaatio 1 :een tai Relaatio 2 :een. Selvyyden vuoksi huomautettakoon, että yhdisteeseen kuuluvat myös ne monikot, jotka kuuluvat kumpaankin relaatioon. Joukko-opillisesta unionista poiketen relaatioalgebran unioni vaatii kuitenkin relaatioiden yhteensopivuutta eli sitä, että relaatioilla on sama määrä attribuutteja ja relaatioiden attribuuteilla on samat arvojoukot eli mahdollisten arvojen joukot. Tulosrelaation attribuuttien nimet ovat samat kuin yhdistettävien relaatioiden. Operaatiota on havainnollistettu kuvassa 3.1, jossa on esitetty kaksi yhteensopivaa relaatiota sekä niiden unioni. Kannattaa huomata, että jokaisen relaatioalgebran operaation tulos on relaatio eli monikkojen joukko, joka ei - kuten eivät joukot yleensäkään - sisällä duplikaatteja. Niinpä esimerkiksi <Orimatti,Teuras> sisältyy unioniin ainoastaan kerran, vaikka se kuuluukin sekä Asiakas- että Työntekijärelaatioon. 3.1.2 Leikkaus Relaatioiden Relaatio 1 ja Relaatio 2 leikkaus Relaatio 1 Relaatio2 sisältää ne monikot, jotka sisältyvät sekä Relaatio 1 :een että Relaatio 2 :een. Unionin 11
Asiakas Etunimi Sukunimi Orimatti Laupias Hanhikki Teuras Psaltari Hillosilmä Työntekijä Etunimi Sukunimi Luikuri Orimatti Lahtiranta Teuras Asiakas Työntekijä Etunimi Sukunimi Orimatti Laupias Hanhikki Luikuri Teuras Psaltari Hillosilmä Lahtiranta Asiakas Työntekijä Etunimi Sukunimi Orimatti Teuras Asiakas Työntekijä Etunimi Sukunimi Laupias Hanhikki Psaltari Hillosilmä Kuva 3.1: Esimerkki relaatioiden unionista, leikkauksesta ja erotuksesta. tavoin myös leikkaus vaatii relaatioiden yhteensopivuutta. Leikkausoperaatiota on havainnolistettu kuvassa 3.1. 3.1.3 Erotus Relaatioiden Relaatio 1 ja Relaatio 2 erotus Relaatio 1 Relaatio2 sisältää tietysti ne monikot, jotka sisältyvät Relaatio 1 :een, mutta eivät Relaatio 2 :een. Operaatiota on havainnollistettu kuvassa 3.1 ja sen edellytyksenä on jälleen relaatioiden yhteensopivuus. 3.1.4 Karteesinen tulo Karteesinen tulo eli ristitulo yhdistää relaatiot Relaatio 1 ja Relaatio 2 siten, että jokainen Relaatio 1 :n monikko yhdistetään jokaiseen Relaatio 2 :n monikkoon. Karteesisen tulon - samoin kuin muidenkin relaatioalgebran operaatioiden - tulos on siis uusi relaatio, jolla on sekä Relaatio 1 :n että Relaatio 2 :n attribuutit. Tarkemmin sanottuna karteesisen tulon Relaatio 1 Relaatio 2 tulosrelaation kaavassa esiintyvät ensin Relaatio 1 :n attribuutit siinä järjestyksessä ja samoin nimettynä kuin Relaatio 1 :ssä ja sitten Relaatio 2 :n attribuutit niin ikään siinä järjestyksessä ja samoin nimettynä kuin Relaatio 2 :ssa. Kuvissa 3.2 ja 3.3 on havainnollistettu karteesisen tulon käsitettä käyttäen esimerkkinä tuloja Asiakas Työntekijä sekä Tuote Toimittaja. Kummassakis tapauksessa relaatioilla on samannimisiä attribuutteja, joten tulosrelaatioiden attribuuttien nimiä on tarvittaessa selvennetetty alkuperäisten relaatioiden nimillä. Myöhemmin opitaan, miten nimeämisongelmat voidaan välttää uudelleennimeämisoperaatiota käyttäen. Vaikka karteesisella tulolla onkin operaationa käyttöä vain harvoin, on se käsitteenä erityisen keskeinen sekä relaation käsitteen että relaatioiden yhdistämisen kannalta. On syytä huomata, että karteesinen tulo ei muista joukko-opillisista operaatioista poiketen vaadi relaatioiden yhteensopivuutta. Karteesisen tulon käsitteen avulla voimme myös määritellä relaation täsmällisemmin kahden tai useamman joukon karteesisen tulon osajoukkona. 12
Asiakas Etunimi Sukunimi Orimatti Laupias Hanhikki Teuras Psaltari Hillosilmä Työntekijä Etunimi Sukunimi Luikuri Orimatti Lahtiranta Teuras Asiakas Työntekijä Asiakas.Etunimi Asiakas.Sukunimi Työntekijä.Etunimi Työntekijä.Sukunimi Orimatti Teuras Luikuri Lahtiranta Orimatti Teuras Orimatti Teuras Laupias Psaltari Luikuri Lahtiranta Laupias Psaltari Orimatti Teuras Hanhikki Hillosilmä Luikuri Lahtiranta Hanhikki Hillosilmä Orimatti Teuras Kuva 3.2: Esimerkki relaatioiden karteesisesta tulosta. Tuote.Id Tuote.Nimi... ToimittajaId Toimittaja.Id Toimittaja.Nimi 1 Hilavitkutin... 2 1 Jaskan vimpain 1 Hilavitkutin... 2 2 Orimattilan kone 2 Vimpain... 1 1 Jaskan vimpain 2 Vimpain... 1 2 Orimattilan kone 3 Masiina... 1 1 Jaskan vimpain 3 Masiina... 1 2 Orimattilan kone 4 Jiirisaha... 2 1 Jaskan vimpain 4 Jiirisaha... 2 2 Orimattilan kone Kuva 3.3: Kuvan 2.3 relaatioiden Tuote ja Toimittaja karteesinen tulo. Jo aiemmin tarkastelimme joukkoja {Lissu, Masa} ja {Tuulilasi, Eeva} sekä näiden joukkojen relaatiota Tilaus = {<Lissu,Eeva>,<Masa,Tuulilasi>}. Relaatio Tilaus siis tosiaan on joukkojen karteesisen tulon osajoukko ja sen merkityskin on ilmeinen: Lissu tilaa Eevaa ja Masa Tuulilasia. Mikä sitten on kuvassa 2.3 esitetyn Asiakas-relaation merkitys? Relaatio on selvästikin joukkojen {1, 2, 3}, {Orimatti, Laupias, Hanhikki} ja {Teuras, Psaltari, Hillosilmä} karteesisen tulon osajoukko 1. Esimerkiksi se, että arvot 1, Orimatti ja Teuras ovat relaatiossa Asiakas, on tulkittavissa siten, että Orimatin sukunimi on Teuras ja asiakasnumero 1. Monikko <1,Orimatti,Psaltari> kuuluu myös karteesiseen tuloon, mutta ei ole Asiakas-relaatiossa, koska Orimatin sukunimi ei ole Psaltari. 3.2 Perusoperaatiot Relaatioalgebran operaatiot kohdistuvat relaatioihin ja ne tuottavat tuloksenaan relaation. Siten operaatioita voidaan kirjoittaa sisäkkäin ja peräkkäin siten, että edellisen operaation tulosrelaatio on seuraavan operaation kohteena. 1 Joukot voitaisiin tietysti valita myös toisin. Attribuutin Id arvojoukko voisi olla vaikkapa luonnollisten lukujen joukko ja attribuuttien Etunimi ja Sukunimi arvojoukot kaikkien etu- ja sukunimien joukot tai vielä yleisemin kaikkien merkkijonojen joukot. 13
3.2.1 Valinta σ Valintaoperaatio σ valitsee relaatiosta eli taulusta tietyt ehdot täyttävät monikot eli rivit 2. Jos esimerkiksi haluamme valita kaikki ne asiakkaat, joiden etunimi on Orimatti, voimme käyttää valintaa seuraavasti: σ Etunimi= Orimatti (Asiakas). Valintaoperaation toimintaa on havainnollistettu kuvassa 3.4. σ Etunimi= Orimatti (Asiakas) valitsee siis kuvan vasemmanpuoleisessa relaatiossa tummennetun rivin ja sen tuloksena saadaan kuvassa oikealla esitetty relaatio. Voimme myös halutessamme eksplisiittisesti nimetä tulosrelaation ja sen attribuutit ja käyttää asetuslausetta seuraavasti: Tulos(Numero, Etu, Suku) σ Etunimi= Orimatti (Asiakas). Tulosrelaation käyttöä on havainnollistettu kuvassa 3.5. Ainoa ero kuvaan 3.4 on tietysti se, että tulosrelaatiolla ja sen attribuuteilla on toiset nimet. Yleisesti valintaoperaatio σ on muotoa σ Ehto (Relaatio), missä Relaatio ja Ehto ovat tietysti operaation kohderelaatio ja valintaehto; tulosrelaation attribuuttien nimet ovat samat kuin kohderelaatiossa. Valintaehto voi periaatteessa olla mikä tahansa totuusarvoinen lauseke. Käytännössä se kuitenkin useimmiten koostuu vertailuista, joissa operandeina eli vertailun kohteina voidaan käyttää kohderelaation attribuuttien arvoja ja vakioita ja vertailuoperaatioina operaatioita =,, <,, > ja. Operaatioiden <,, > ja käyttö edellyttää luonnollisesti sitä, että attribuutin arvojoukko on järjestetty 3. Merkkijonovakiot erotetaan attribuuttien nimistä heittomerkkejä käyttäen. Ehtoja voidaan tavalliseen tapaan yhdistellä konjunktion AND ja disjunktion OR avulla sekä negaation NOT avulla. Ehtojen normaalia arviointijärjestystä - eli vasemmalta oikealle - voidaan muuttaa sulkeiden avulla. Kuten edellä jo mainittiin, on jokaisen relaatioalgebran operaation tulos relaatio, joten tulokseen voidaan kohdistaa uusia operaatioita. Tämä onnistuu joko kirjoittamalla operaatioita sisäkkäin tai peräkkäin. Voisimme esimerkiksi valita relaatioiden Tuote ja Toimittaja karteesisesta tulosta kaikki ne monikot, joissa ToimittajaId=Toimittaja.Id. Kirjoittaen operaatiot sisäkkäin päädymme seuraavaan lausekkeeseen: σ ToimittajaId=Toimittaja.Id (Tuote Toimittaja). Lauseketta on havainnollistettu kuvassa 3.6; alla esitettyyn tulosrelaatioon on valittu yllä esitetystä karteesisesta tulosta tummennetut rivit. Jos taas haluamme kirjoittaa operaatiot peräkkäin, voimme ensin esitellä apurelaation Apu, johon ensimmäisen operaation tulos tallennetaan 4 : 2 Lukija, joka jo tuntee SQL:ää, voi ajatella valintaoperaation vastaavan SQL-kyselyn WHERE-osaa. 3 Kokonaislukujen ja reaalilukujen lisäksi myös esimerkiksi merkkijonoilla voidaan katsoa olevan järjestys eli aakkosjärjestys. 4 Relaatiossa Apu on tietysti oltava yhtä monta attribuuttia kuin relaatioiden Tuote ja Toimittaja tulossa. Tilan säästämiseksi kaavassa on lueteltu vain osa attribuuteista. 14
Asiakas Id Etunimi Sukunimi 1 Orimatti Teuras 2 Laupias Psaltari 3 Hanhikki Hillosilmä Id Etunimi Sukunimi 1 Orimatti Teuras Kuva 3.4: Lausekkeen σ Etunimi= Orimatti (Asiakas) toiminta ja tulos. Asiakas Id Etunimi Sukunimi 1 Orimatti Teuras 2 Laupias Psaltari 3 Hanhikki Hillosilmä Tulos Numero Etu Suku 1 Orimatti Teuras Kuva 3.5: Kuvan 3.4 lauseke apurelaatiota käyttäen. Apu(TuoId, TuoNimi,...) Tuote Toimittaja. Jos attribuutteja Tuote.ToimittajaId ja Toimittaja.Id vastaavien Apurelaation attribuuttien nimiksi valittiin TuoToimId ja ToimId, voimme nyt valita Apu-relaatiosta ne rivit, joissa TuoToimId=ToimId seuraavasti: σ TuoToimId=ToimId (Apu). Peräkkäin kirjoitettuina operaatiot siis toimivat samalla tavalla ja tuottavat saman tuloksen kuin sisäkkäin kirjoitettuina. Toisinaan sisäkkäin kirjoitetut lausekkeet ovat kuitenkin siksi monimutkaisia, että ne on syytä kirjoittaa peräkkäin apurelaatioita käyttäen. Valintaoperaatio on selvästikin kommutatiivinen eli σ Ehto1 (σ Ehto2 (Relaatio)) = σ Ehto2 (σ Ehto1 (Relaatio)) mille tahansa ehdoille Ehto 1 ja Ehto 2 sekä relaatiolle Relaatio. Lisäksi myöhemmin SQL-kyselyitä kirjoittaessamme käytämme hyväksemme sitä, että mille tahansa ehdoille Ehto 1,..., Ehto n ja relaatiolle Relaatio on voimassa σ Ehto1 (...(σ Ehton (Relaatio))) = σ Ehto1 AND... AND Ehto n (Relaatio). On ehkä vielä syytä huomauttaa, että mikäli yksikään kohderelaation monikoista ei täytä valintaehtoa, on tuloksena tyhjä relaatio. Esimerkiksi valinta σ Hinta<0.50 (Tuote) tuottaa kuvassa 3.7 esitetyn relaation. 3.2.2 Projektio π Projektio π valitsee relaatiosta eli taulusta tietyt attribuutit eli sarakkeet 5. Voimme esimerkiksi valita kaikkien asiakkaittemme etu- ja sukunimet seuraavasti: 5 SQL:ää hallitseva voi ajatella projektion vastaavan suunnilleen SQL-kyselyn SELECT-osaa. 15
Tuote Toimittaja Tuote.Id Tuote.Nimi... ToimittajaId Toimittaja.Id Toimittaja.Nimi 1 Hilavitkutin... 2 1 Jaskan vimpain 1 Hilavitkutin... 2 2 Orimattilan kone 2 Vimpain... 1 1 Jaskan vimpain 2 Vimpain... 1 2 Orimattilan kone 3 Masiina... 1 1 Jaskan vimpain 3 Masiina... 1 2 Orimattilan kone 4 Jiirisaha... 2 1 Jaskan vimpain 4 Jiirisaha... 2 2 Orimattilan kone Tuote.Id Tuote.Nimi... ToimittajaId Toimittaja.Id Toimittaja.Nimi 1 Hilavitkutin... 2 2 Orimattilan kone 2 Vimpain... 1 1 Jaskan vimpain 3 Masiina... 1 1 Jaskan vimpain 4 Jiirisaha... 2 2 Orimattilan kone Kuva 3.6: Lausekkeen σ ToimittajaId=Toimittaja.Id (Tuote Toimittaja) toiminta ja tulos. Id Nimi Kuvaus Hinta ToimittajaId Kuva 3.7: Lausekkeen σ Hinta<0.50 (Tuote) tulos. π Etunimi, Sukunimi (Asiakas) Edellistä operaatiota on havainnollistettu kuvassa 3.8; operaatio valitsee vasemmalla esitetystä kohderelaatiosta tummennetut sarakkeet. Yleisessä tapauksessa operaatio on muotoa π Attribuutti1,...,Attribuutti n (Relaatio), missä Attribuutti 1,...,Attribuutti n ovat valittavat attribuutit ja Relaatio operaation kohderelaatio. Jotta projektio olisi mielekäs, on kohderelaatiolla tietysti oltava valittavat attribuutit. Käyttämällä valintaa ja projektiota voimme valita kaikkien niiden tuotteiden nimet, jotka maksavat yli kymmenen euroa seuraavasti: π Nimi (σ Hinta>10 (Tuote)) Sisempi valintaoperaatio siis valitsee ne Tuote-taulun rivit, joissa attribuutin Hinta arvo on suurempi kuin 10. Ulompi operaatio eli projektio taas valitsee sisemmän operaation tulostaulusta Nimi-sarakkeen 6. Lauseketta on havainnollistettu kuvassa 3.9. 3.2.3 Uudelleennimeäminen ρ Edellä esiteltiin, miten relaatioita ja attribuutteja voidaan nimetä uudelleen asetuslausetta käyttäen. Toisinaan on kuitnekin kätevämpää käyttää uudelleennimeämisoperaatiota ρ, jonka avulla voidaan nimetä uudelleen sekä relaatioi- 6 Relaatio määriteltiin aiemmin kahden tai useamman joukon karteesisen tulon osajoukoksi, joten relaatiolla pitäisi periaatteessa olla vähintään kaksi attribuuttia. Relaatioalgebran kannalta yhden attribuutin relaatiot eivät kuitenkaan ole mikään ongelma. 16
Asiakas Id Etunimi Sukunimi 1 Orimatti Teuras 2 Laupias Psaltari 3 Hanhikki Hillosilmä Etunimi Orimatti Laupias Hanhikki Sukunimi Teuras Psaltari Hillosilmä Kuva 3.8: Operaation π Etunimi, Sukunimi (Asiakas) toiminta ja tulos. Tuote Id Nimi Kuvaus Hinta ToimittajaId 1 Hilavitkutin Laatuisa vitkutin 10.99 2 2 Vimpain Vimmattu vimpaaja 99.99 1 3 Masiina Tuotantoväline lisäarvon tuottamiseen 12.50 1 4 Jiirisaha Komea sähkötyökalu 0.99 2 Id Nimi Kuvaus Hinta ToimittajaId 1 Hilavitkutin Laatuisa vitkutin 10.99 2 2 Vimpain Vimmattu vimpaaja 99.99 1 3 Masiina Tuotantoväline lisäarvon tuottamiseen 12.50 1 Nimi Hilavitkutin Vimpain Masiina Kuva 3.9: Lausekkeen π Nimi (σ Hinta>10 (Tuote)) toiminta ja tulos. ta että attribuutteja 7. Yleisessä tapauksessa relaation Relaatio(Attr 1,...,Attr n ) uudelleen nimeävä operaatio on muotoa ρ Relaatio (Attr 1,...,Attr n ) (Relaatio), missä Relaatio on relaation Relaatio uusi nimi ja Attr 1,...,Attr n attribuuttien Attr 1,...,Attr n uudet nimet. Uudelleennimeämisoperaation sijasta on kuitenkin usein selkeämpää käyttää apurelaatiota, edellä esitetty uudelleennimeömisoperaatio kun vastaa seuraavaa lauseketta: Relaatio (Attr 1,...,Attr n) Relaatio(Attr 1,...,Attr n ). Esimerkiksi tapauksesta, jossa selkeyssyistä pitäisi ehkä käyttää apurelaatioita, käy hyvin vaikkapa seuraava kaikkien hilavitkutinta kalliimpien tuotteiden nimet valitseva lausekehirviö: π Nimi (σ NimiB= Hilavitkutin AND Hinta>HintaB (Tuote ρ TuoteB(NimiB, HintaB) (π Nimi, Hinta (Tuote)))). 7 SQL-kielessä uudelleennimeämistä vastaa AS-operaatio. 17
3.3 Liitosoperaatiot 3.3.1 Liitosoperaatio Edellä opittiin, miten karteesisen tulon avulla voidaan yhdistää tauluja siten, että jokaisen taulun jokainen rivi yhdistetään muiden taulujen jokaiseen riviin. Karteesista tuloa käytetään vain harvoin yksinään ja tulon tuloksena syntyvään relaatioon kohdistetaankin usein valintaoperaatio. Karteesinen tulo ja valinta σ voidaan yhdistää liitosoperaatioksi, joka on muotoa Relaatio 1 Ehto Relaatio2, missä Relaatio 1 ja Relaatio 2 ovat liitettävät relaatiot ja Ehto liitosehto. Liitosoperaatio vastaa tulon ja valinnan yhdistelmää seuraavasti: Relaatio 1 Ehto Relaatio2 = σ Ehto (Relaatio 1 Relaatio 2 ). Edellä esitettyä liitosoperaation sekä valinnan ja karteesisen tulon yhteyttä voidaan SQL-kielen yhteydessä käyttää hyväksi ns. alikyselyiden poistamisessa. Myös tietokantojen tehokkaan toiminnan kannalta operaatio on erittäin keskeinen, sillä tehokkaat kyselyoperaatiot edellyttävät tehokkaasti toteutettua liitosoperaatiota. Relaatioalgebran kannalta liitosoperaatiota voidaan kuitenkin pitää syntaktisena sokerina eli lyhennysmerkintänä, joka ei lisää kielen ilmaisukykyä, mutta helpottaa kirjoittamista. Esimerkiksi aiemmin esitetty lauseke σ ToimittajaId=Toimittaja.Id (Tuote Toimittaja), jonka toimintaa havainnollistettiin kuvassa 3.6, voidaan liitosoperaatiota käyttäen kirjoittaa hieman lyhyemmin Tuote ToimittajaId=Toimittaja.Id (Toimittaja). 3.3.2 Luonnollinen liitos * Myös luonnollista liitosta voidaan pitää eräänlaisena lyhennysmerkintänä. Kun liitosoperaatiossa käytetään liitosehtona yhtäsuuruutta = ja liitosehdossa vertaillaan samannimisten attribuuttien arvoja, voidaan liitosoperaation sijasta käyttää luonnollista liitosta. Liitos Relaatio 1 Relaatio1.Attribuutti=Relaatio2.Attribuutti Relaatio 2 eli liitos, jossa vertaillaan Relaatio 1 :n ja Relaatio 2 :n samannimisen attribuutin Attribuutti arvoja, voidaan siten kirjoittaa lyhyemmin luonnollisen liitoksen avulla seuraavasti: Relaatio 1 Relaatio 2. Usein luonnollinen liitos määritellään vielä siten, että toinen liitosattribuuteista poistetaan tulosrelaatiosta. Tietoahan tässä ei varsinaisesti menetetä, sillä luonnollisessa liitoksessa vertailuoperaationa toimii =, joten tulosrelaation liitosattribuutteja vastaavissa sarakkeissa on aina täsmälleen samat arvot. Lisäksi operaatio esitetään usein yleisempänä siten, että liitosehtona käytetään liitettävien relaatioiden kaikkien samannimisten attribuuttien yhtäsuuruutta. 18
Henkilö Id Etunimi Sukunimi OsastoId 1 Luikuri Lahtiranta 2 2 Orimatti Teuras 2 3 Laupias Psaltari NULL Osasto Id Nimi 1 Hallinto 2 Myynti Henkilö l OsastoId=Osasto.Id Osasto Henkilö.Id Etunimi Sukunimi OsastoId Osasto.Id Nimi 1 Luikuri Lahtiranta 2 2 Myynti 2 Orimatti Teuras 2 2 Myynti 3 Laupias Psaltari NULL NULL NULL Henkilö r OsastoId=Osasto.Id Osasto Henkilö.Id Etunimi Sukunimi OsastoId Osasto.Id Nimi NULL NULL NULL NULL 1 Hallinto 1 Luikuri Lahtiranta 2 2 Myynti 2 Orimatti Teuras 2 2 Myynti Henkilö lr OsastoId=Osasto.Id Osasto Henkilö.Id Etunimi Sukunimi OsastoId Osasto.Id Nimi 1 Luikuri Lahtiranta 2 2 Myynti 2 Orimatti Teuras 2 2 Myynti 3 Laupias Psaltari NULL NULL NULL NULL NULL NULL NULL 1 Hallinto Kuva 3.10: Esimerkki vasemmasta, oikeasta ja täydestä puoliliitoksesta. 3.3.3 Puoliliitokset Toisinaan on tarpeen säilyttää kaikki jomman kumman tai molempien liitokseen osallistuvien relaatioiden monikot. Tällaisia tilanteita varten relaatioalgebra sisältää vasemman puoliliitoksen l, oikean puoliliitoksen r sekä täyden puoliliitoksen lr. Esimerkiksi vasemman puoliliitoksen Relaatio 1 l Ehto Relaatio 2 tulos sisältää kaikki Relaatio 1 :n monikot liitettyinä niihin Relaatio 2 :n monikkoihin, jotka täyttävät liitosehdon Ehto. Jos Relaatio 1 :n monikkoa ei voida liittää yhteenkään Relaatio 2 :n monikkoon, täytetään puuttuvat arvot tuntemattomalla arvolla NULL. Kuvassa 3.10 on esitetty relaatiot Henkilö ja Osasto sekä näiden relaatioiden vasen, oikea ja täysi puoliliitos. Esimerkiksi kuvassa 3.10 esitetyn oikean puoliliitoksen käyttö tulee kyseeseen silloin, kun halutaan hakea ensinnäkin kaikki osastot sekä lisäksi osastoilla työskentelevät henkilöt, jos osastolla henkilöitä työskentelee. 3.4 Muut operaatiot 3.4.1 Jakolasku Jakolaskun voi ajatella olevan karteesisen tulon käänteisoperaatio, sillä jakolaskun tulosrelaation ja jakajarelaation karteesinen tulo sisältyy jaettavaan 19
Jaettava Attr1 Attr2 1 a 2 a 3 a 1 b 1 c 2 c 3 d Jakaja Attr1 1 2 Tulos Attr2 a c Kuva 3.11: Esimerkki jakolaskusta Tulos Jaettava Jakaja. relaatioon, kuten oikeastaan jakolaskussa yleensäkin. Yleisessä tapauksessa jakolasku on muotoa Relaatio 1 Relaatio 2. Jotta jakolasku olisi mielekäs, on Relaatio 2 :n eli jakajan attribuuttien sisällyttävä Relaatio 1 :n attribuuttien joukkoon. Jakolaskun tulos on kardinaliteetiltaan eli kooltaan suurin mahdollinen relaatio Relaatio 3, jolle Relaatio 1 Relaatio 2 Relaatio 3. Jakolaskun toimintaa on havainnollistettu kuvassa 3.11. Kannattaa huomata, että vaikka esimerkiksi {<1>,<2>} {<a>} sisältyy relaatioon Jaettava, ei joukko {<a>} kelpaa vastaukseksi, sillä siihen voidaan vielä lisätä <c>. Jakolasku Relaatio 1 Relaatio 2 voidaan aina esittää projektion π, karteesisen tulon sekä erotuksen avulla seuraavasti: Apu 1 π Tulosattr1,...,Tulosattr n (Relaatio 1 ) Apu 2 π Tulosattr1,...,Tulosattr n ((Relaatio 2 Apu 1 ) Relaatio 1 ) Tulos Apu 1 Apu 2, missä Tulosattr 1,...,Tulosattr n ovat sellaiset Relaatio 1 :n attribuutit, jotka eivät ole Relaatio 2 :n attribuutteja. 3.4.2 Aggregaattifunktiot Aggregaatti- eli koostefunktioiden avulla voidaan yhdistää useita monikkoja yhdeksi monikoksi. Meitä saattaisi esimerkiksi kiinnostaa kalleimman valikoimissamme olevan tuotteen hinta. Tällainen kysely voidaan muotoilla aggregaattifunktiota MAX käyttäen seuraavasti: F MAX(Hinta) (Tuote). Operaation tulos on esitetty kuvassa 3.12. Kannattaa huomata, että operaation tulos ei ole luku, vaan yhden rivin ja yhden sarakkeen relaatio. Yleisessä tapauksessa relaatioon kohdistuva aggregaattifunktio on muotoa F Funktio1(Attribuutti 1),...,Funktio n(attribuutti n)(relaatio), missä Attribuutti 1,...,Attribuutti n ovat Relaatio:n attribuutteja ja aggregaattifunktiot Funktio 1,...,Funktio n jotkin seuraavista: 20
MAX(Hinta) 99.99 Kuva 3.12: Operaation F MAX(Hinta) (Tuote) tulos. ToimittajaId MIN(Hinta) MAX(Hinta) 1 12.50 99.99 2 0.99 10.99 Kuva 3.13: Operaation ToimittajaId F MIN(Hinta), MAX(Hinta) (Tuote) tulos. 1. SUM(Attribuutti), joka laskee sarakkeen Attribuutti arvojen summan. Vaatimuksena on tietysti se, että attribuutin arvojoukko koostuu luvuista. 2. AVERAGE(Attribuutti), joka tietysti palauttaa sarakkeen keskiarvon. Attribuutti-sarakkeen on jälleen sisällettävä vain lukuja. 3. MAX(Attribuutti), joka palauttaa sarakkeen suurimman arvon. Attribuutin Attribuutti arvojen on tietenkin oltava vertailtavissa. 4. MIN(Attribuutti), joka palauttaa sarakkeen pienimmän arvon. Attribuutin Attribuutti arvojen on jälleen oltava vertailtavissa. 5. COUNT(Attribuutti), joka laskee attribuutin Attribuutti arvojen määrän. On ehkä syytä korostaa, että arvojen ei tarvitse olla erilaisia. Muista aggregaattifunktioista poiketen attribuutin ei tarvitse saada arvojaan lukujoukosta. Toisaalta meitä saattaisi myös kiinnostaa, mikä on halvimman ja kalleimman kunkin toimittajan toimittaman tuotteen hinta. Tällainen kysely voitaisiin muotoilla seuraavasti: ToimittajaId F MIN(Hinta), MAX(Hinta). Edellisessä kyselyssä ToimittajaId on ns. ryhmittelyattribuutti, eli attribuutti, jonka jokaiselle erilaiselle arvolle minimihinta lasketaan. Operaation tulos on esitetty kuvassa 3.13. Tulosrelaation attribuutit ovat siis ryhmittelyattribuutti ToimittajaId sekä MIN(Hinta). Koska ryhmittelyattribuutilla ToimittajaId on kaksi erilaista arvoa 1 ja 2, on tulosrelaatiossa kaksi riviä. Ensimmäisessä esimerkissämme ryhmittelyattribuuttia ei esiintynyt, joten tuloksena oli yhden monikon relaatio. Yleinen muoto ryhmittelyattribuutteja käyttävälle aggregaattifunktiolle on Ryhm 1,...,Ryhm n F Funktio1(Attribuutti 1),...,Funktio m(attribuutti m)(relaatio), missä Ryhm 1,...,Ryhm n ovat ryhmittelyattribuutit; funktio sekä attributit ovat kuten edellä. Tulosrelaatiossa esiintyvät ensin ryhmittelyattribuutit ja sitten funktioita vastaavat attribuutit. Aggregaattifunktioiden toiminta saattaa 21
vaikuttaa monimutkaiselta, mutta niiden kannattaa ajatella toimivan yksinkertaisesti siten, että ensin haetaan kaikki kohderelaatiossa esiintyvät ryhmittelyattribuuttien arvoyhdelmät, joista jokaiselle sitten lasketaan funktiolistan funktiot. Käyttäen aggregaattifunktiota, projektiota, tuloa sekä valintaa voimme esimerkiksi hakea Orimatin tilausten arvon seuraavasti: Masa(MId) π Id (σ Etunimi= Orimatti (Asiakas)) MasaTuote(TId) π TuoteId (σ AsiakasId=MId (Tilaus Masa)) Tulos(Arvo) F SUM(Hinta) (σ TId=TuoteId (MasaTuote Tuote)). 22
Luku 4 Tietokannan suunnittelu Tässä luvussa perehdytään tietokantojen suunnitteluun. Pääpaino on käsitteellisessä mallintamisessa, ja valtaosa luvusta käsitteleekin ERmallinnusta. Kannattaa muistaa, että käytännössä tietokantaa suunnitellaan usein samaan aikaan tietokantaa käyttävän tietojärjestelmän kanssa, joten tietojärjestelmien kehittämisen ja ohjelmistotuotannon menetelmien yleinen hallinta on tarpeen myös tietokantaa suunniteltaessa. 4.1 Suunnittelusta yleisesti 4.1.1 Hyvän tietokannan tunnusmerkit Suunnittelun tavoittena on tietysti laadukas tietokanta, jolle asetetaan usein seuraavat, varsin ilmeiset vaatimukset: 1. Tietokannan on sisällettävä käyttäjien tarvitsema tieto. 2. Tietokannan on oltava rakenteeltaan selkeä ja helppo ylläpitää. Ylläpidettävyyden vaatimuksesta seuraa myös se, että tietokanta on dokumentoitava huolellisesti. 3. Tietokannan on oltava tehokas. Tässä yhteydessä tehokkuudella tarkoitetaan sekä nopeita tietokantaoperaatioita että pientä tilankulutusta. Nykyiset kiintolevyt ovat tosin niin halpoja, että tietokannan suuruus muodostuu ongelmaksi vain harvoin. Vaikka vaatimukset - ehkä tietokannan dokumentointia lukuunottamatta - ovatkin oikeastaan itsestään selviä, on varsinkin vaatimusten 1 ja 2 täyttymistä vaikeaa mitata. Lisäksi jotkin edellä mainituista tavoitteista ovat toistensa kanssa vastakkaisia. Esimerkiksi tallennustilan minimointi saattaa johtaa hitaampiin tietokantaoperaatioihin ja päinvastoin. Samalla tavoin rakenteeltaan selkeä ja helposti ylläpidettävä tietokanta voi olla tehoton. 23
4.1.2 Tietokantaprojektin vaiheet Vaatimusten kerääminen ja analysointi Ennen tietokannan suunnittelua on tietysti syytä selvittää tietokannan käyttäjien nykyiset ja tulevat tarpeet. Tätä suunnittelun vaihetta kutsutaan vaatimusten keräämiseksi ja analysoinniksi. Tarkoituksena on tuottaa erilaisia kuvauksia organisaation toiminnasta ja tietotarpeista 1. Vaatimusten keräämiseen liittyvät yleensä seuraavat toiminnot: 1. Vaatimusten keräämiseksi on tunnistettava ne sovellukset ja käyttäjäryhmät, jotka tulevaa tietokantaa käyttävät. Jokaisesta ryhmästä valitaan yleensä edustaja, joka osallistuu vaatimusten keräämiseen sekä myöhemmin myös tietokannan suunnitteluun. 2. Muu organisaation liittyvä materiaali, kuten esimerkiksi erilaiset raportit ja organisaatiokaaviot, tutkitaan huolellisesti, sillä ne saattavat kertoa organisaatiosta kokonaisuutena jotakin sellaista, mitä yksittäiset käyttäjät eivät tule ajatelleeksi. 3. On myös syytä pohtia, millaisia operaatioita ja miten usein suunniteltavaan tietokantaan kohdistuu. Saattaa nimittäin olla, että kaikkia käyttäjien tietokantaan kohdistamia odotuksia ei voida täyttää projektiin varatuilla resursseilla. Tällöin vaatimuksia on syytä rukata realistisemmiksi mahdollisimman aikaisessa vaiheessa. 4. Kerättyä informaatiota saatetaan joutua täydentämään esimerkiksi käyttäjähaastatteluiden avulla. Haastatteluiden avulla voidaan esimerkiksi selvittää, miten tärkeinä käyttäjät pitävät eri ominaisuuksia. Kerätyt vaatimukset ovat käytännössä aina epätarkkoja ja usein myös virheellisiä tai ainakin ristiriitaisia. Näistä syistä vaatimusten kerääminen ja tallentaminen on suunniteltava tarkoin. Saatamme esimerkiksi toteutusvaiheessa törmätä määrittelyyn, jota pitäisi tarkentaa. Jos vaatimustenhallinta on järjestetty hyvin, voimme selvittää, kenen pyynnöstä kyseistä ominaisuutta ollaan toteuttamassa ja esittää tarkentavia lisäkysymyksiä kyseiselle käyttäjälle. Oman ongelmansa muodostaa myös käyttäjien kanssa kommunikointi, sillä käyttäjät harvoin ovat IT-alan ammattilaisia ja IT-alan ammattilaiset harvoin ovat vaikkapa pankinjohtajia tai pankkitoimihenkilöitä. Vaatimusten keräämiseen ja analysointiin on syytä paneutua huolellisesti, sillä kaikki myöhemmät suunnitteluvaiheet perustuvat juuri tämän vaiheen tuloksiin. Jos tietokanta suunnitellaan vääriä vaatimuksia vastaavaksi, ratkaistaan tietysti vain vääriä ongelmia ja tuhlataan resursseja. Myöhemmissä suunnitteluvaiheissa tehtyjen virheiden - kuten esimerkiksi pienten bugien tai tietokantakaavan puutteiden - korjaaminen taas on huomattavasti helpompaa ja halvempaa. 1 Vaikka esimerkiksi toimintaa kuvaavat prosessikaaviot eivät ehkä olisikaan tietokannan suunnittelun kannalta keskeisiä, kehitetään tietokannan ohella usein myös tietokantaa käyttävää tietojärjestelmää, mikä tietysti vaatii prosessien analysointia. 24
Käsitteellinen suunnittelu Käsitteellisestä sunnittelusta voidaan erottaa seuraavat kaksi osa-aluetta: 1. Käsitteellisen mallintamisen tavoittena on tuottaa aiemmin kerättyjä vaatimuksia mahdollisimman hyvin vastaava käsitteellinen tietomalli, joka kuvaa tallennettavan tiedon rakennetta ja tiedon osasten välisiä suhteita. 2. Tietokantaoperaatioiden suunnittelu on syytä yhdistää käsitteelliseen mallintamiseen, sillä se saattaa auttaa erottamaan oleellisen tiedon epäoleellisesta. Tietokantaoperaatiot suunnitellaan tietysti aiemmin kerättyjen vaatimusten perusteella, joten kyse on oikeastaan käyttäjien analysoinnista eli samasta asiasta kuin vaatimuksia kerättäessä. Tietokantaoperaatioiksi muotoiltuina vaatimukset ovat kuitenkin huomattavasti konkreettisempia kuin vaikkapa toiminnan sanalliset kuvaukset. Tietokantojen käsitteellisessä mallintamisessa käytetään useimmiten ns. ER-mallinnusta, johon perehdytään tarkemmin kohdassa 4.2. Jos eri käyttäjäryhmien vaatimukset on sovitettu yhteen jo vaatimuksia kerättäessä ja analysoitaessa, on käsitteellinen suunnittelu yleensä helpompaa. Useimmiten ristiriitaisia vaatimuksia kuitenkin joudutaan sovittamaan yhteen myös käsitteellisen mallintamisen yhteydessä. Juuri tämän vuoksi eri käyttäjäryhmien edustajien osallistuminen suunnitteluun on tarpeen. Tietokannanhallintajärjestelmän valitseminen Seuraava vaihe on useimmiten tietokannanhallintajärjestelmän valitseminen, joka joissakin tietokantaprojekteissa saattaa toisinaan näytellä suurtakin osaa. Huomioon otettavia seikkoja ovat esimerkiksi tietokantaohjelmiston hinta ja tehokkuus, olemassaolevan palvelinlaitteiston sopivuus valittavalle tietokannanhallintajärjestelmälle sekä mahdollisesti tarvittavan koulutuksen kustannukset. Lisäksi on selvitettävä, millaisia ohjelmointityökaluja valittavalle tietokannanhallintajärjestelmälle on saatavilla. Toisinaan tietokannanhallintajärjestelmän valinnan saattavat ratkaista myös tietyn tietokantaohjelmiston tarjoamat ylimääräiset ominaisuudet. Kaikkein eksoottisimpiin tuoteominaisuuksiin turvautuminen ei kuitenkaan ole suositeltavaa, sillä tietokanta saatetaan myöhemmin syystä tai toisesta joutua siirtämään toiseen tietokannanhallintajärjestelmään, joka ei tuekaan kaikkia käytettyjä ominaisuuksia. Tietokantakaavan suunnittelu Kun tietokannanhallintajärjestelmä on valittu, on seuraavaksi suunniteltava tietokantakaava. Tämän suunnitteluvaiheen tuloksena on joukko relaatiokaavoja tai vielä konkreettisemmin joukko SQL-lauseita, joiden avulla voidaan luoda kaavoja vastaava tietokanta. Periaatteessa ER-mallin muuntaminen tietokantakaavaksi on suoraviivaista, mutta esimerkiksi tehokkuussyistä joudutaan tietokantakaavaan toisinaan lisäämään joitakin relaatioita. Lisäksi valitun tietokannanhallintajärjestelmän tarjoamat erityisominaisuudet saattavat vaikuttaa tietokantakaavaan. Myös tähän vaiheeseen perehdytään tarkemmin kohdassa 4.2. 25
Toteuttaminen Tietokantakaavan suunnittelua seuraa toteutusvaihe eli taulujen ja hakemistojen eli tietokantahakuja nopeuttavien rakenteiden luominen. Toisaalta hakemistot taas useimmiten hidastavat päivitysoperaatioita, joten hakemistoja suunniteltaessa on syytä käyttää hyväksi käsitteellisen suunnittelun yhteydessä listattuja tietokantaoperaatioita. Samalla tavoin tietokantaoperaatioita on syytä käyttää hyväksi myös silloin, kun pohditaan, miten relaatioiden monikot fyysisesti kiintolevylle järjestetään. Vaikka relaatiomalli nimittäin tarkasteleekin relaatioita järjestämättömänä joukkona monikoita, on monikoiden fyysisellä järjestyksellä toisinaan hyvinkin suuri merkitys. Toteutusvaiheen tuloksena syntyvä tietokanta on harvoin täydellinen ja sitä joudutaankin usein muokkaamaan. Käyttöönotto ja ylläpito Siinä, missä edelliset suunnitteluvaiheet ovat ennen kaikkea ohjelmistosuunnittelijoiden ja projektipäällkäiden vastuulla, on päävastuu viimeisestä vaiheesta eli tietokannan käyttöönotosta ja ylläpidosta useimmiten DBA:n eli tietokannasta vastaavan henkilön 2. Tässä vaiheessa esimerkiksi siirretään data vanhasta tietokannasta uuteen, luodaan käyttäjät ja jaetaan heille oikeudet. Ennen tietokannan lopullista käyttöönottoa on vielä tietysti testattava tietokantaa käyttävä ohjelmisto. Kun ohjelmisto on todettu riittävän toimivaksi, se otetaan käyttöön. Käyttöönoton jälkeistä vaihetta kutsutaan ylläpitovaiheeksi ja se jatkuu käytännössä tietokannan olemassaolon ajan. Useimmat tietokannanhallintajärjestelmät tarjoavat tilastotietoa tietokantaan kohdistuneista tietokantaoperaatioista. Tämän tiedon avulla tietokantaa voidaan virittää tehokkaammaksi. Jos tietokannan parantelu ei ole mahdollista, voidaan toisinaan toisinaan tietysti viritellä myös tietokantaoperaatioita. Käyttäjien vaatimuksetkin saattavat muuttua. Tällöin on syytä pohtia, miten nämä vaatimukset on helpointa ja halvinta täyttää. Ideaalitilanteessa vaatimusten muutokset on pystytty ainakin osittain ennustamaan jo vaatimuksia ja organisaation toimintaympäristöä analysoitaessa, mikä luonnollisesti helpottaa muutoksiin reagoimista. 4.2 ER-mallinnus Tässä osassa käsitellään ER-mallinnusta, joka nykyisin lienee käytetyin tietokantojen käsitteellisen mallintamisen menetelmä. Oikeaoppisessa ERmallinnuksessa erotetaan toisistaan esimerkiksi vahvat ja heikot entiteetit - jälkimmäisessä tapauksessa entiteetin olemassaolo riippuu muiden entiteettien olemassaolosta - sekä atomaariset ja koosteiset attribuutit. Koska näiden erojen merkitys kuitenkin on käytännön tietokantasuunnittelun kannalta pieni, esitellään tässä osassa vain ER-mallinnuksen perusteet. Lukijan, joka haluaa perehtyä ER-mallintamiseen tarkemmin, kannattaa perehtyä Ramez Elmasrin ja Shamkant B. Navathen tietokantoja käsittelevään perusteokseen Fundamentals of Database Systems [3]. 2 DBA on lyhennys sanoista Database Administrator. 26
Kuva 4.1: Kuvan 2.3 tauluja Asiakas ja Tuote vastaavat entiteetit. Kuva 4.2: Kuvan 4.1 entiteetit sekä niiden välinen liittymä. 4.2.1 Perusrakenteet ER-mallinnus [4] perustuu tiedon kuvaamiseen entiteettien eli kohteiden ja entiteettien välisten suhteiden eli liittymien avulla. Tietokeskeisenä mallinnusmenetelmänä ER-mallinnus sopii tietokantojen mallintamiseen erityisen hyvin, sillä eräs tietokanta-ajattelun perusteista on tiedon ja tiedon käytön erottaminen toisistaan. Mallinnettavan tiedon käyttötarkoituksen kannalta oleellisia entiteetin ominaisuuksia kutsutaan attribuuteiksi. Esimerkiksi auton attribuutteja voisivat olla rekisterinumero, merkki, malli, vuosimalli jne. Opiskelijan attribuutteja taas voisivat olla vaikkapa opiskelijanumero, nimi, osoite ja puhelinnumero. Kuvassa 4.1 on esitetty kuvan 2.3 tauluja Asiakas ja Tuote vastaavat entiteetit attribuutteineen. Nimensä mukaisesti liittymät liittävät entiteettejä toisiinsa. Esimerkkimme entiteetit Asiakas ja Tuote liittyvät toisiinsa siten, että asiakkaat tilaavat tuotteita. Niinpä nämä entiteetit on kuvassa 4.2 yhdistetty toisiinsa Tilaus-liittymän avulla. Liittymän yhteydessä kuvataan myös entiteettien lukumääräsuhteet. Koska yksi asiakas voi tilata monta tuotetta ja koska yhden tuotteen voi tilata moni asiakas, on kyseessä ns. monta moneen -liittymä, jota ER-kaaviossa merkitään lukumääräsuhteilla N:M. Kuvan 4.2 ER-kaavion voi siis tulkita kutakuinkin siten, että yksi asiakas liittyy moneen tuotteeseen ja yksi tuote liittyy moneen asiakkaaseen tai yksi asiakas voi tilata monta tuotetta ja yhtä tuotetta voi tilata moni asiakas. Kuvan 2.3 esimerkkitietokannassa Tuote ja Toimittaja taas liittyivät toisiinsa hieman toisella tavalla. Oletimme, että yksi toimittaja voi toimittaa montaa tuotetta, mutta yhtä tuotetta voi toimittaa vain yksi toimittaja, joten kyseessä ei selvästikään ole monta moneen -liittymä. Nyt kyseessä onkin ns. yksi 27
Kuva 4.3: Kuvan 2.3 tietokantaa vastaava ER-kaavio. moneen -liittymä, jota kuvan 4.3 ER-mallissa on merkitty lukumääräsuhteilla 1:N. Tarkkasilmäinen lukija saattaa huomata, ettei entiteetissä Tuote esiinny relaatiossa Tuote esiintyvää attribuuttia ToimittajaId, mutta kyse ei ole virheestä. Asia selviää monisteen seuraavassa osassa. Entiteettien Tuote ja Toimittaja liittymä voidaan nyt tulkita siten, että yksi toimittaja liittyy moneen tuotteeseen ja yksi tuote liittyy vain yhteen toimittajaan. Liittymiä, joiden lukumääräsuhteet ovat 1:1, ei oikeastaan pitäisi esiintyä, sillä tällöin entiteetit pitäisi olla mahdollista yhdistää. On ehkä myös syytä huomauttaa, että liittymä voi yhdistää mielivaltaisen määrän entiteettejä. Tämä tarkoittaa myös sitä, että entiteetti saattaa liittyä myös itseensä. Aiemmin esittelimme relaation Työntekijä(Id, Etunimi, Sukunimi, EsimiesId), jossa EsimiesId oli saman relaation attribuuttiin Id viittaava vierasavain. Tällaista tilannetta kuvaavassa ER-kaaviossa entiteetti Työntekijä voitaisiin liittää itseensä Johtaa-nimisellä liittymällä. Lisäksi kahden entiteetin välillä saattaa olla useampia liittymiä. Esimerkkikaavioomme voitaisiin entiteettien Asiakas ja Tuote välille lisätä Suosittelee-liittymä, joka liittää asiakkaan hänen suosittelemaansa tuotteeseen. Ylipäätään on helpointa ensin tunnistaa ilmeisiä entiteettejä, kuten esimerkiksi Asiakas, Tuote, Kurssi, Auto ja Opiskelija, ja vasta sen jälkeen ruveta pohtimaan, millaisia entiteettejä ERmallista mahdollisesti puuttuu ja miten entiteetit toisiinsa liittyvät. 4.2.2 ER-mallista relaatioihin Eräs ER-mallinnuksen eduista on se, että ER-mallin muuntaminen relaatiokaavoiksi on periaatteessa hyvin suoraviivaista. ER-mallin käsitteille eli entiteeteille, attribuuteille sekä erilaisille liittymille on kullekin nimittäin olemassa vastineensa relaatiomallissa: 1. Jokaista entiteettiä vastaa relaatio, jolla on tietysti samat 28
attribuutit kuin vastaavalla entiteetillä. Esimerkkitapauksessamme Asiakas-entiteetti muunnetaan siten Asiakas-relaatioksi, jolla on avainattribuutti Id sekä attribuutit Etunimi ja Sukunimi. 2. Jokaista 1:N-liittymää vastaa viitevain siten, että N-puolen entiteettiä vastaavaan relaatioon lisätään vierasavainattribuutti, joka viittaa 1-puolen entiteetin pääavaimeen. Tuote-relaatioon lisätään siten viiteavainattribuutti ToimittajaId, joka viittaa Toimittaja-taulun pääavaimeen Id. 3. Jokaista N:M-liittymää vastaa relaatio, jonka attribuutteja ovat liittymään liittyvien entiteettien avainattibuutit. Esimerkkitapauksessamme Tilaus-relaatio vastaa Tilaus-liittymää ja sen attribuutteina ovat Asiakas-tauluun viittaava AsiakasId ja Tuote-tauluun viittaava TuoteId. Monta moneen -liittymää vastaavan relaation pääavaimena toimii viiteavainten yhdistelmä. Näitä sääntöjä käyttäen voidaan kuvan 4.3 ER-kaavio muuttaa luvussa 2 käsitellyksi tietokantakaavaksi. 4.2.3 Tavallisimpia virheitä Erityisen tavallinen ja oikeastaan myös vakavin virhe on se, että tiedon osasten ja niiden välisten suhteiden kuvailemisen sijasta pyritään virheellisesti mallintamaan toimintaa tai prosesseja. ER-mallinnus on kuitenkin tietokeskeinen menetelmä, joten sen avulla pyritään mallintamaan vain tiedon rakennetta eikä toimintaa. Prosessien ja toiminnan mallintamiseen on olemassa muita menetelmiä, kuten esimerkiksi tietovuokaaviot. Ylipäätäänkin liiaksi organisaation toimintaan perustuva tietokanta on usein hyvin lyhytikäinen, koska prosesseilla - siis tiedon käyttötavalla - on tapana muuttua tiedon rakennetta nopeammin. Tiedon pysyvyydestä vakuuttuakseen voi miettiä vaikkapa sitä, että yrityksen ryhtyessä myymään tuotteitaan Internetissä yrityksen toiminnot saattavat muuttua huomattavastikin, mistä syystä yrityksen on hankittava esimerkiksi uusia ohjelmistoja, palkattava uusia työntekijöitä ja ehkä myös muutettava toimintatapojaan. Yrityksen tietokannan rakenne taas saattaa pysyä hyvinkin muuttumattomana eli kokoelmana tietoa asiakkaista, tuotteista, tilauksista jne. Tiedon rakenteen ja tietoalkioiden välisten suhteiden pysyvyys onkin oikeastaan koko tietokanta-ajattelun ja tietokantojen nykyisen suosion perusta. Toinen tyypillinen virhe on se, että ER-malliin lisätään viittauksiin liittyviä attribuutteja. Nämä eivät kuitenkaan ole tarpeen, sillä viiteavainattribuutit vastaavat liittymiä, minkä edellisessä osassa jo opimme. Kolmas virhe on erilaisten listojen tai joukkojen mallintaminen. Esimerkkikaaviossamme olisimme saattaneet yrittää mallintaa tuotelistaa tai tilauslistaa, vaikka taulu on oikeastaan monikkojen joukko ja toimii siten listaa vastaavasti 3. Virhe ei kuitenkaan yleensä ole kovin vakava, koska sen korjaaminen siirryttäessä ER-mallista relaatioihin on suhteellisen helppoa. Neljäs tyypillinen virhe on liian rajoittuneen mallin luominen. Esimerkkitapauksessamme olemme olettaneet, että yhtä tuotetta toimittaa 3 Relaatio ei tarkasti ottaen ole lista, sillä relaation monikoilla ei ole keskinäistä järjestystä. 29
vain yksi toimittaja 4. Vaikka näin tietokantaa suunniteltaessa olisikin, saattaa asia myöhemmin muuttua. ER-mallissa on tämä tarkoittaa yksi moneen -liittymän korvaamista monta moneen -liittymällä ja tietokantakaavassa uuden relaation luomista sekä yhden viiteavainattribuutin poistamista. Hölmönpuoleinen suunnittelija tai DBA saattaisi kuitenkin harkita uuden attribuutin Toimittaja2 lisäämistä Tuote-relaatioon. Tämä ei kuitenkaan ole oikea ratkaisu, sillä se vaikeuttaa kyselyiden kirjoittamista. Lisäksi uuden attribuutin lisääminen ratkaisisi ongelman vain väliaikaisesti, sillä tuotteella saattaa myöhemmin alkaa toimittaa kolmas toimittaja. Tästä huolimatta tällaisiin viritelmiin törmää valitettavan usein. 4 Esimerkkititokantamme on muutenkin kovin rajoittunut, sillä esimerkiksi asiakkaista tai toimittajista ei pidetä yllä yhteystietoja. Relaatio Tilaus on myös vajaa, sillä relaation avulla ei voida tallentaa tietoa siitä, millä hinnalla tuote on tilattu tai siitä, onko tilaus jo toimitettu. 30