vaatimusmaarittely.md 5.04 KB
Newer Older
M1888's avatar
M1888 committed
1 2 3 4 5 6 7
# TTZC0800 - Tietokannat - Vaatimusmäärittely

## Kendokanta

Tietokanta jääkiekko-otteluiden tapahtumien tallentamiseen.

| Nimi | Email |
M1888's avatar
M1888 committed
8
|---|---|
M1888's avatar
M1888 committed
9 10
| Joeli Hokkanen | M1888@student.jamk.fi |

M1888's avatar
M1888 committed
11
Versio: 0.8 (12.4.2019)
M1888's avatar
M1888 committed
12 13 14 15 16

## Johdanto

Ohjelmisto tehdään TTZC0800 Tietokannat -kurssin puitteissa harjoitustyönä. Tavoitteena on toteuttaa tietokanta, jonne voidaan tallentaa tietoa jääkiekkojoukkueista, pelaajista, areenoista, otteluista, sekä ottelutapahtumista.

M1888's avatar
M1888 committed
17
Lisäksi toteutetaan MS Access -pohjainen käyttöliittymä osalle tietokannan ominaisuuksista.
M1888's avatar
M1888 committed
18 19 20 21 22

## Yleiskuvus

Järjestelmä sijoitetaan JAMKin student.labranet.jamk.fi -palvelimelle ja tietokantaratkaisuna on MySQL.

M1888's avatar
M1888 committed
23
Olettamuksia arkkitehtuurista:
M1888's avatar
M1888 committed
24

M1888's avatar
M1888 committed
25 26 27 28 29
- Joukkueilla on kotikaupunki
- Joukkueilla on sopimuksia pelaajista, sopimukseen kuuluu alku- ja loppupäivä sekä pelinumero
- Kaupunki omistaa areenan
- Ottelu pelataan yhdellä areenalla koti- ja vierasjoukkueen kesken
- Ottelusta kirjataan ottelutapahtumia, jotka voivat olla ainakin maaleja, jäähyjä, rangaistuslaukauksia, aikalisiä
M1888's avatar
M1888 committed
30 31
- Maalilla voi yksi syöttäjä, mutta ei sen enempää
- Maali-taululle piti määritellä myös maalin tehnyt joukkue, koska muuten omaan maaliin menevä kiekko tulisi väärän joukkueen maaliksi
M1888's avatar
M1888 committed
32 33 34 35 36

Alustava ER-kaavio tietokannasta:

![](er.png)

M1888's avatar
M1888 committed
37 38 39 40 41 42 43 44 45 46
Ottelutapahtumat toimivat tyypin mukaan ottamalla tapahtuma_id:n halutusta taulusta.

| Numero | Tapahtumatyyppi |
|---|---|
| 1 | Maali |
| 2 | Jäähy |
| 3 | Rangaistuslaukaus |
| 4 | Aikalisä |

Aikamääreet (esim. ottelutapahtumassa ja jäähyssä), ovat sekunteina
M1888's avatar
M1888 committed
47

M1888's avatar
M1888 committed
48 49 50 51 52 53 54 55 56 57
Toteuttamisvaiheessa ilmeni, että tämä suunnitelma ei toiminutkaan. MySQL valitti ottelutapahtumia lisätessä vierasavaimien konfliktista, kun kaikista taulukoista ei löydykään sopivaa id:tä:

```SQL
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)
```

Suunnittelupöydältä pyörähti sitten ulos kakkosversio, jossa ottelutapahtuma-taulussa on suoraan oma erillinen foreign key jokaiselle ottelutapahtumatyypille, ja näistä rajoitteen avulla täytetään vain yksi. Taulun pääavain tulee ottelu_id:stä, sekä tästä yhdestä täytetystä foreign keystä.

M1888's avatar
M1888 committed
58
Jotta varmistuttiin, että vain yksi näistä vierasavaimista täytetään kerralla, tuli ottelutapahtuma-taululle kirjoitettua vielä seuraavanlainen constraint *(myöhemmin tajusin, että eihän nämä CHECKit toimineet MySQL:ssä)*:
M1888's avatar
M1888 committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84

```SQL
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)

```

![](er_v2.png)

Mutta edelleen törmättiin samankaltaiseen ongelmaan:

```SQL
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)

```

Googlesta ja StackOverflow'sta aikani luettuani, kokeilin pariakin eri lähestymistapaa:

- Vaihdoin ottelutapahtuma-taulun vierasavaimet UNSIGNED INT -tyyppiin
- Kokeilin määrittää kaikki muut vierasavaimet INSERTin aikana erikseen NULL-arvolle
- Vielä paria erilaista constraintia ja muuta määrettä taululle

M1888's avatar
M1888 committed
85
Mikään ei auttanut vaikka tämän piti toimia hyvin. Olin jo varma, että Student-palveimen MySQL on liian vanha ja buginen eikä koodissani mitään vikaa ole. Sitten tajusin vielä kokeilla, että jätän FK-määreet näille ottelutapahtuman eri id:ille, mutta teen taululle erillisen oman id:n primary keyksi, näiden neljän fuusion sijaan. Tämä tuntui vihdoin toimivan, ja tietokannan skeema oli vihdoin valmis. Lopullinen ongelma oli siis siinä, että primary keyssä ei saa olla NULL-kenttiä, vaikka INSERT-rivin virhe tulikin foreign key constraintista.
M1888's avatar
M1888 committed
86 87 88

![ER final](er_final.png)

M1888's avatar
M1888 committed
89 90 91 92 93 94 95 96 97 98
## Toiminnot

Pakollisia toimintoja ovat ainakin:

1) Joukkueiden lisäys ja ylläpito (nimi, kaupunki, pisteet ym.)
2) Pelaajien lisäys ja muokkailu (nimi, pelinumero, paikka, joukkue, tehopisteet, ..)
3) Otteluiden lisääminen (joukkue vs joukkue, tapahtumat..)
4) Pelitapahtumien lisääminen otteluun (maalit, jäähyt, jne)

Lisäksi tulisi saada koosteita mm. seuraavista asioista:
M1888's avatar
M1888 committed
99

M1888's avatar
M1888 committed
100
1) Ottelun aikana tehdyt maalit
M1888's avatar
M1888 committed
101 102
2) Joukkueiden pistepörssi (= voitetut ottelut)
3) Pelaajapörssi (= maalit + syötöt)
M1888's avatar
M1888 committed
103 104 105

## Ulkoiset liittymät

M1888's avatar
M1888 committed
106
Kannalle toteutetaan MS Access -pohjainen käyttöliittymä tietojen tarkastelua ja lisäilyä varten.
M1888's avatar
M1888 committed
107 108 109

## Muut ominaisuudet

M1888's avatar
M1888 committed
110
Suorituskyky: Vasteajat tulisi olla käyttämällämme datamäärällä käytännössä välittömiä. Kannan tulisi skaalautua suuremmillekkin datamäärille.