Luku 5

Lisää suunnittelusta

Tässä luvussa esitellyt periaatteet ovat hyödyllisiä ja johtavat usein toimiviin ratkaisuihin, mutta vielä tärkeämpää on käyttää omaa järkeä. Tavoitteen tulisi olla aina se, että tietokanta on käyttötarkoitukseen sopiva, eikä että noudatetaan periaatteita ilman omaa ajattelua.

Esimerkki 1

Sarakkeessa tulisi olla vain yksittäinen tieto, joten onko seuraava taulu huonosti suunniteltu, koska samassa sarakkeessa on etu- ja sukunimi?

sqlite> SELECT * FROM Kayttajat;
id          nimi         
----------  --------------
1           Anna Virtanen
2           Maija Korhonen
3           Pasi Lahtinen

Voisimme myös tallentaa etu- ja sukunimen erikseen näin:

sqlite> SELECT * FROM Kayttajat;
id          etunimi     sukunimi  
----------  ----------  ----------
1           Anna        Virtanen
2           Maija       Korhonen
3           Pasi        Lahtinen

Riippuu tilanteesta, kumpi taulu on parempi. Jos järjestelmässä on erityisesti tarvetta etsiä tietoa etu- tai sukunimen perusteella (esimerkiksi etsiä kaikki käyttäjät, joiden etunimi on Anna), jälkimmäinen taulu voi olla parempi. Kuitenkaan usein ei ole näin eikä ole mitään pahaa tallentaa samaan sarakkeeseen etu- ja sukunimi.

Esimerkki 2

Seuraavassa taulussa näyttää olevan toisteista tietoa: kaksi kertaa sama viesti "Hei!". Pitäisikö tietokannan rakennetta parantaa?

SELECT * FROM Viestit;
id          kayttaja_id  viesti
----------  -----------  --------------
1           1            Hei!
2           2            Hei!
3           1            Missä olet?
4           2            Bussissa

Tässä tapauksessa ei olisi hyvä idea toteuttaa tietokantaa niin, että jos kaksi käyttäjää lähettää saman sisältöisen viestin, viestin sisältö tallennetaan vain yhteen paikkaan.

Vaikka viesteissä on sama sisältö, ne ovat erillisiä viestejä. Jos käyttäjä 1 muuttaa viestin sisältöä, muutoksen ei ole tarkoitus heijastua käyttäjän 2 viestiin, vaikka siinä sattuu olemaan sama sisältö.

Esimerkki 3

Yliopiston kurssijärjestelmällä on kahdenlaisia käyttäjiä: opettajia ja opiskelijoita. Kannattaako tehdä yksi yhteinen taulu kaikille käyttäjille vai eri taulut opettajille ja opiskelijoille?

Tämä vastaa olio-ohjelmoinnissa tilannetta, jossa voisimme käyttää rajapintoja tai periytymistä, mutta SQL:ssä ei ole tarjolla tällaisia tekniikoita.

Kokemus on osoittanut, että hyvä ratkaisu on tallentaa kaikki käyttäjät samaan tauluun. Tauluun tarvitaan jokin sarake, joka ilmaisee käyttäjän roolin. Esimerkiksi voimme sopia, että rooli 1 tarkoittaa opettajaa ja rooli 2 tarkoittaa opiskelijaa. Esimerkiksi seuraava kysely hakee tiedot opettajista:

SELECT * FROM Kayttajat WHERE rooli=1;

Syynä tähän ratkaisuun on, että järjestelmässä on kuitenkin paikkoja, jotka ovat käyttäjille yhteisiä, ja olisi vaivalloista alkaa tehdä eri SQL-komentoja opettajia ja opiskelijoita varten näissä paikoissa.

Kun järjestelmä kehittyy, siihen saattaa tulla lisää rooleja, ja on myös mahdollista, että käyttäjällä on monta roolia (esimerkiksi käyttäjä voi olla samaan aikaan opiskelija ja opettaja). Tällöin voi olla hyvä idea luoda uusi taulu, joka kertoo, mitä eri rooleja kullakin käyttäjällä on.

Esimerkki 4

Seuraavassa taulussa ei ole vielä mitään ongelmaa:

sqlite> SELECT * FROM Kurssit;
id          nimi           op          kuvaus    
----------  -------------  ----------  ----------
1           Ohjelmointi 1  5           ...       
2           Ohjelmointi 2  5           ...       
3           Tietokannat    10          ...       

Mutta kun järjestelmä kasvaa, niin tauluun voi alkaa ilmestyä lisää ja lisää sarakkeita sekalaista tietoa (kuten kurssin oppiaine, kirjallisuus, suoritustavat, jne.). Taulu voi alkaa tuntua sekavalta, jos siinä on suuri määrä sarakkeita.

Yksi vaihtoehto olisi rakentaa taulu niin, että siinä onkin vain kiinteä määrä sarakkeita:

sqlite> SELECT * FROM Kurssit;
id          avain       arvo
----------  ----------  -------------
1           nimi        Ohjelmointi 1
1           op          5
1           kuvaus      ...
2           nimi        Ohjelmointi 2
2           op          5
2           kuvaus      ...
3           nimi        Tietokannat
3           op          10
3           kuvaus      ...

Tämän ratkaisun etuna on, että voimme vapaasti lisätä uusia avaimia muuttamatta taulun rakennetta. Lisäksi jos jokin avain on käytössä vain harvoin, siihen ei tarvitse ottaa kantaa jokaisen kurssin kohdalla.

Ratkaisussa on kuitenkin omat ongelmansa: kaikilla arvoilla on sama tyyppi (käytännössä niiden täytyy olla merkkijonoja) ja tietyn kurssin tietojen etsiminen on vaikeampaa kuin aiemmin. Kuitenkin jos sarakkeiden määrä uhkaa paisua hankalan suureksi, tämä ratkaisu voi olla pelastava enkeli.