Andmebaasid I - Teema nr. 14
Andmebaasid I - Teema nr. 14
Andmebaasid I - Teema nr. 14
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
<strong>Teema</strong> <strong>14</strong>. <strong>Andmebaasid</strong>e projekteerimine<br />
(füüsilisest disainist töötava andmebaasi<br />
hooldamiseni)<br />
Sisukord<br />
1.Eesmärgid............................................................................................................1<br />
2.Klassikaline (kaskaadne) infosüsteemi arendusprotsess....................................2<br />
3.Füüsiline disain (järg)...........................................................................................2<br />
4. SQL-andmebaasi disain – kokkuvõte...............................................................21<br />
5. Realiseerimise (ehitamise) etapp.....................................................................26<br />
6. Rakendamise (üleviimise) etapp.......................................................................26<br />
7. Hoolduse etapp.................................................................................................26<br />
8. Mõisted..............................................................................................................27<br />
9. Kasutatud materjalid.........................................................................................27<br />
Joonised<br />
1.Eesmärgid............................................................................................................1<br />
2.Klassikaline (kaskaadne) infosüsteemi arendusprotsess....................................2<br />
3.Füüsiline disain (järg)...........................................................................................2<br />
4. SQL-andmebaasi disain – kokkuvõte...............................................................21<br />
5. Realiseerimise (ehitamise) etapp.....................................................................26<br />
6. Rakendamise (üleviimise) etapp.......................................................................26<br />
7. Hoolduse etapp.................................................................................................26<br />
8. Mõisted..............................................................................................................27<br />
9. Kasutatud materjalid.........................................................................................27<br />
1.Eesmärgid<br />
1. Anda lihtsustatud ülevaade andmebaasi arendustsükli viimastest etappidest.<br />
2. Selgitada denormaliseerimist ja sellest tulenevaid eeliseid ja probleeme.<br />
1
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
2.Klassikaline (kaskaadne) infosüsteemi<br />
arendusprotsess<br />
… hõlmab järjestikku toimuvaid etappe:<br />
• Strateegiline analüüs<br />
• Detailanalüüs<br />
• Disain<br />
• Realiseerimine (Ehitamine)<br />
• Rakendamine (Üleviimine)<br />
• Hooldus<br />
3.Füüsiline disain (järg)<br />
Kasutan denormaliseerimisest kirjutades SQLi termineid (baastabel, rida, veerg).<br />
3.1 Denormaliseerimine<br />
Loogilise disaini lõpuks peaksid tabelid olema viidud soovitavalt kuni viiendale<br />
normaalkujule. Selle eesmärk on vähendada andmete liiasust.<br />
Füüsilise disaini käigus võib (aga ei pea) toimuda valikuline tabelite<br />
denormaliseerimine. Denormaliseerimine on normaliseerimise pöördprotsess.<br />
Denormaliseerimine on protsess, mille käigus vähendatakse ühe või mitme<br />
andmebaasis oleva baastabeli (edaspidi tabeli) normaliseerituse astet.<br />
Denormaliseerimise tulemusel dubleeritakse veerge või ühendatakse tabeleid, et<br />
andmete otsimisel oleks vaja viia läbi vähem tabelite ühendamise operatsioone.<br />
Date (2007) esitab formaalse denormaliseerimise definitsiooni. Olgu R1, R2,...,<br />
Rn relvarid. Sellisel juhul tähendab nende denormaliseerimine järgmist.<br />
Relvarid asendatakse nende ühendiga R nii, et<br />
iga võimaliku R1, R2, ..., Rn vääruse r1, r2, ..., rn korral kehtib olukord, et<br />
tehes tehes projektsiooni R väärtuse r põhjal üle Ri atribuutide saadakse<br />
tulemuseks ri.<br />
Lähtutakse eeldusest, et andmebaasisüsteemilt nõuab ühendamise operatsiooni<br />
läbi viimine palju vaeva (andmebaasisüsteem peab viima läbi palju I/O<br />
(sisend/väljund) operatsioone) ja selle kasutamine mõjub andmebaasist andmete<br />
otsimiseks mõeldud lausete töökiirusele halvasti.<br />
Juhime tähelepanu, et kõrgel normaalkujul olevate baastabelite põhjal<br />
madalamatel normaalkujudel olevate vaadete loomine töökiiruse parandamisele<br />
kaasa ei aita, sest vaate põhjal päringut tehes peab andmebaasisüsteem ikkagi<br />
täitma vaate aluseks oleva päringu.<br />
2
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Denormaliseerimise eesmärgiks on parandada päringute töökiirust. Samas<br />
tuuakse denormaliseerimisega tabelitesse sisse andmete liiasus, mille<br />
kaotamiseks viidi läbi normaliseerimine.<br />
Hoberman (2002, lk. 342–344) loetleb denormaliseerimisest tulenevaid<br />
probleeme.<br />
1. Ilmnevad andmete muutmise anomaaliad, mille pärast normaliseerimine ette<br />
võeti.<br />
2. Denormaliseerimine võib suurendada andmete muutmiseks kuluvat aega,<br />
sest tänu andmete liiasuse kasvule tuleb andmeid muuta mitmes erinevas<br />
tabelis või mitmes erinevas tabeli reas. Lighstone et al. (2007) märgib, et<br />
mitmed andmebaasisüsteemid pakuvad funktsionaalsust, mis võimaldab<br />
tabelites olevate andmete sünkroniseerimist (IBM DB2 Everyplace, Oracle<br />
Data Hubs, Oracle Streams, SQL Server Compare, SQL Server Everywhere<br />
Edition). Seda võib andmete kooskõlalisuse tagamiseks ära kasutada.<br />
3. Denormaliseerimine võib suurendada ka päringule vastuse saamise aega.<br />
See võib näiteks juhtuda, kui tabeli veergude hulk läheb nii suureks, et üks<br />
rida ei mahu ära ühte plokki. Sellisel juhul jaotub rida mitme erineva ploki<br />
vahel ning andmete lugemiseks ja muutmiseks kulub rohkem aega. Samuti<br />
võib põhjuseks olla, et kuigi read mahuvad ühte plokki ära, tuleb päringule<br />
vastuse saamiseks andmebaasisüsteemil vaadata läbi rohkem plokke.<br />
4. Denormaliseerimine suurendab andmemahte, sest andmete liiasus suureneb.<br />
Näiteks võib denormaliseerimise tulemusel tekkivates tabelites 100 märgiline<br />
stringi e. sõne ühe rea asemel olla viies reas.<br />
5. Denormaliseerimine võib põhjustada probleeme andmete kvaliteedis. Näiteks<br />
kui denormaliseerimise tulemusel tekkinud tabelis dubleeritakse inimese<br />
perenime mitmes reas, kuid andmete muutmisel tehakse muudatus vaid ühes<br />
reas, siis see tekitab vastuolu andmetes ja põhjustab andmete kvaliteedi<br />
vähenemise.<br />
6. Kunagi ei tuleks denormaliseerida ilma eelneva normaliseerimiseta. Vastasel<br />
juhul jääb arusaamine andmetest ja nende vahelistest seostest poolikuks.<br />
7. Denormaliseerimine vähendab süsteemi paindlikust ja laiendamise võimalusi.<br />
Täiendavad probleemid.<br />
• Date (2007) märgib, et denormaliseerimine võib muuta mõne päringu<br />
kirjutamise keerulisemaks.<br />
• Kui alustada andmebaasi loomist kohe denormaliseeritud andmetabelite<br />
tekitamisega, siis tähendab see, et ei leita andmete vahelisi seoseid ja<br />
andmete tegelikku tähendust. Tulemuseks on skeem, mille korrektsust ja<br />
infovajadustele vastavust on väga raske kontrollida ja mis väga suure<br />
tõenäosusega sisaldab selles osas puudusi. Date (2009) rõhutab, et<br />
andmebaasi disaini käigus tuleb kõigepealt viia läbi loogiline disain ja leida<br />
kõrge tasemeni normaliseeritud tabelid. Seejärel peaks toimuma füüsiline<br />
disain, kus loogilise disaini tulemuste põhjal projekteeritakse andmebaas<br />
konkreetse andmebaasisüsteemi võimalustest lähtuvalt. Denormaliseerimine<br />
toimub füüsilise disaini käigus.<br />
• Mida kõrgema tasemeni on tabelid normaliseeritud, seda lihtsam on nendes<br />
tabelites jõustada funktsionaalsetele-, multiväärtuslikele- ja<br />
3
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
ühendamissõltuvustele vastavaid kitsendusi. Selliste kitsenduste jõustamiseks<br />
piisab kõrge astmeni normaliseeritud tabelites võtmete deklareerimisest ja<br />
nende väärtuste unikaalsuse tagamisest. Denormaliseerimine omakorda<br />
tähendab, et nende kitsenduste jõustamine muutub keerukamaks ning võib<br />
SQL-andmebaasisüsteemides nõuda näiteks trigeri protseduuride kasutamist.<br />
Date (2007) rõhutab, et andmebaasis tuleb kitsendused jõustada ka siis, kui<br />
põhiliselt toimuvad selles andmebaasis lugemisoperatsioonid. Kitsendused<br />
määravad ära andmete tähenduse ja seda tähendust on vaja teada nii<br />
andmebaasi kasutajal (et andmetest aru saada) kui ka andmebaasisüsteemil<br />
(et optimeerida päringuid).<br />
• Denormaliseerimise tulemusel muutub andmebaasi kontseptuaalne skeem<br />
kasutaja jaoks ebaselgemaks.<br />
Näitena vaadake esimesel normaalkujul (kuid mitte kõrgematel normaalkujudel)<br />
oleva tabeli struktuuri ja kitsenduste kirjeldust.<br />
Töötaja_maja_inspekteerimine (maja_<strong>nr</strong>, kuupäev, kellaaeg, maja_aadress,<br />
kommentaar, töötaja_<strong>nr</strong>, eesnimi, auto_<strong>nr</strong>)<br />
Primaarvõti (maja_<strong>nr</strong>, kuupäev)<br />
Alternatiivvõti (töötaja_<strong>nr</strong>, kuupäev, kellaaeg)<br />
Alternatiivvõti (auto_<strong>nr</strong>, kuupäev, kellaaeg)<br />
Vaadates selle tabeli struktuuri ning kitsendusi ei ole võimalik lihtsalt aru saada,<br />
et kehtib reegel, mille kohaselt saab iga töötaja ühel päeval kasutada<br />
maksimaalselt ühte autot. Küll aga saab selle reegli kehtivusest aru, vaadates<br />
ühe algse tabeli täiendava normaliseerimise tulemusena leitud tabeli struktuuri<br />
ning kitsendusi. Nimetatud reegli jõustamiseks piisab võtme (töötaja_<strong>nr</strong>,<br />
kuupäev) deklareerimisest tabelis Töötaja_auto.<br />
Töötaja_auto(töötaja_<strong>nr</strong>, kuupäev, auto_<strong>nr</strong>)<br />
Primaarvõti (töötaja_<strong>nr</strong>, kuupäev)<br />
Välisvõti (töötaja_<strong>nr</strong>) Viitab Töötaja(töötaja_<strong>nr</strong>)<br />
• Pole selge, millal tuleb denormaliseerimine lõpetada – kas siis kui kõik/osa<br />
tabeleid on Boyce/Coddi normaalkujul, teisel normaalkujul ...?<br />
Lighstone et al. (2007) tõstab esile denormaliseerimise tekitatavaid probleeme,<br />
kui denormaliseerimist rakendada juba kasutuses olevas andmebaasis.<br />
• Denormaliseerimise järel tuleb üle kontrollida ja vajadusel muuta kõiki<br />
päringuid, mida on juba jõutud denormaliseeritud tabelite põhjal kirjutada.<br />
• Denormaliseerimise korral nõuab aega tabelite/relvaride reorganiseerimine ja<br />
vajalike andmete ülekandmine uutesse tabelitesse / relvaride väärtuste<br />
muutmine.<br />
Denormaliseerimise võimalust võiks kaaluda (see ei tähenda, et tingimata peab<br />
denormaliseerima) vaid tabelite puhul mida kasutatakse sageli päringutes<br />
ning milles andmete muutmised toimuvad harva.<br />
4
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Selliste omadustega tabelid on näiteks andmeaida ja andmevaka<br />
andmebaasides. Seal hoitakse ajaloolisi andmeid mille põhjal tehakse keerukaid<br />
päringuid. Seetõttu rakendatakse sellist tüüpi andmebaaside tabelite struktuuri<br />
leidmisel sageli denormaliseerimist.<br />
Denormaliseerimise käigus tehtud otsused tuleb dokumenteerida. Mida<br />
täpsemalt tuleks kirja panna?<br />
• Tehtud muudatused võrreldes loogilise andmemudeliga.<br />
• Põhjused, miks denormaliseerimist kasutatakse.<br />
• Kui on võimalik denormaliseerida mitmel erineval viisil, siis tuleb<br />
dokumenteerida põhjendused, miks valiti mingi kindel viis.<br />
Denormaliseerimise juures sobib eriti hästi meelde tuletada vanasõna: Üheksa<br />
korda mõõda, üks kord lõika. Date (2009) märgib, et denormaliseerimine<br />
tuleks võtta ette kõige viimase abinõuna – siis, kui ükski teine töökiiruse<br />
parandamiseks ettevõetud tegevus ei ole loodetud tulemust andnud.<br />
Celko (1999) märgib, et denormaliseerimist võib kaaluda kui:<br />
denormaliseerimine ei kahjusta süsteemi kui terviku töökiirust<br />
(operatsiooni A kiirendamiseks läbiviidav denormaliseerimine, võib muuta<br />
operatsioonide B, C ja D täitmise palju aeglasemaks),<br />
denormaliseerimine ei kahjusta andmebaasi terviklikkust.<br />
Denormaliseerimise jaoks annab kasulikku informatsiooni CRUD maatriks:<br />
milliseid tabeleid kasutab kõige rohkem transaktsioone?<br />
ja transaktsioonanalüüs:<br />
<br />
<br />
millised on sagedasti käivitatavad päringud?<br />
kas ja kui sageli muudetakse andmeid tabelites, mille põhjal päringut<br />
tehakse?<br />
Näide: Näiteks olgu meil viiendal normaalkujul olevad tabelid:<br />
Isik (isikukood, perenimi, riigi_kood)<br />
Primaarvõti (isikukood)<br />
Välisvõti (riigi_kood) Viitab Riik (riigi_kood)<br />
Riik (riigi_kood, riigi_nimi)<br />
Primaarvõti (riigi_kood)<br />
Kuid kuna isiku andmeid kasutatakse sageli koos riigi nimega, kus ta elab, siis<br />
luuakse denormaliseerimise tulemusena tabel Isik, mis on teisel normaalkujul ja<br />
sisaldab ülekanduvat sõltuvust:<br />
Isik (isikukood, perenimi, tänav, riigi_kood, riigi_nimi)<br />
Primaarvõti (isikukood)<br />
Välisvõti (riigi_kood) Viitab Riik (riigi_kood)<br />
5
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Riik (riigi_kood, riigi_nimi)<br />
Primaarvõti (riigi_kood)<br />
Funktsionaalsed sõltuvused denormaliseerimise tulemusena leitud tabelis Isik:<br />
- isikukood → {perenimi, riigi_kood, riigi_nimi} (sõltuvus primaarvõtmest)<br />
- riigi_kood → riigi_nimi (ülekanduv sõltuvus)<br />
Tabel Riik säilitatakse, et saaks registreerida andmeid riikide kohta (ka selliste<br />
kohta, kus ei ole teada ühtegi isikut, kelle andmeid andmebaasis registreerida).<br />
Tabelit Riik on vaja, et rakenduses oleks võimalik esitada isiku andmete<br />
registreerijale nimekiri riikidest, millega isikut võib seostada.<br />
Celko (1999) märgib, et on olemas kaks võimalikku denormaliseerimise<br />
strateegiat.<br />
- Asendada kõrge astmeni normaliseeritud tabelid denormaliseeritud<br />
tabelitega.<br />
- Lisada olemasolevasse kõrge astmeni normaliseeritud tabeleid sisaldavasse<br />
andmebaasi uued denormaliseeritud tabelid, mis täidetakse vastavalt<br />
vajadusele. Sellised tabelid võiksid olla hetktõmmised ehk materialiseeritud<br />
vaated.<br />
Denormaliseerimise käigus võib Connolli ja Begg (2001) põhjal teha järgnevaid<br />
tegevusi.<br />
• 1:M seosetüübi puhul mitte-võtmeveergude dubleerimine erinevates<br />
tabelites. Selle eesmärgiks on vähendada tabelite ühendamise vajadust.<br />
Näide: Koos õpingukavaga soovitakse sageli näha ka üliõpilase nime, kellele see<br />
õpingukava kuulub. Tüüpiline SQL lause on:<br />
SELECT Yliopilane.yliopilaskood, Yliopilane.perenimi,<br />
Opingukava.opingukava_id, Opingukava.loomise_aeg<br />
FROM Yliopilane, Opingukava<br />
WHERE Yliopilane.yliopilaskood = Opingukava.yliopilaskood;<br />
Kui tabelisse Opingukava lisada veerg perenimi, siis saaks SQL lauset<br />
lihtsustada ja ei peaks tegema päringut mitme tabeli põhjal:<br />
SELECT yliopilaskood, perenimi, opingukava_id, loomise_aeg<br />
FROM Opingukava;<br />
Eksisteerib funktsionaalne sõltuvus:<br />
yliopilaskood → perenimi.<br />
6
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Kuna tegemist on ülekanduva sõltuvusega, siis see tabel on teisel, aga mitte<br />
kolmandal normaalkujul.<br />
Probleemid:<br />
- Kui põhitabelis (Yliopilane) dubleeritud veerus (perenimi) väärtus muutub,<br />
siis tuleb seda väärtust muuta ka seotud tabelis (Opingukava). Kui muudatust<br />
seotud tabelis ei tehta, tekib andmetesse vastuolu.<br />
- Kui tabelis Opingukava on üliõpilase kohta mitu rida, siis tuleb tagada, et<br />
üliõpilase perenimi on igas sellises reas ühesugune.<br />
- Tabelis Opingukava tuleb kas keelata perenime muutmine või siis kirjutada<br />
programm, mis kannab muudatused üle teistesse tabeli Opingukava<br />
ridadesse ja tabelisse Yliopilane.<br />
- Tuleb kirjutada programm kooskõla automaatseks tagamiseks ja muudatuste<br />
üleviimiseks. Selle programmi võib realiseerida trigerina. Selle programmi<br />
kirjutamine võtab aega ja programm on võimalik vigade allikas.<br />
- Veergude dubleerimisest tulenev andmemahu kasv.<br />
• 1:M seosetüübi puhul välisvõtme veergude dubleerimine erinevates<br />
tabelites. Selle eesmärgiks on vähendada tabelite ühendamise vajadust<br />
päringute tegemisel.<br />
a)<br />
Yliopilane<br />
-------------------------<br />
yliopilaskood (PK)<br />
perenimi<br />
Oppimine<br />
-------------------------<br />
oppimine_id (PK)<br />
yliopilaskood (FK)<br />
algus<br />
lopp<br />
Teadmiste_kontroll<br />
-------------------------<br />
kontroll_id (PK)<br />
oppimine (FK)<br />
toimumise_aeg<br />
tulemus<br />
b)<br />
Yliopilane<br />
-------------------------<br />
yliopilaskood (PK)<br />
perenimi<br />
Oppimine<br />
-------------------------<br />
oppimine_id (PK)<br />
yliopilaskood (FK)<br />
algus<br />
lopp<br />
Teadmiste_kontroll<br />
-------------------------<br />
kontroll_id (PK)<br />
oppimine (FK)<br />
yliopilaskood (FK)<br />
toimumise_aeg<br />
tulemus<br />
Joonis 1Välisvõtme veergude dubleerimine.<br />
Kui tüüpiline päring otsib üliõpilase ja tema teadmiste kontrolli andmed, siis<br />
esimesel juhul tuleb üliõpilase teadmiste kontrolli leidmiseks teha päring kolme<br />
tabeli põhjal:<br />
7
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
SELECT Tk.*, Y.perenimi<br />
FROM Yliopilane Y, Oppimine O, Teadmiste_kontroll Tk<br />
WHERE (Y.yliopilaskood=O.yliopilaskood) AND (O.oppimise_id=Tk.oppimine);<br />
Teisel juhul tuleb teha päring kahe tabeli põhjal:<br />
SELECT Tk.*, Y.perenimi<br />
FROM Yliopilane Y, Teadmiste_kontroll Tk<br />
WHERE (Y.yliopilaskood =Tk.yliopilaskood);<br />
Variant a) korral on Teadmiste_kontroll vähemalt Boyce/Coddi normaalkujul.<br />
Mille alusel saan seda väita? Iga mittetriviaalse, täieliku funktsionaalse sõltuvuse<br />
determinant on kandidaatvõti.<br />
kontroll_id → {oppimine, toimumise_aeg, tulemus}<br />
{oppimine, toimumise_aeg} → {kontroll_id, tulemus}<br />
See tabel on ka vähemalt neljandal normaalkujul tulenevalt järgmisest reeglist<br />
(vt. teema 9): Kui tabel on Boyce/Coddi normaalkujul ja mõni selle kandidaatvõti<br />
on lihtne, siis on see tabel ka neljandal normaalkujul (aga ei pruugi olla viiendal<br />
normaalkujul). Antud juhul on selleks võtmeks võti, mis hõlmab veergu<br />
kontroll_id.<br />
Variant b) korral ei ole Teadmiste_kontroll Boyce/Coddi normaalkujul.<br />
Funktsionaalsed sõltuvused on järgnevad.<br />
kontroll_id → {oppimine, toimumise_aeg, tulemus, yliopilaskood}<br />
{oppimine, toimumise_aeg} → {kontroll_id, tulemus, yliopilaskood}<br />
{yliopilaskood, toimumise_aeg} → {kontroll_id, tulemus, oppimine}<br />
oppimine → yliopilaskood<br />
Funktsionaalse sõltuvuse (oppimine → yliopilaskood) determinant ei ole<br />
kandidaatvõti.<br />
Probleemid:<br />
• Andmete liiasus.<br />
• Tuleb tagada, et andmebaasis ei tekiks andmete vastuolu. Teadmiste kontroll<br />
peab olema läbi Õppimise seotud sama Üliõpilasega, millega Teadmiste<br />
kontroll on seotud ka otse.<br />
• Klassifikaatorite tabelite ühendamine põhitabeliga (eelmise näite<br />
erijuht).<br />
Taolise tabelis on tavaliselt klassifikaatori kood, nimetus ja võibolla ka pikem<br />
kirjeldus.<br />
8
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Kava_seisund<br />
------------------------------<br />
kava_seisund_id (PK)<br />
nimetus<br />
Opingukava<br />
-------------------------<br />
opingukava_id (PK)<br />
kava_seisund (FK)<br />
loomise_aeg<br />
Joonis 2 Tüüpide (klassifikaatorite) tabel.<br />
Kava_seisund<br />
------------------------------<br />
kava_seisund_id (PK)<br />
nimetus<br />
Opingukava<br />
-------------------------<br />
opingukava_id (PK)<br />
kava_seisund (FK)<br />
seisundi_nimetus<br />
loomise_aeg<br />
Joonis 3 Klassifikaatori tabeliga seotud tabeli denormaliseerimine.<br />
Klassifikaatori tabel säilib endiselt, sest selle abil saab kontrollida kasutajapoolset<br />
andmete sisestamist.<br />
Eksisteerib funktsionaalne sõltuvus:<br />
kava_seisund → seisundi_nimetus.<br />
Kuna tegemist on ülekanduva sõltuvusega, siis see tabel on teisel, aga mitte<br />
kolmandal normaalkujul.<br />
Probleemid:<br />
Probleemid on samad, mida mainiti juba 1:M suhte puhul mitte-võtmeveergude<br />
dubleerimise juures.<br />
• M:N seosetüübi puhul veergude dubleerimine vahetabelis. Selle<br />
eesmärgiks on vähendada päringutes tabelite ühendamise vajadust.<br />
Opingukava<br />
-------------------------<br />
opingukava_id (PK)<br />
loomise_aeg<br />
Aine_opingukavas<br />
------------------------------------<br />
opingukava_id(FK)(PPK)<br />
ainekood (FK)(PPK)<br />
Aine<br />
---------------------------<br />
ainekood (PK)<br />
nimetus<br />
ainepunkte<br />
Joonis 4Denormaliseerimata vahetabel.<br />
Tüüpiline päring on:<br />
9
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
SELECT O.*, A.nimetus<br />
FROM Opingukava O, Aine_opingukavas Aa, Aine A<br />
WHERE (O.opingukava_id=Ao.opingukava_id) AND (Ao.ainekood=A.ainekood)<br />
Sellisel juhul võib tabelisse Aine_opingukavas lisada juurde veeru aine_nimetus.<br />
Opingukava<br />
-------------------------<br />
opingukava_id (PK)<br />
loomise_aeg<br />
Aine_opingukavas<br />
------------------------------------<br />
opingukava_id(FK)(PPK)<br />
ainekood (FK)(PPK)<br />
aine_nimetus<br />
Aine<br />
---------------------------<br />
ainekood (PK)<br />
nimetus<br />
ainepunkte<br />
Joonis 5 Denormaliseeritud vahetabel.<br />
SELECT O.*, Ao.aine_nimetus<br />
FROM Opingukava O, Aine_opingukavas Aa<br />
WHERE (O.opingukava_id=Ao.opingukava_id)<br />
Eksisteerib funktsionaalne sõltuvus:<br />
ainekood → aine_nimetus<br />
Kuna aine_nimetus ei sõltu mitte tervest primaarvõtmest vaid mõnest selle osast,<br />
siis on see tabel esimesel normaalkujul, aga ei ole teisel normaalkujul.<br />
10
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Probleemid:<br />
Kontseptuaalsel tasemel esinev M:N suhe lahendatakse SQL-andmebaasis<br />
vahetabeliga, milles on kaks välisvõtme veergu. Seega on ka probleemid samad,<br />
mida mainiti juba 1:M suhte puhul mitte-võtmeveergude dubleerimise juures.<br />
• 1:1 seosetüübi puhul tabelite ühendamine.<br />
<br />
Leping<br />
lepingu_<strong>nr</strong> : Integer<br />
kehtivuse_algus : Date<br />
1<br />
koostatakse<br />
0..1<br />
<br />
Arve<br />
arve_<strong>nr</strong> : Integer<br />
summa : Currency<br />
tasumistähtaeg : Date<br />
Joonis 61:1 seosetüüp.<br />
+koostamise alus<br />
+koostamise tulemus<br />
Lighstone et al. (2007) toob näite denormaliseerimise kohta ka seoses 1:1<br />
seosetüüpidega.<br />
1:1 seosetüübi alusel luuakse loogilise disaini käigus tabelid.<br />
Leping (lepingu_<strong>nr</strong>, kehtivuse_algus)<br />
Primaarvõti (lepingu_<strong>nr</strong>)<br />
Arve (arve_<strong>nr</strong>, lepingu_<strong>nr</strong>, summa, tasumistähtaeg)<br />
Primaarvõti(arve_<strong>nr</strong>)<br />
Alternatiivvõti (lepingu_<strong>nr</strong>)<br />
Välisvõti (lepingu_<strong>nr</strong>) Viitab Leping (lepingu_<strong>nr</strong>)<br />
Tabelid Leping ja Arve on viiendal normaalkujul.<br />
Denormaliseerimise käigus võib kaaluda nende tabelite ühendamist ja luua<br />
tabeli.<br />
Leping (lepingu_<strong>nr</strong>, arve_<strong>nr</strong>, kehtivuse_algus, summa, tasumistähtaeg)<br />
Primaarvõti(lepingu_<strong>nr</strong>)<br />
Kuna võib leiduda lepinguid, millel pole arvet, siis ei saa loodud tabelis määrata<br />
(arve_<strong>nr</strong>) alternatiivvõtmeks (sest igas tabeli reas peab võtme väärtus olema<br />
määratud).<br />
Uues loodud tabelis Leping eksisteerib funktsionaalne sõltuvus:<br />
arve_<strong>nr</strong> → summa
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Kuna arve_<strong>nr</strong> ei kuulu primaarvõtmesse, siis ei ole täidetud kolmanda<br />
normaalkuju reeglid. Denormaliseerimise tulemusel leitud tabel Arve on teisel<br />
normaalkujul, aga ei ole kolmandal normaalkujul.<br />
Toodud lahenduse puhul on oluline tähele panna, et olemitüübile Arve vastavad<br />
veerud tabelis Leping peavad olema mittekohustuslikud.<br />
Esitame näite selle kohta, et denormaliseerimine võib muuta mõningate<br />
päringute kirjutamise keerukamaks. Ülesandeks on leida erinevate arvete arv.<br />
Enne denormaliseerimist:<br />
SELECT Count(*) AS arv FROM Arve;<br />
Pärast denormaliseerimist:<br />
SELECT Count(*) AS arv FROM (SELECT arve_<strong>nr</strong> FROM Leping WHERE<br />
arve_<strong>nr</strong> IS NOT NULL);<br />
3.2 Liiasuse tekitamine<br />
Denormaliseerimine suurendab andmete liiasust. Samas mitte igasugune<br />
liiasuse tekitamine ei ole denormaliseerimine!<br />
Vaatleme näidet andmete liiasuse suurendamise kohta, mis ei tähenda<br />
denormaliseerimist. Tuleb märkida, et kirjanduses esitatakse järgnevaid näiteid<br />
ekslikult kui näiteid denormaliseerimise kohta. Tegelikult ei tähenda järgnevate<br />
disainimuudatuste tegemine denormaliseerimise rakendamist.<br />
• Tuletatavate väärtuste kasutamine.<br />
Opingukava<br />
-------------------------<br />
opingukava_id (PK)<br />
loomise_aeg<br />
ainepunktide_summa<br />
Aine_opingukavas<br />
------------------------------------<br />
opingukava_id(FK)(PPK)<br />
ainekood (FK)(PPK)<br />
aine_nimetus<br />
Aine<br />
---------------------------<br />
ainekood (PK)<br />
nimetus<br />
ainepunkte<br />
Joonis 7 Tuletatud andmeid sisaldava veeru lisamine andmetabelisse.<br />
Näiteks võib tabelisse Opingukava lisada veeru, kus hoitakse sellese<br />
õpingukavasse kuuluvate õppeainete ainepunktide summat.
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Selle väärtuse saaks ka välja arvutada SQL lausega:<br />
SELECT opingukava_id, loomise_aeg, SUM(ainepunkte) AS summa<br />
FROM Opingukava, Aine_opingukavas, Aine<br />
WHERE Opingukava.opingukava_id=Aine_opingukavas.opingukava_id AND<br />
Aine_opingukavas.ainekood=Aine.ainekood;<br />
Probleemid<br />
• Tabelis Opingukava hoitav ainepunktide_summa peab olema kooskõlas tabeli<br />
Aine_opingukavas põhjal leitava andmepunktides summa. Kooskõla<br />
kontrollimiseks ja tagamiseks tuleb kirjutada kontrollprotseduurid, mis<br />
käivitatakse tabelites Opingukava ja Aine_opingukavas toimuvate<br />
andmemuudatuste tulemusena (tuleb kasutada trigereid).<br />
• Aruande tabelite koostamine.<br />
Miks võiks olla vaja sellist tabelit luua?<br />
- Aruanne koostatakse mitme tabeli põhjal.<br />
- Aruande väljastamine peab toimuma kiiresti.<br />
Aruande väljastamise lihtsustamiseks laaditakse andmed aruande struktuurile<br />
vastavasse tabelisse. Aruande väljastamine on nüüd üks lihtne päring ühe tabeli<br />
põhjal.<br />
Oletame, et andmebaasis on järgnevad tabelid:<br />
Müük (müük_id, kuupäev)<br />
Primaarvõti (müük_id);<br />
Müügi_rida(müük_id, kauba_kood, kogus)<br />
Primaarvõti (müük_id, kauba_kood)<br />
Välisvõti (müük_id) Viitab Müük(müük_id);<br />
Selleks, et kiirendada müügiaruande koostamist, võib luua tabeli:<br />
Müügitulemused<br />
kauba jan feb mar apr may jun jul aug sep oct nov dec SUM<br />
_kood<br />
1 4 2 1 4 3 8 9 7 6 4 2 1 51<br />
2 5 3 3 3 4 2 9 8 5 3 1 0 46<br />
SUM 9 5 4 7 7 10 18 15 11 7 3 1 97<br />
Sellise tabeli võib luua hetktõmmise e. materialiseeritud vaatena. Sellisel juhul<br />
hoolitseb andmebaasisüsteem ise, et selles tabelis olevaid andmeid<br />
värskendatakse regulaarselt tabelites Müük ja Müügi_rida olevate andmete<br />
põhjal.
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Seega ei ole normaliseerimine – imerelv. Tabelid võivad olla kõrgeima tasemeni<br />
normaliseeritud, kuid andmebaasis võib olla endiselt andmete liiasus.<br />
3.3 Denormaliseerimise algoritm<br />
Hoberman (2002, lk. 342 – 361) kirjeldab algoritmi "Denormalization Survival<br />
Guide", mis aitab otsustada, millised tabelid tuleb denormaliseerida ja millised<br />
mitte. Iga andmemudelis esitatud suhte kohta vastatakse küsimustikule. Igal<br />
küsimustiks sisalduval küsimusel on vastusevariandid. Iga variant annab teatud<br />
arv punkte.<br />
Suhte kontekstis sisaldab sõltuv tabel välisvõtit. Sõltuv tabel on välisvõtme kaudu<br />
seotud primaarse tabeliga (peremeestabeliga).<br />
Järgnevalt esitatakse selle algoritmi kasutatav küsimustik ja vaadeldakse lühikest<br />
näidet.<br />
Küsimus<br />
Mis tüüpi suhtega on<br />
tegemist peremeestabeli<br />
ja sõltuva tabeli vahel?<br />
Milline on ühe<br />
peremeestabeli reaga<br />
seotud sõltuva tabeli<br />
ridade arv?<br />
Kui palju veerge on<br />
peremeestabelis, jättes<br />
arvestamata<br />
primaarvõtme veerud?<br />
Kui tehakse päring<br />
sõltuva tabeli kohta, siis<br />
kui sageli soovitakse<br />
andmeid ka<br />
peremeestabelist?<br />
Kas peremeestabelisse<br />
on lähiajal plaanis lisada<br />
uusi veerge või siduda<br />
uusi tabeleid?<br />
Valik<br />
Osa-terviku (agregatsiooni või kompositsiooni) seos,<br />
hierarhia. Nt. tellimus sisaldab tellimuste ridu, kauba<br />
kategooria sisaldab alamkategooriaid. (20)<br />
Suhe võrdsete vahel. Kummalegi tabeli rida võib eksisteerida<br />
teise tabeli reast sõltumatult. Nt. õppejõud koostab<br />
dokumendi. (-10)<br />
Definitsioon. Peremeestabelis olevad andmed määravad<br />
sõltuvas tabelis olevate andmete tähenduse. Nt. õppeaine<br />
spetsifikatsioon ja õppeaine tegelik õpetamine. Kui<br />
olemitüüpide vahel on M:N seosetüüp, siis luuakse selle<br />
esitamiseks vahetabel. Suhe selle vahetabeli ja<br />
peremeestabeli vahel on defineeriv suhe.(-20)<br />
1 kuni 5 (20)<br />
5 kuni 100 (-10)<br />
100 ja rohkem (-20)<br />
Vähem kui 10 (20)<br />
10 kuni 20 (-10)<br />
Rohkem kui 20 (-20)<br />
Päringus soovitakse sageli andmeid peremeestabelist (30)<br />
Päringus ei soovita sageli andmeid peremeestabelist (-30)<br />
Jah (-20)<br />
Ei (20)
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Kas peremeestabelis ja<br />
ja sõltuvas tabelis<br />
toimub ajaperioodis<br />
sarnane arv lisamisi ja<br />
muutmisi?<br />
KOKKU PUNKTE<br />
Jah (toimub sarnane arv lisamisi ja muutmisi) (20)<br />
Ei (ei toimu sarnane arv lisamisi ja muutmisi) (-20)<br />
Denormaliseerimise protsess.<br />
- Määra mudelil olevate suhete prioriteedid.<br />
- Vali suhted.<br />
- Vasta suhte kohta küsimustikule<br />
- Denormaliseeri suhtes osalevad tabelid, kui küsimustiku tulemus on 10<br />
punkti või rohkem. Selleks loo suhtes osalevate tabelite põhjal üks uus<br />
tabel.<br />
- Mine tagasi punkti 2, kuni kõik suhted on läbitud.<br />
Näide:<br />
Tudeng<br />
matrikli_<strong>nr</strong><br />
eesnimi<br />
perenimi<br />
synni_aeg<br />
sugu<br />
aadress<br />
telefon<br />
e_mail<br />
Oppimine<br />
matrikli_<strong>nr</strong> (FK)<br />
aine_kood (FK)<br />
alguse_kuupaev<br />
eelregistreerimise_kuupaev<br />
lopetamise_kuupaev<br />
Aine<br />
aine_kood<br />
hindamisviis (FK)<br />
aine_seisund (FK)<br />
nimetus<br />
loomise_kuupaev<br />
kinnitamise_kuupaev<br />
ainepunkte<br />
loenguid<br />
laboreid<br />
harjutusi<br />
lyhisisu<br />
Aine_seisund<br />
aine_seisund<br />
nimetus<br />
kirjeldus<br />
Hindamisviis<br />
hindamisviis<br />
nimetus<br />
kirjeldus<br />
Joonis 8 Näidisandmebaasi struktuur enne denormaliseerimist.
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Suhe: Aine-Aine_seisund (Aine_seisund on peremeestabel ja Aine on sõltuv<br />
tabel)<br />
Küsimus<br />
Valik<br />
Mis tüüpi suhtega on tegemist peremeestabeli ja Definitsioon. (-20)<br />
sõltuva tabeli vahel?<br />
Milline on ühe peremeestabeli reaga seotud sõltuva 100 ja rohkem (-20)<br />
tabeli ridade arv?<br />
Kui palju veerge on peremeestabelis, jättes<br />
Vähem kui 10 (20)<br />
arvestamata primaarvõtme veerud?<br />
Kui tehakse päring sõltuva tabeli kohta, siis kui Päringus soovitakse sageli<br />
sageli soovitakse andmeid ka peremeestabelist? andmeid peremeestabelist (30)<br />
Kas peremeestabelisse on lähiajal plaanis lisada Ei (20)<br />
uusi veerge või siduda uusi tabeleid?<br />
Kas peremeestabelis ja ja sõltuvas tabelis toimub Ei (ei toimu sarnane arv lisamisi<br />
ajaperioodis sarnane arv lisamisi ja muutmisi? ja muutmisi; klassifikaatorid<br />
registreeritakse juba enne<br />
andmete ülekandmist<br />
andmebaasi, õppeainete<br />
andmeid aga lisatakse<br />
regulaarselt) (-20)<br />
KOKKU PUNKTE<br />
10<br />
Otsus: Kaaluda denormaliseerimist<br />
Suhe: Aine-Hindamisviis (Hindamisviis on peremeestabel ja Aine on sõltuv<br />
tabel)<br />
Küsimus<br />
Valik<br />
Mis tüüpi suhtega on tegemist peremeestabeli ja Definitsioon. (-20)<br />
sõltuva tabeli vahel?<br />
Milline on ühe peremeestabeli reaga seotud sõltuva 100 ja rohkem (-20)<br />
tabeli ridade arv?<br />
Kui palju veerge on peremeestabelis, jättes<br />
Vähem kui 10 (20)<br />
arvestamata primaarvõtme veerud?<br />
Kui tehakse päring sõltuva tabeli kohta, siis kui Päringus soovitakse sageli<br />
sageli soovitakse andmeid ka peremeestabelist? andmeid peremeestabelist (30)<br />
Kas peremeestabelisse on lähiajal plaanis lisada Ei (20)<br />
uusi veerge või siduda uusi tabeleid?<br />
Kas peremeestabelis ja sõltuvas tabelis toimub Ei (ei toimu sarnane arv lisamisi<br />
ajaperioodis sarnane arv lisamisi ja muutmisi? ja muutmisi) (-20)<br />
KOKKU PUNKTE<br />
10<br />
Otsus: Kaaluda denormaliseerimist
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Suhe: Tudeng – Oppimine (Tudeng on peremeestabel ja Oppimine on sõltuv<br />
tabel)<br />
Küsimus<br />
Valik<br />
Mis tüüpi suhtega on tegemist peremeestabeli ja Definitsioon (-20)<br />
sõltuva tabeli vahel?<br />
Milline on ühe peremeestabeli reaga seotud sõltuva 5 kuni 100 (-10) (keskmine<br />
tabeli ridade arv?<br />
hinnang)<br />
Kui palju veerge on peremeestabelis, jättes<br />
arvestamata primaarvõtme veerud?<br />
Kui tehakse päring sõltuva tabeli kohta, siis kui<br />
sageli soovitakse andmeid ka peremeestabelist?<br />
Kas peremeestabelisse on lähiajal plaanis lisada<br />
uusi veerge või siduda uusi tabeleid?<br />
Kas peremeestabelis ja sõltuvas tabelis toimub<br />
ajaperioodis sarnane arv lisamisi ja muutmisi?<br />
KOKKU PUNKTE<br />
Vähem kui 10 (20)<br />
Päringus soovitakse sageli<br />
andmeid peremeestabelist (30)<br />
Jah (-20) (ülikoolis on plaanis<br />
jätkata uute registrite<br />
väljatöötamist)<br />
Ei (ei toimu sarnane arv lisamisi<br />
ja muutmisi) (-20)<br />
-20<br />
Otsus: Mitte denormaliseerida<br />
Suhe: Aine – Oppimine (Aine on peremeestabel ja Oppimine on sõltuv tabel)<br />
Küsimus<br />
Valik<br />
Mis tüüpi suhtega on tegemist peremeestabeli ja Definitsioon.(-20)<br />
sõltuva tabeli vahel?<br />
Milline on ühe peremeestabeli reaga seotud sõltuva 100 ja rohkem (-20)<br />
tabeli ridade arv?<br />
Kui palju veerge on peremeestabelis, jättes<br />
10 kuni 20 (-10) (tulenevalt<br />
arvestamata primaarvõtme veerud?<br />
sellest, et toimus<br />
denormaliseerimine)<br />
Kui tehakse päring sõltuva tabeli kohta, siis kui<br />
sageli soovitakse andmeid ka peremeestabelist?<br />
Kas peremeestabelisse on lähiajal plaanis lisada<br />
uusi veerge või siduda uusi tabeleid?<br />
Kas peremeestabelis ja sõltuvas tabelis toimub<br />
ajaperioodis sarnane arv lisamisi ja muutmisi?<br />
KOKKU PUNKTE<br />
Päringus soovitakse sageli<br />
andmeid peremeestabelist (30)<br />
Jah (-20) (ülikoolis on plaanis<br />
jätkata uute registrite<br />
väljatöötamist)<br />
Ei (ei toimu sarnane arv lisamisi<br />
ja muutmisi) (-20)<br />
-60<br />
Otsus: Mitte denormaliseerida
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Joonis 9 Näidisandmebaasi struktuur peale denormaliseerimist.<br />
Õppejõu seisukoht – ei denormaliseeriks. Miinuseid on rohkem kui plusse.
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Parem lahendus oleks, kui andmebaasisüsteemid lubaksid tabelite andmeid<br />
ühendada sisemises skeemis, kuid kontseptuaalses skeemis jääksid tabelid<br />
lahku.<br />
Kontseptuaalne<br />
skeem<br />
Tabel 1 Tabel 2<br />
Sisemine<br />
skeem<br />
Tabeli 1 plokid<br />
Tabeli 2 plokid<br />
Joonis 10 Lähteolukord.<br />
Kasutajad soovivad teha päringu ja näha päringu tulemuses nii tabelist 1 kui ka<br />
tabelist 2 võetud andmeid.<br />
Kontseptuaalne<br />
skeem<br />
Tabel 1 +<br />
Tabel 2<br />
Sisemine skeem<br />
Tabeli 1 plokid<br />
+ Tabeli 2<br />
plokid<br />
Joonis 11 Denormaliseerimise praktika tänapäeva SQL-andmebaasides.<br />
Paraku on tänapäeva SQL-andmebaasisüsteemides tavaline praktika, et<br />
kontseptuaalses skeemis olevatele elementidele vastab üks-ühele element
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
sisemises skeemis (direct image) (vt. Joonis 11). Tänu sellele ei ole tagatud<br />
andmete sõltumatus. Kui soovitakse muuta andmete organisatsiooni sisemisel<br />
tasemel, siis tänapäeva SQL-andmebaasisüsteemides ei jää paraku sageli muud<br />
üle, kui teha muudatusi kontseptuaalses skeemis (denormaliseerida). See ei ole<br />
hea lahendus. Joonis 12 esitab parema lahenduse probleemile, mida<br />
denormaliseerimise tulemusel üritatakse lahendada. Kui andmebaasisüsteem<br />
kasutaks Joonisel 12 esitatud lahendust, siis näiteks päringu:<br />
SELECT *<br />
FROM Tabel1 NATURAL JOIN Tabel2;<br />
läbiviimiseks peab andmebaasisüsteem viima läbi vähem I/O operatsioone<br />
võrreldes Joonis 11 esitatud lahendusega.<br />
Kontseptuaalne<br />
skeem<br />
Tabel 1 Tabel 2<br />
Sisemine skeem<br />
Tabeli 1 plokid<br />
+ Tabeli 2<br />
plokid<br />
Joonis 12 Õigem lahendus probleemidele, mida denormaliseerimisega<br />
püütakse lahendada.
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
4. SQL-andmebaasi disain – kokkuvõte<br />
Kasutusjuhtude<br />
mudel<br />
Infovajaduste<br />
nimekiri<br />
Pädevusalade<br />
nimekiri<br />
Ärireeglid<br />
Domeenimudel<br />
Sõnastik<br />
Kontseptuaalne<br />
andmemudel<br />
Andmebaasioperatsioonide<br />
lepingud<br />
Seisundidiagramm<br />
Infosüsteemi<br />
rollide<br />
kirjeldused<br />
Reaalsete<br />
kasutusjuhtude<br />
kirjeldused<br />
Loogilise<br />
disaini<br />
andmemudel<br />
Transaktsioonanalüüs<br />
Tehnilised<br />
dokumendid<br />
andmebaasisüsteemi<br />
kohta<br />
Füüsilise disaini<br />
andmemudel<br />
Tabelite ja kitsenduste<br />
loomise laused<br />
Andmebaasiserveris<br />
talletatud<br />
rutiinid<br />
Trigerid<br />
Vaated<br />
Kasutajagruppide<br />
loomise laused<br />
Joonis 13 Mõnede olulisemate andmebaaside projekteerimisega seotud<br />
dokumentide omavahelised sõltuvused.
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Eelneval joonisel näitab nool sõltuva tulemi poole.<br />
Strateegilise analüüsi üheks ülesandeks on süsteemi skoobi (piiride) leidmine<br />
ning süsteemi tükeldamine allsüsteemideks. Allsüsteemide leidmine tähendab<br />
tegelikult "jaga ja valitse" (Divide et impera) põhimõtte rakendamist, mille<br />
kohaselt jagatakse keeruline ülesanne lihtsamalt saavutatavateks<br />
alamülesanneteks. Selle asemel, et hakata süsteemi arendama kui monoliitset<br />
tervikut, on võimalik süsteemi arendada osade kaupa – olulisemad osad enne,<br />
vähem olulised osad hiljem.<br />
Detailanalüüsi üheks tulemuseks on kontseptuaalne andmemudel.<br />
Kontseptuaalne andmemudel on mittetehniline mudel, mille eesmärk on<br />
kirjeldada nõudmised loodavale andmebaasile (milliseid andmeid seal tuleks<br />
hoida) ja teha lugejatele võimalikult hästi selgeks andmebaasis hoitavate<br />
andmete tähendus (semantika).<br />
Detailanalüüsi üheks tulemuseks on ka andmetega seotud kitsenduste leidmine.<br />
Selliste kitsenduste leidmisel tuleb arvestada ärireeglitega. Traditsiooniliselt<br />
kontseptuaalse andmemudeli esitamiseks kasutatavad olemi-suhte diagrammid<br />
ei paku võimalusi keerukamate kitsenduste diagrammil kujutamiseks ja seetõttu<br />
tuleks need panna kirja tekstina. Andmetega seotud kitsenduste leidmine ning<br />
nende hilisem süsteemis jõustamine on väga oluline, sest see aitab parandada<br />
andmete kvaliteeti. Andmete kvaliteet aga peaks olema andmebaasi pidaja üks<br />
põhilisi eesmärke, sest halva kvaliteediga andmed põhjustavad halva<br />
kvaliteediga (valede) otsuste langetamise.<br />
Kontseptuaalse andmemudeli põhjal leitakse teisendusreegleid kasutades<br />
esimene variant SQL-andmebaasi (baas)tabelitest ja nende tabelitega seotud<br />
kitsendused, sealhulgas primaarvõtme, unikaalsuse ja välisvõtme kitsendused.<br />
Peale esialgsete tabelite leidmist, rakendatakse formaalseid protseduure tabelite<br />
struktuuri parandamiseks.<br />
• Täiendav normaliseerimine (sageli öeldakse lihtsalt normaliseerimine).<br />
• Ortogonaalse disaini printsiibi rakendamine.<br />
Normaliseerimise ja ortogonaalse disaini printsiibi rakendamise eesmärk on<br />
vähendada andmete liiasust ning sellest tulenevalt andmete muutmise<br />
anomaaliaid. Mida täpsem on olnud analüüs ja mida rohkem on kasutatud<br />
mustreid või universaalseid mudeleid, seda vähem tuleb andmebaasi struktuuris<br />
muudatusi teha. Ideaalis võiksid kõik tabelid olla normaliseerimise tulemusena<br />
viidud viiendale normaalkujule. Täiendav normaliseerimine ja ortogonaalse<br />
disaini printsiibi rakendamine ei taga andmete liiasusest täielikku lahtisaamist.<br />
See ei ole ka vajalik, kuid andmebaasi arendajad peavad tagama, et igasugune<br />
liiasus on kontrollitud – st. andmebaasis ei ole võimalik registreerida üksteisega<br />
vastuolus olevaid fakte.<br />
Andmebaasis olevate andmete kitsendustele vastamise tagamiseks võib<br />
SQL-andmebaasisüsteemides kasutada.
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
• Deklaratiivsed kitsendused. Ühe kindla tabeliga seotud kitsendused ja üldised<br />
kitsendused (viimaseid luuakse CREATE ASSERTION käsuga).<br />
• Andmebaasi trigeri protseduurid e. trigerid.<br />
Miks ikkagi kontrollida andmete kitsendustele vastavust andmebaasi tasemel?<br />
Vastavad kontrollid võiks ju kirjutada sisse loodavasse rakendusse.<br />
Andmete kitsendustele vastavuse kontroll ainult andmebaasi kasutavas<br />
rakenduses ei ole hea mõte.<br />
• Kui andmebaasi hakkab kasutama uus rakendus, tuleb sellesse kitsenduste<br />
kontroll sisse kirjutada. Kui rakenduste arv suureneb, muutub ka raskemaks<br />
kitsenduste muutmine (muudatus tuleb sisse viia mitmesse kohta).<br />
• Kui andmete poole pöördutakse otse (nt. läbi andmebaasi administreerimise<br />
programmi), siis ei kontrollita kitsendustest kinnipidamist.<br />
Mõningate kitsenduste kontrolli võib dubleerida ka rakenduses, sest see<br />
võimaldab kasutajale anda kiirema tagasiside (parem kasutusmugavus) ning<br />
väldib vigaste andmete edastamist üle arvutivõrgu (võrgu koormuse<br />
vähendamine). Kui kitsendust ei õnnestu andmebaasi tasemel jõustada, tuleb<br />
seda igal juhul teha rakenduses, sest nagu vanasõnagi ütleb – parem pool muna<br />
kui tühi koor. Kuid andmebaasis jõustatud kitsendus on nagu teine kaitseliin. Kui<br />
esimene kaitseliin murdub võite ikkagi olla kindlad, et ebakorrektsed andmed ei<br />
jõua andmebaasi.<br />
Detailanalüüsi üheks tulemuseks on andmebaasioperatsioonide lepingud, mis<br />
kirjeldavad.<br />
• Eeltingimused, mis peavad olema täidetud, et operatsiooni saaks käivitada.<br />
• Järeltingimused, mis kirjeldavad operatsiooni täitmise tulemusena<br />
andmebaasis toimunud muudatusi.<br />
Operatsioonidest rääkides tuuakse võrdlust teatri lavaga. Laval on asjad ja<br />
inimesed. Lavale lastakse eesriie ette ja tõstetakse üles (toimub operatsioon).<br />
Järeltingimustes pannakse kirja, mis on laval muutunud võrreldes eesriide<br />
langetamise eelse ajaga (millised muudatused on toimunud andmebaasis).<br />
Näiteks mõni inimene on juurde tulnud, mõni ära läinud ja asjad on oma kohti<br />
muutnud. Kui mõni asi või inimene jäi oma kohale, siis pole sellele vaja<br />
järeltingimuses viidata. Eeltingimustes on kirjas tingimused, mis peavad olema<br />
täidetud, et eesriide langetamist saaks läbi viia.<br />
Andmebaasioperatsioonid pakuvad funktsionaalsetele allsüsteemidele andmete<br />
kasutamise teenuseid. Iga andmebaasioperatsiooni kohta võiks luua omaette<br />
andmebaasiserveris talletatud rutiini (funktsiooni või protseduuri). Iga registri<br />
rutiinid võiks koondada eraldi paketti.<br />
Idee on selles, et andmebaasi poole pöörduv programm kutsub andmete<br />
kasutamiseks välja rutiini. See tähendab, et andmebaasi poole pöörduvas<br />
programmis e. rakenduses pole SQL lauseid. Rakenduse programmeerija ei pea
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
SQL lausete kirjutamisega vaeva nägema. SQL laused on koondatud<br />
andmebaasiserveris talletatud rutiinidesse. Seal on neid vajadusel lihtne muuta.<br />
Nende muutmine on andmebaasi programmeerija ülesanne. Andmebaasiserveris<br />
talletatud rutiinid kasutavad omakorda vaateid või pöörduvad otse tabelite poole.<br />
Rakenduse andmebaasi kasutus seisneb andmebaasiserveris talletatud rutiinide<br />
väljakutsumises. Rakenduses on rutiinide väljakutsed jaotatud<br />
transaktsioonidesse. Transaktsioon võib sisaldada ühe või mitme rutiini<br />
väljakutsumist. Rutiinis omakorda on üks või mitu SQL lauset.<br />
Detailanalüüsi oluliseks tulemuseks on ka põhiolemitüüpide seisundidiagrammid.<br />
Seisundidiagrammil kirjeldatakse põhiolemitüübi võimalikud seisundid ja<br />
võimalikud üleminekud ühest seisundist teise. Lisaks saab kirjeldada<br />
valvurtingimusi, mis peavad olema täidetud, et seisund saaks muutuda.<br />
Andmebaas peaks olema projekteeritud nii, et selle põhjal saab teha päringuid –<br />
"Leidke olemid, mis on seisundis X" (näiteks: Leidke arved, mis on seisundis<br />
kinnitatud.) Sellised päringud võib andmebaasis realiseerida vaadetena.<br />
Lisaks peaks kuidagi kontrolllima, et registreeritavad olemite<br />
seisundimuudatused vastavad seisundidiagrammis kirjeldatule. Selleks võib<br />
kasutada trigereid.<br />
Oletame, et meil on tabelid:<br />
Tellimuse_seisundi_liik(tellimuse_seisundi_liik_id, nimetus)<br />
Primaarvõti(tellimuse_seisundi_liik_id)<br />
Alternatiivvõti (nimetus)<br />
Tellimus(tellimus_id, summa, kuupäev, tellimuse_seisundi_liik_id)<br />
Primaarvõti(tellimus_id)<br />
Välisvõti (tellimuse_seisundi_liik_id) Viitab<br />
Tellimuse_seisundi_liik(tellimuse_seisundi_liik_id)
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Koostamisel<br />
Tellimust ei soovita esitada<br />
Kustutatud<br />
[ Tellimuses on vähemalt üks rida; Igas reas on kauba kogus suurem kui 0 ]<br />
Esitatud<br />
Kliendihaldur<br />
veendub tellimuse<br />
korrektsuses ja<br />
täidetavuses<br />
Klient on esitanud enda kohta<br />
valeandmed; Tellimust pole<br />
võimalik täita.<br />
Kinnitatud<br />
Tellija ei tasu<br />
tähtajaks<br />
tellimuse eest<br />
Tühistatud<br />
Tellija tasub tellimuse eest<br />
Tasutud<br />
Tellitud kaup viiakse kliendile kohale<br />
Täidetud<br />
Joonis <strong>14</strong> Tellimuse seisundidiagramm.<br />
Tellimuse seisund ei saa muutuda suvaliselt ühest seisundist teise.<br />
Seisundidiagramm kirjeldab, millised seisundi üleminekud on lubatud.<br />
Andmebaasi mõttes on tegemist järeldusreeglitega – muudatus on lubatud vaid<br />
siis, kui on täidetud teatud tingimused. Näiteks.<br />
• Tellimuse saab kustutada SIIS ja AINULT SIIS, kui see on seisundis<br />
"Koostamisel".<br />
Paraku ei võimalda SQL keel järeldusreeglite deklaratiivset kirjeldamist<br />
andmebaasis (CREATE ja ALTER lausetes). Kontrolli läbiviimiseks tuleb<br />
kirjutada trigeri protseduur (triger).<br />
Triger võiks olla seotud tabeliga Tellimus ning kontrollida tellimuse seisundi<br />
muutmisel, kas taoline seisundi muutus on legaalne ning mittelegaalset
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
muudatust mitte lubada. Näiteks seisundis "koostamisel" olev tellimus saab<br />
minna seisundisse "esitatud" või selle võib kustutada. Seisundisse "esitatud"<br />
saab tellimus minna vaid siis, kui tellimusega on seotud mõni tellimuse rida ja<br />
kauba kogus sellel on suurem kui 0 (need on valvurtingimused). Seisundist<br />
"esitatud" saab tellimus minna seisundisse "kinnitatud" või "tühistatud", aga mitte<br />
seisundisse "koostamisel", "tasutud", "täidetud". Seisundis "esitatud",<br />
"kinnitatud", "tasutud", "täidetud" ja "tühistatud" olevat tellimust ei tohi kustutada.<br />
Sellise lahenduse probleem on, et lubatud seisundimuutused on programmi sisse<br />
kodeeritud. Äriprotsesside muutumisel tuleb programmi muuta. Paindlikum<br />
lahendus oleks lubatud seisundi üleminekute ja valvurtingimuste kirjeldamine<br />
andmebaasis (SQL-andmebaasi korral võiks nende kirjeldus olla mingis tabelis).<br />
Trigeri sündmuse tulemusel käivitunud protseduur loeb neid andmeid kontrolli<br />
läbiviimisel. Sellisel juhul pole vaja seisundidiagrammi muutumisel hakata<br />
programmi ümber kirjutama, vaid tuleb muuta andmebaasis seisundimuudatuste<br />
kirjeldusi.<br />
5. Realiseerimise (ehitamise) etapp<br />
Toimub eraldi disainitud allsüsteemide (andmebaaside ja rakenduste) lõplik<br />
realiseerimine ja integreerimine terviksüsteemi tasemel. Põhitegevusteks<br />
programmeerimine, testimine, loodud andmebaasi ja programmide<br />
integreerimine.<br />
6. Rakendamise (üleviimise) etapp<br />
Eesmärgiks on süsteemi ehitajate poolt realiseeritud terviksüsteemi üleviimine<br />
tellija keskkonda ning seal toimima panemine. Üheks oluliseks tegevuseks on<br />
siin andmete ülekandmine vana(de)st süsteemi(de)st uue süsteemi<br />
andmebaasi(desse). Seda nimetatakse andmesiirdeks.<br />
7. Hoolduse etapp<br />
Tellija keskkonnas toimiva süsteemi ülalhoidmine, vigade parandamine, jõudluse<br />
jälgimine, häälestamine, uute arendustööde käivitamine. See on pidev protsess.<br />
Andmebaasi toimimise tagamine, aga ka pisemate jooksvate<br />
paranduste/arendustööde tegemine, on andmebaasi administraatori ülesanne.<br />
Andmebaasi jõudluse jälgimisest ja häälestamisest saadav kasu on näiteks:<br />
- võib väheneda täiendava riistvara vajadus,<br />
- suurenev töökiirus parandab organisatsiooni töö efektiivsust ja suurendab<br />
klientide rahulolu.
TTÜ: <strong>Andmebaasid</strong>e projekteerimine (2012) © Erki Eessaar<br />
Teisest küljest – madal töökiirus vähendab töötajate tööindu ja tekitab klientides<br />
rahulolematust.<br />
8. Mõisted<br />
Eesti keeles<br />
Denormaliseerimine<br />
Klassifikaatorite tabel<br />
Töötava süsteemi jälgimine ja<br />
häälestamine<br />
Inglise keeles<br />
Denormalization<br />
Lookup table<br />
Reference table<br />
Monitoring and tuning of operational<br />
system.<br />
9. Kasutatud materjalid<br />
1. Celko, J., 1999. Joe Celko's Data & Databases: Concepts in Practice. Morgan<br />
kaufmann Publishers, Inc. 1999. 382 p.<br />
2. Connolly, T.M. & Begg, C.E., 2001. Database Systems. A Practical Approach<br />
to Design, Implementation and Management. Third Edition. Pearson<br />
Education, 2001. 1236 p.<br />
3. Date, C.J., 2007. Logic and Databases. The Roots of Relational Theory.<br />
Trafford Publishing. 445 p.<br />
4. Date, C.J., 2009. SQL and Relational Theory. How to Write Accurate SQL<br />
Code. O'Reilly. 404 p.<br />
5. Hoberman, S., 2002. Data Modeler's Workbench: Tools and Techniques for<br />
Analysis and Design. Wiley Computer Publishing. 472 p.<br />
6. Lighstone, S., Teorey, T. & Nadeau, T., 2007. Physical database design. The<br />
databse professional's guide to exploiting indexes, views, storage, and more.<br />
Morgan Kaufmann Publishers. 427 p.<br />
7. Muller, R.J., 1999. Database Design for Smarties. Using UML for Data<br />
Modeling. Morgan Kaufmann Publishers. 442 p.