Luku 7

Toisteinen tieto

Ihanteena tietokannan suunnittelussa on, että tauluissa ei ole toisteista tietoa, jonka voi päätellä tietokannan muusta sisällöstä. Välillä kuitenkin tästä periaatteesta kannattaa joustaa, jotta saamme tehostettua kyselyitä.

Esimerkki

Tarkastellaan pankin tietokantaa, jossa taulu Tapahtumat sisältää tiedot tilitapahtumista. Jokaiseen tapahtumaan liittyy sarake muutos, joka ilmaisee, paljonko tilin saldo muuttuu (muutos voi olla positiivinen tai negatiivinen).

Seuraava kysely ilmoittaa tilin 123 nykyisen saldon laskemalla yhteen kaikki tiliin liittyvät muutokset:

SELECT SUM(muutos) FROM Tapahtumat WHERE tili_id=123;

Tämä on sinänsä mainio kysely, mutta se joutuu käymään läpi kaikki tiliin 123 liittyvät rivit taulusta Tapahtumat saadakseen selville lopullisen saldon. Tämä on tavallaan turhaa työtä, koska meitä ei kiinnosta tilin historia vaan vain saldo.

Voimmekin tehostaa kyselyä luomalla uuden taulun Saldot, joka sisältää jokaisen tilin saldon. Tämän taulun avulla saamme haettua tilin 123 saldon näin helposti:

SELECT saldo FROM Saldot FROM tili_id=123;

Tässä rikomme periaatetta, jonka mukaan tietokannassa ei saa olla muista tiedoista laskettavissa olevaa tietoa, koska taulun Saldot rivit olisi mahdollista laskea taulun Tapahtumat sisällön perusteella. Saamme kuitenkin näin aikaan tehokkaamman kyselyn.

Mitä haittaa periaatteen rikkomisesta on? Lähinnä se, että meidän on tästä lähtien hankalampaa päivittää tietokantaa. Aina kun lisäämme uuden tapahtuman tauluun Tapahtumat, meidän täytyy lisäksi tehdä muutos tauluun Saldot. Aiemmin saldo laskettiin suoraan tilitapahtumista, minkä ansiosta se oli varmasti aina ajan tasalla.

Muutokset vs. kyselyt

Usein esiintyvä ilmiö tietojenkäsittelytieteessä on, että joudumme tasapainoilemaan sen kanssa, haluammeko muuttaa vai hakea tehokkaasti tietoa ja paljonko tilaa voimme käyttää. Tämä tulee tietokantojen lisäksi vastaan esimerkiksi algoritmien suunnittelussa.

Jos tietokannassa ei ole toisteista tietoa, muutokset ovat helppoja, koska jokainen tieto on vain yhdessä paikassa eli riittää muuttaa vain yhden taulun yhtä riviä. Myös hyvänä puolena tietokanta vie vähän tilaa. Toisaalta kyselyt voivat olla monimutkaisia ja hitaita, koska halutut tiedot pitää kerätä kasaan eri puolilta tietokantaa.

Kun sitten lisäämme toisteista tietoa, pystymme nopeuttamaan kyselyjä mutta toisaalta muutokset hidastuvat, koska muutettu tieto pitää päivittää useaan paikkaan. Samaan aikaan myös tietokannan tilankäyttö kasvaa toisteisen tiedon takia.

Ei ole mitään yleistä sääntöä, paljonko toisteista tietoa kannattaa lisätä, vaan tämä riippuu tietokannan sisällöstä ja halutuista kyselyistä. Yksi hyvä tapa on aloittaa tilanteesta, jossa toisteista tietoa ei ole, ja lisätä sitten toisteista tietoa tarvittaessa, jos osoittautuu, että kyselyt eivät muuten ole riittävän tehokkaita.

Huomaa, että indeksit ovat myös yksi esimerkki siitä, miten toisteinen tieto voi tehostaa kyselyjä. Niissä kuitenkaan toisteista tietoa ei tallenneta tauluun vaan taulun ulkopuolelle erilliseen hakemistorakenteeseen.