Luku 5

Tietokannan rakenne

Tietokannan suunnittelussa meidän tulee päättää tietokannan rakenne: mitä tauluja tietokannassa on sekä mitä sarakkeita kussakin taulussa on. Tähän on sinänsä suuri määrä mahdollisuuksia, mutta tuntemalla muutaman periaatteen ja maalaisjärjellä pärjää pitkälle.

Hyvä tavoite suunnittelussa on, että tuloksena olevaa tietokantaa on mukavaa käyttää SQL-kielen avulla. Tietokannan rakenteen tulisi olla sellainen, että pystymme hakemaan ja muuttamaan tietoa näppärästi SQL-komennoilla.

Taulu vs. luokka

Tietokannan taulu ja olio-ohjelmoinnin luokka ovat samantapaisia käsitteitä. Molemmissa on kyse siitä, että määrittelemme tiedon tyypin. Esimerkiksi seuraava SQL-komento ja Java-koodi vastaavat toisiaan:

CREATE TABLE Elokuvat (id INTEGER PRIMARY KEY, nimi TEXT, vuosi INTEGER);
public class Elokuva {
	private String nimi;
	private int vuosi;

	public Elokuva(String nimi, int vuosi) {
	    this.nimi = nimi;
	    this.vuosi = vuosi;
	}
}

Vastaavasti rivin lisääminen tietokannan tauluun ja olion luominen luokasta toimivat samalla periaatteella. Esimerkiksi voimme lisätä kolme riviä ja luoda kolme oliota seuraavasti:

INSERT INTO Elokuvat (nimi,vuosi) VALUES ('Lumikki',1937);
INSERT INTO Elokuvat (nimi,vuosi) VALUES ('Fantasia',1940);
INSERT INTO Elokuvat (nimi,vuosi) VALUES ('Pinocchio',1940);
Elokuva a = new Elokuva("Lumikki",1937);
Elokuva b = new Elokuva("Fantasia",1940);
Elokuva c = new Elokuva("Pinocchio",1940);

Huomaa, että ohjelmoinnissa luokissa ei ole tarvetta id-kentälle, koska voimme viitata muutenkin luokasta luotuihin olioihin. Esimerkiksi yllä olevassa koodissa muuttujat a, b ja c sisältävät viittaukset olioihin.

Yksi vai useita tauluja?

Periaatteena tietokannan suunnittelussa on, että kaikki saman tyyppiset rivit ovat yhdessä taulussa. Tämän ansiosta voimme käsitellä rivejä kätevästi SQL-komennoilla.

Esimerkiksi jos tietokannassa on elokuvia, hyvä ratkaisu on tallentaa kaikki elokuvat samaan tauluun:

sqlite> SELECT * FROM Elokuvat;
id          nimi        vuosi     
----------  ----------  ----------
1           Lumikki     1937      
2           Fantasia    1940      
3           Pinocchio   1940      
4           Dumbo       1941      
5           Bambi       1942    

Tästä taulusta voimme hakea esimerkiksi vuoden 1940 elokuvat näin:

SELECT nimi FROM Elokuvat WHERE vuosi=1940;

Mutta mitä kävisi, jos jakaisimmekin elokuvat moneen tauluun? Esimerkiksi voisimme jakaa elokuvat tauluihin vuosien mukaan. Tällöin taulussa Elokuvat1940 olisi vuoden 1940 elokuvat, ja voisimme hakea ne näin:

SELECT nimi FROM Elokuvat1940;

Tällainen ratkaisu toimii niin kauan, kuin haluamme hakea vain tietyn vuoden elokuvia. Kuitenkin tietokanta muuttuu vaikeakäyttöiseksi heti, jos haluamme tehdä jotain muita hakuja. Esimerkiksi jos haluamme hakea kaikki elokuvat vuosilta 1940–1950, tarvitsemme useita kyselyjä:

SELECT nimi FROM Elokuvat1940;
SELECT nimi FROM Elokuvat1941;
SELECT nimi FROM Elokuvat1942;
...
SELECT nimi FROM Elokuvat1950;

Kuitenkin kun elokuvat ovat samassa taulussa, niin selviämme yhdellä kyselyllä:

SELECT nimi FROM Elokuvat WHERE vuosi BETWEEN 1940 AND 1950;

Kun elokuvat ovat yhdessä taulussa, pystymme käsittelemään niitä monipuolisesti yksittäisillä SQL-komennoilla, mikä ei olisi mahdollista, jos tauluja olisi useita.

Jatka tästä seuraavaan osaan: