README.md 2.47 KB
Newer Older
M1888's avatar
M1888 committed
1 2
# ttzc0800-harkka

M1888's avatar
M1888 committed
3 4 5 6 7 8 9 10
Tietokannat (TTZC0800) kurssin harkkatyö

## Suunnitelmavaihe:

**[Vaatimusmäärittelyyn](vaatimusmaarittely.md)** tästä.

Vaatimusmäärittelyn pohjalta nousi ainakin seuraavanlaisia käsitteitä:

M1888's avatar
M1888 committed
11 12 13 14 15 16
- Kaupunki (sisältää areenoja, joukkueilla kotikaupunki)
- Areena (sisältää otteluita)
- Joukkue (sisältää pelaajia)
- Pelaaja (kuuluu joukkueeseen)
- Ottelu (sisältää tapahtumia)
- Tapahtumat (maali & jäähy, eri tauluista)
M1888's avatar
M1888 committed
17

M1888's avatar
M1888 committed
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
##  Toteutus

Lähdettäessä toteuttamaan vaatimusmäärittelyn mukaista ensimmäistä versiota tietokannasta, kannan luonti sujui hyvin ja alustavia tietojakin sai lisättyä. Ongelmat kuitenkin ilmenivät ottelutapahtumia lisätessä. Olin suunnitellut ottelutapahtuman tapahtuma_id:n olevan viittaus jonkin ottelutapahtuman id-tauluun (maali, jäähy, rankkari, aikalisä), ja oikea taulu josta tämä id etsittäisiin pääteltäisiin ottelutapahtuman tyyppi-kentän mukaan.

Tämä ei kuitenkaan onnistunut, vaan MySQL valitti vierasavaimien konfliktista, kun kaikista tauluista ei löytynyktään sopivaa id:tä:

```
mysql> INSERT INTO ottelutapahtuma (tyyppi, tapahtuma_id, ottelu_id, aika) VALUES
    ->     (2, 1, 1, 3*60+14);
    ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`M1888`.`ottelutapahtuma`, CONSTRAINT `fk_ottelutapahtuma_maali1` FOREIGN KEY (`tapahtuma_id`) REFERENCES `maali` (`maali_id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
```

Takaisin suunnittelupöydän ääreen siis. Seuraava versio oli sellainen, jossa ottelutapahtuma-taulussa on oma erillinen foreign key jokaiselle ottelutapahtumatyypille, ja näistä täytetään rajoitteen avulla vain ja ainoastaan yksi. Taulun pääavain tulee ottelu_id:stä ja tästä yhdestä täytetystä FK:sta.

![](er_v2.png)
M1888's avatar
M1888 committed
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

Itse kirjoitettu check tätä varten meni näin:

```
  CONSTRAINT `CK_tapahtumaid` CHECK (
    CASE WHEN aikalisa_id IS NULL THEN 0 ELSE 1 END +
    CASE WHEN jaahy_id    IS NULL THEN 0 ELSE 1 END +
    CASE WHEN rankkari_id IS NULL THEN 0 ELSE 1 END +
    CASE WHEN maali_id    IS NULL THEN 0 ELSE 1 END = 1)

```

Mutta edelleen törmättiin samankaltaiseen ongelmaan:
```
mysql> INSERT INTO ottelutapahtuma (ottelu_id, jaahy_id, aika) VALUES (1, 1, 3*60+14);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`M1888`.`ottelutapahtuma`, CONSTRAINT `fk_ottelutapahtuma_aikalisa1` FOREIGN KEY (`aikalisa_id`) REFERENCES `aikalisa` (`aikalisa_id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
```