Relatsioonilise mudeli loomise läbimäng
Rakendame nüüd antud algoritmi ja teisendame Eurovisiooni ER mudeli relatsiooniliseks mudeliks. Meenutame esialgu, milline nägi välja eelnevalt koostatud ER mudel:
Samm 1- tugevad olemid relatsioonideks
Millised on meil praegu tugevad olemid? Õige vastus on kõik. Siinkohal tasub aga mainida, et antud relatsioonilise mudeli koostamisel loome igale olemile uue tunnuse "ID", mis saab võtmeks.
Mida aga tähendab olemitüübi teisendamine relatsiooniks? Selle protsessi käigus tuleks olemitüüpi ainult täiendada. Lihttunnused nagu sünniaeg, isikukood, pikkus jne jäävad samasuguseks. Liittunnustest tuleks luua aga eraldi pisemad tunnused, näiteks lauljate nime puhul võivad olla selleks lausa kolm lihttunnust- artisti nimi, eesnimi, perekonnanimi. Kui tunnused on korrastatud, siis tuleks ära märkida veel, milline neist on primaarvõti, ehk identifikaator. Tuleks lisada ka andmetüübid. Praeguses läbimängus loob igale relatsioonile juurde ühe atribuudi nimega ID, mille väärtused saab lasta siis hiljem andmebaasil endal genereerida. Andmebaas hoolitseb ise selle eest, et need väärtused oleks selle tunnuse puhul unikaalsed. Teeb selle protsessi nüüd läbi iga tugeva olemi puhul.
Laulud
Laulude olemil on kõik atribuudid lihttunnused ja seega relatsiooni kõik tunnused ongi need samad tunnused. Nendele lisaks lisab ka enne mainitud ID tunnuse, mille väärtused genereerib meile andmebaas. See on relatsiooni primaarvõtmeks ja tüübiks on INTEGER, ehk täisarv.
Miks aga mitte valida ise mingit tunnuste kompleki identifikaatoriks ja panna seda primaarvõtmeks? Sellele leidub mitu põhjust, näiteks on automaatselt genereeritud ID-de kasutamine mugavam. Teisalt aga saavutab selle arvelt ka andmebaasi jõudluse kasvu, sest INTEGER tüüpi väärtuste võrdlemine käib kiiremini, kui näiteks VARCHAR väärtuste võrdlemine. Seoste kaudu andmete pärimisel tehakse neid võrdlusi palju.
Tuleks määrata ära ka ülejäänud atribuutide andmetüübid. Pealkirja ja keele puhul on lihtne, nende tunnuste väärtusteks laseb salvestada teksti ehk sõne tüüpi andmeid. Teeb ka kitsenduse ja piirab nende sõnede pikkust 50 tähemärgini. Võiks ju eeldada, et ükski pealkiri ja keele nimetus ei ole sellest pikem.
Kestusega on natuke rohkem mõtlemist. Kas on mõeldud sekundeid, minuteid tunde või midagi muud? Kui on mõeldud sekundeid, siis saaks väärtusi esitada täisarvudena. Kui aga on mõeldud minuteid, siis oleks vaja salvestada juba ujukomaarve. Kui salvestaks minuteid täisarvudena, siis läheks ju palju infot kaotsi, sest alati ümardatakse mingi osa kestust juurde või maha võrreldes õige väärtusega. Oletame, et uurisime välja, et tegu on siiski sekunditega ja salvestab need täisarvudena, ehk INTEGER. Samas võib kasutada ka TIME andmetüüpi.
Vaatleme järgmist tunnust "Finaalis". Kui meenutada, siis selle atribuudi andmetüüp sai välja toodud juba eelmises peatükis. Selle tunnuse väärtused pidid sümboliseerima seda, kas laul jõudis finaali või mitte. Seda saab edukalt esitada andmetüübiga BIT, kus väärtusteks on 0 või 1.
Kui vaadelda järgmist kolme tunnust "Esinemis_jrk", "Punkte" ja "Koht", siis on ilmne, et nende atribuutide väärtused saavad olla täisarvud. Seega määrab nende tunnuseks INTEGER.
Oleme saanud olemist "Laulud" relatsiooni "Laulud":
Võistlused
Olemil "Võistlused" on vähe tunnuseid ja mõlemad on lihttunnused, seega määrab mõlemad ka relatsiooni tunnusteks. Muudame aga ära tunnuse "Linn" nimetuse näiteks tunnuseks "Kohanimi", sest võib ju juhtuda, et võistlus ei toimu üldsegi linnas, vaid mingis muus asulas. Nagu laulude puhulgi, siis lisab ka samuti siin ID välja tüübiga INTEGER, millest saab selle relatsiooni primaarvõti.
Tunnuse "Kohanimi" tüübiks võiks määrata VARCHAR ja eeldab, et meil pikemaid kohanimesi kui 50 tähemärki ei esine. Tunnuse "Toimumisaeg" tüüp peaks kindlasti olema seotud aja tüüpidega, aga kas kasutada näiteks DATETIME tüüpi või lihtsalt DATE? Kuna võistluse toimumisaja juures meid täpne kellaaeg ei huvita, siis piisab tüübist DATE.
Olemegi koostanud relatsiooni "Võistlused":
Riigid
Olemitüübil "Riigid" on kõik tunnused lihttunnused. Lisame need relatsiooni tunnusteks ja lisaks neile lisab ka jälle ID tunnuse nagu tegime seda eelnevalt teiste relatsioonidega.
Tunnused "Nimi" ja "Pealinn" saavad tüübiks VARCHAR maksimaalse pikkusega 50, sest nende väärtused saavad olema sõne kujul nagu "Eesti", "Tallinn" jne.
"Rahvaarv" on kindlasti INTEGER tüüpi. Rahvaarvu väärtus võib mõne riigi puhul olla väga suur ja seega tasuks ette mõelda, kas tavalisest INTEGER tüübist piisab. Kui meenutada, siis INTEGER maksimaalne väärtus sai olla 2147483647 (~2.15 miljardit), ehk 231. Maailma suurima populatsiooniga riik Hiina rahvaarv on näiteks peaaegu 1.5 miljardit ja seega on tavaline INTEGER ka sobilik hetkel.
Riigi pindala salvestades tuleks esialgu mõelda sellele, et mis ühikutes seda salvestada. Ruutsentimeetrites seda kindlasti mõistlik teha ei ole. Lepib kokku, et salvestame pindala ruutkilomeetrites. Selle juures tasub tähele panna ka seda, et komakohad meid ei huvita, sest need ei omaks väga suurt vahet riikide pindalade juures. Seega võiks tüübiks määrata jällegi INTEGER. Ei tohiks tekkida ka väärtuste suurustega probleemi, sest maailma suurima pindalaga riigi, Venemaa, pindala on ~17 miljonit ruutkilomeetrit.
Kui vaadata majandusaruandeid, siis SKP puhul jääb silma, et seda esitatakse tavaliselt miljardites ja komakoha täpsusega. Seega oleks vajalik kasutusele võtta andmetüüp, mis võimaldab salvestada ujukomaarve. Selleks sobiks NUMERIC.
Tulemusena saame järgneva riikide relatsiooni:
Lauljad
Jäänud on veel teisendada olemitüüp "Lauljad" relatsiooniks. Lisab esimesena ära jälle primaarvõtmeks uue tunnuse ID tüübiga INTEGER.
On näha, et olemis "Lauljad" on samuti atribuut "Nimi" nagu oli see ka olemis "Riigid. Kas aga see tähendab kohe, et ka see on lihttunnus ja sama tüübiga? Nii see ei ole. Laulja puhul on nimi liittunnus. Inimesel koosneb siiski nimi ju kahest osast- eesnimi ja perekonnanimi. Lisaks sellele võiks lisada veel ühe tunnuse "Lavanimi", sest on ju teada, et lauljad ei esine tihti oma pärisnime all. Seega olemi tunnusest "Nimi" saime kolm relatsiooni tunnust "Lavanimi", "Eesnimi" ja "Perekonnanimi". Tüübiks määrab kõigile kolmele VARCHAR maksimaalse pikkusega 50 tähemärki. Liittunnuse lihttunnusteks tegemise eelis on see, et hiljem on võimalik mugavalt pärida infot näiteks ainult eesnime järgi. Kui panna eesnimi ja perekonnanimi ühe tunnuse alla, siis on ka see võimalik, aga tuleb näha lisavaeva, et see toimiks.
Sünniajale võiks määrata tüübiks DATE, sest nagu võistluse toimumisaja puhulgi, siis täpne kellaaeg kasutajaid ei huvita.
Tunnusele "Sugu" võiks alguses tahta määrata tüübiks näiteks BIT, kus 0 võiks tähistada siis meest ja 1 naist. Kui aga meenutada näiteks 2014 aasta Eurovisiooni, siis oleks mõistlik võimaldada rohkem väärtusi kui kaks. Sugu võib esitada ka mõne sõne tüübiga, aga valib hetkel siiski tüübiks INTEGER, kus iga arv tähistab kokkuleppeliselt mingit sugu.
Tunnus "Ansambel" tüüp sai käsitletud juba eelmises peatükis ja on teada, et selle tüübiks võiks olla BIT. Ehk siis väärtused sümboliseeriksid seda, kas laulja kuulub ansamblisse või mitte.
Sellega oleme ära teisendanud viimase olemi:
Samm 2- nõrgad olemid relatsioonideks
See algoritmi samm on selle näite puhul väga lihtne. Võib lihtsalt edasi minna, sest nõrgad olemid puuduvad.
Kui aga esineks nõrkasi olemeid, siis tuleks suurel määral toimida samamoodi nagu tugevate olemite puhul. Erinevuseks on see, et nõrkade olemite teisendamisel lisab temaga seotud tugeva olemi võtme eraldi tunnusena sellele relatsioonile. Kujutame ette olukorda, kus leidub nõrk olem "Lapsed", mis on seotud tugeva olemiga "Töötajad", millel on võti "isikukood". Relatsiooni "Lapsed" tuleks lisada seega töötaja isikukood näiteks tunnusena "Töötaja_Isikukood". Relatsiooni "Lapsed" võtmeks saaks see sama tunnus + mingid lapse enda tunnused. Lisatud tunnust nimetatakse välisvõtmeks.
Samm 3- 1:1 seoste teisendamine
Jällegi on see samm väga lihtne, sest meie loogilises mudelis ei esine ühtegi 1:1 seost. Kui aga selline seos leiduks, siis tuleks valida suvaliselt üks neist ja selle võti, ehk primaarvõti, lisada teisele relatsioonile tunnuseks. Sellest saaks välisvõti. Relatsioonide vahelise noole tõmbab välisvõtmest primaarvõtme suunas.
Samm 4- 1:N seoste teisendamine
Nende seoste puhul peab juba natuke vaeva nägema, sest 1:N seoseid on loogilises mudelis neli tükki. Iga sellise seose puhul, tuleks võtta 1-poolse relatsiooni võti ja lisada see N-poolsele relatsioonile uueks tunnuseks, ehk välisvõtmeks. Noole tõmbab relatsioonide vahel jällegi välisvõtmest primaarvõtme suunas.
Peale neid teisendusi näeks meie relatsiooniline mudel välja selline (rohelisega on märgitud lisatud välisvõtmed):
Samm 5- M:N seoste teisendamine
N:M seose implementatsiooni kirjelduse juures sai seletatud, et nende seoste puhul tekib juurde üks vahetabel, ehk seose relatsioon. Nagu algoritmis öeldud, siis sinna relatsiooni lähevad mõlema seotava relatsiooni primaarvõtmed tunnusteks välisvõtmetena. Relatsiooni identifikaatortunnuseks saab määrata need samad välisvõtmed ühe komplektina. Alternatiivina saaks lisada ID välja ja andmebaasil lasta automaatselt genereerida sinna unikaalseid väärtusi. Teeb seda ka siin. Nooled liiguvad ikka samamoodi välisvõtmetest primaarvõtmetesse. Lisaks võib soovi korral nüüd sinna relatsiooni lisada ka tunnuseid juurde. Näiteks, kui luua vahetabeliks relatsiooni "Esitamised", siis võib lisada sinna juure tunnuse esitamise kellaaja jaoks. Seda praegu ei tee.
Peale M:N seose teisendamist saame all oleva skeemi (rohelisega on märgitud uued lisatud välisvõtmed):
Samm 6- Korduvate gruppide käsitlemine
Kui loogiline mudel oli hästi tehtud, siis selles sammus ei olegi rohkem midagi teha ja relatsiooniline mudel on valmis. Praeguses relatsioonilises mudelis korduvaid gruppe ei esine ja seega ongi töö lõppenud. Relatsiooniline mudel on valmis.
<< Relatsiooniline mudel | Andmebaaside administreerimine >> |