# Teema: Andmebaasi kavandamise sisulised küsimused ## Küsimus: Andmebaasis on tabelid, millesse võib olla vaja teha muudatusi. Osadel kasutajatel on muudatuste tegemise õigus, neil kellel pole, peaks olema aga võimalus muudatusi soovitada, need soovitused jõustuksid peale muutmisõigusega kasutaja heakskiitu. See süsteem oleks inspireeritud sellest, kuidas toimivad pull request'id / merge request'ed GitHub ja GitLab keskkondades. Samasugune loogika on olemas ka näiteks Google Docsis (inimese saab lisada soovituse, mis vajab dokumeni omaniku heakskiitu). Kasutaja ei pruugi siinjuures tähistada andmebaasi kasutajat, tegemist võib olla rakenduse kasutajatega, ehk siis kirjetega tabelis `User`. Hea oleks, kui tegemist ei oleks mitte ühe tabeli spetsiifilise lahendusega, vaid üldise lahendusega, mida saaksid kasutada erinevad tabelid. Kuidas võiks sellist asja PostgreSQLiga teha? **Vastus:** Üks võimalus oleks luua soovitatud muudatuste jaoks tabelid.Soovituse_seisundi_liik(soovituse_seisundi_liik_kood, nimetus)Primaarvõti (soovituse_seisundi_liik_kood)Alternatiivvõti (nimetus)Tabelis Soovituse_seisundi_liik on registreeritud seisundid "esitatud", "vastuvõetud" ja "tühistatud".Muutmise_soovitus (soovitus_id, skeemi_nimi, tabeli_nimi, veeru_nimi, võti, väärtus, soovituse_aeg, soovitaja, soovituse_seisundi_liik_kood)Primaarvõti (soovitus_id)Alternatiivvõti (skeemi_nimi, tabeli_nimi, veeru_nimi, võti, soovituse_aeg, soovitaja)Välisvõti (soovituse_seisundi_liik_kood) Viitab Soovituse_seisundi_liik(soovituse_seisundi_liik_kood)Välisvõti (soovitaja) Viitab Kasutaja (kasutaja_id) Tabeli Muutmise_soovitus veerul soovituse_seisundi_liik_kood on vaikimisi väärtuseks seisundile "esitatud" vastav kood. Tabeli Muutmise_soovitus veerul soovituse_aeg on vaikimisi väärtuseks ajatempli leidmiseks mõeldud funktsiooni poole pöördumine. (skeemi_nimi, tabeli_nimi, veeru_nimi) identifitseerivad tabeli+veeru, kus soovitakse muudatust teha ning veerus võti olev väärtus identifitseerib rea tabelis, milles soovitakse muudatust teha. Muutmise_soovitus veerg võti võiks näiteks olla massiivitüüpi text[][] ning seal oleks registreeritud võtmeveergude nimede ja nende väärtuste tekstiliste esituste paarid. Alternatiiv oleks see esitada JSON objektina ja siis oleks veerg võti tüüpi JSONB. Variant oleks ka kasutata tüüpi hstore, millesse kuuluvad väärtused on võti-väärtus paaride hulgad. Tabeli Muutmise_soovitus veerg väärtus on tekstitüüpi (PostgreSQL puhul tüüpi TEXT), et registreerida soovitatud väärtuse tekstiline esitus. Kas soovituse esitamisel või ülevaatamisel tuleb kontrollida, et see on teisendatav sobivat tüüpi väärtuseks (a'la, keegi soovitab kuupäeva 31. veebruar 2022). Veeru tüübi saab kindlaks teha päringu abil INFORMATION_SCHEMA.columns süsteemikataloogi vaate põhjal, sest soovituse tabelis on skeemi, tabeli ja veeru nimi registreeritud. Tabel Muutmise_soovitus on mõeldud selleks, et soovitada UPDATE operatsioone. Kui soovitada saaks ka ridade lisamist (INSERT) või kustutamist (DELETE), siis selleks looksin eraldi tabelid (Lisamise_soovitus ja Kustutamise_soovitus). Tabelis Kustutamise_soovitus ei ole vaja veerge veeru_nimi ja väärtus. Tabelis Lisamise_soovitus ei ole vaja veerge veeru_nimi ja võti. Veerus väärtus peab olema lisatava rea esitus (sõltuvalt kasutatavast tüübist kas massiivina, JSON objektina või võti-väärtus paaride hulgana).Keerukust soovituste ülevaatamisele lisab see, kui samale väljale/reale on tehtud mitu soovitust. Ilmselt peaks ülevaatajale kõiki näitama ja andma talle võimaluse ühe valida või enda poolt mingi kombineeritud väärtus sisestada.Edasiarenduseks on näiteks võimalus määrata, kas kasutajale või kasutajate rollile (mida võib omada mitu kasutajat) veerud, mille jaoks on tal üldse lubatud muudatusi soovitada.Kastutaja (kasutaja_id, ....)Primaarvõti (kasutaja_id)Kasutaja_roll (kasutaja_roll_kood, nimetus)Primaarvõti (kasutaja_roll_kood)Alternatiivvõti (nimetus)Kasutaja_rolli_omamine (kasutaja_id, kasutaja_roll_kood)Primaarvõti (kasutaja_id, kasutaja_roll_kood)Välisvõti (kasutaja_id) Viitab Kasutaja (kasutaja_id)Välisvõti (kasutaja_roll_kood) Viitab Kasutaja_roll (kasutaja_roll_kood)Muutmise_soovituse_luba (skeemi_nimi, tabeli_nimi, veeru_nimi, kasutaja_roll_kood)Primaarvõti (skeemi_nimi, tabeli_nimi, veeru_nimi, kasutaja_roll_kood)Kui soovitada saab ka ridade lisamist või kustutamist, tuleks luua ka tabelid Lisamise_soovituse_luba ja Kustutamise_soovituse_luba.Õiguste poolelt soovitaksin lahendust, kus igale rakenduse lõppkasutajale (mille kohta on rida tabelis Kasutaja) vastaks ka eraldi andmebaasi kasutaja (seda on muide tehtud selles näiteprojektis) nii nagu soovitakse  SELLES artiklis andmebaasipõhise turvalisuse tagamise mudeli kohta. See võimaldab teha nii, et rakenduse kasutajatel, kes saavad soovitada muudatusi, on INSERT õigus tabeli Muutmise_soovitus suhtes, kuid ei ole UPDATE õigust tabelite suhtes, mille jaoks muudatusi soovitatakse. Rakenduse kasutajatel, kes saavad ise otse muudatusi teha on UPDATE õigus muudetava tabeli suhtes, kuid ei ole INSERT õigust tabeli Muutmise_soovitus suhtes. Muudatuste kinnitamiseks võiks luua plpgsql keeles kirjutatud funktsiooni, mis koostab muudatuste soovituse andmete põhjal dünaamiliselt SQL lause, mille abil muudatus ära teha, käivitab selle lause ja muudab ühtlasi soovituse seisundit. Kui funktsioonis kasutada SECURITY DEFINER määrangut, siis saab teha nii, et ülevaatajal on funktsiooni käivitamise õigus, kuid tal ei ole muutmisõiguseid soovituste tabeli ja tegelike andmetega tabeli suhtes. **Märksõnad:** PostgreSQL ## Küsimus: Igal isikul on null või rohkem meiliaadressi. Võib juhtuda, et mitu isikut jagavad ühte ja sama meiliaadressi. Kas selliste andmete hoidmiseks peaks tegema kokku kolm tabelit: meiliaadresside tabeli, isikute tabeli ja meiliaadresside ja isikute vahelist M:N seost esitava vahetabeli? **Vastus:** Ma arvan, et ei peaks.Kui andmebaasis oleksid tabelid:Isik (isik_id, ...)Primaarvõti (isik_id)E_meil (e_meil_id, e_meil)Primaarvõti (e_meil_id)Alternatiivvõti (e_meil)Isiku_meiliaadress (isik_id, e_meil_id)Primaarvõti (isik_id, e_meil_id)Välisvõti (isik_id) Viitab Isik (isik_id)Välisvõti (e_meil_id) Viitab E_meil (e_meil_id), siis päring, mis seob isikuandmed meiliaadressidega, peab lugema kolme tabelit. Eraldi meiliaadresside tabelil oleks mõtet, kui meiliaadressi kohta oleks vaja talletada veel andmeid - näiteks oleks tegemist põhiobjektiga, mille korral tuleb fikseerida selle seisund/staatus. Analoogiana võiks mõelda isiku nimele. Igal isikul on üks või rohkem nime komponenti (nt eesnimi, perenimi, isanimi) ning üks ja sama nimi võib kuuluda mitmele isikule. Lahendus, mille korral on eraldi tabel Isikunimi, kus oleksid näiteks registreeritud nimed nagu "Mari" ja "Maasikas", mida tuleks vahetabeli kaudu siduda tabeliga Isik, ei tundu mulle otstarbekas ja ma pole ka sellist lahendust kuskil kohanud. Selle asemel võiks luua tabelid.Isik (isik_id, ...)Primaarvõti (isik_id)Isiku_meiliaadress (isik_id, e_meil)Primaarvõti (isik_id, e_meil)Välisvõti (isik_id) Viitab Isik (isik_id)Kui primaarvõtme kitsenduses on veerud just selles järjekorras, siis tekib andmebaasis automaatselt liitindeks, kus isik_id on esimene veerg. Sellisel juhul pole vaja luua välisvõtme toetuseks veerule isik_id eraldi indeksit. Ühtlasi tagab selline primaarvõti, et sama meiliaadressi ei saa sama isikuga korduvalt siduda.Isiku_meiliaadress oleks antud juhul nn nõrk olemitüüp (weak entity type), mille eksemplari eksistents sõltub seotud tugeva olemitüüpi (strong entity type) Isik eksemplari olemasolust. Seega sobib Isik tabelile viitavale välisvõtmele ON DELETE CASCADE kompenseeriv tegevus. See  on loogiline, sest meiliaadress on lisainfo isiku kohta ja kui kustub isik, siis peaks kustuma ka lisainfo.Sellise kahe tabeliga lahenduse eelis ühe tabeliga lahenduse ees (meiliaadressid on salvestatud tabelis Isik kui massiivi väärtused, json objekt või XML objekt) on näiteks see, et lihtsam on jõustada reeglit, mille kohaselt samal isikul ei tohi olla sama meiliaadressi korduvalt. ## Küsimus: Kas ja millised probleemid võivad tekkida andmebaasirakenduse tegemisel kasutades mõnda ORM (Object-Relational Mappers, objekt-relatsioonvastenduse) vahendit? **Vastus:** SIIN (Sulaoja, K.M., Saarep, A. Cognate kasutajamugavuse parandamine ja arendustöö lihtsustamine) on 2024. aasta bakalaureusetöö, mille sisuks oli ühe Tallinna Tehnikaülikoolis õppetöö läbiviimist abistava süsteemi parandamine ning edasiarendamine. Ka süsteemi eelmine versioon tehti üliõpilaste poolt. Süsteemi realiseerimiseks kasutati Django ORMi. Jaotises 3.3.1 (lk 26-27) kirjutatakse ORM probleemidest ning jaotises 3.3.2 tuuakse näide, et need probleemid päriselt esinevad. ORM probleemide hulka kuulub see, et vahendi oskamatu kasutuse korral tehakse andmebaasi põhjal liiga palju päringuid ja see aeglustab süsteemi tööd. Autorid tõdesid, et süsteemi puhul "oli reageerimiskiiruse pudelikaelaks tagarakenduse kood ning Djangosse sisseehitatud objekt-relatsioonvastanduse ehk ORM-i (object-relational mapping) valekasutus".Autorid uurisid enne paranduste tegemist rakenduse tööd 63 registreeritud projekti ning hindamissüsteemi kaheksa tähtpunkti korral. "Selgus, et 63 projekti puhul tehakse 12124 erinevat baasipäringut, mille kogupikkus jäi keskmiselt vahemikku 6400-6700ms. Sealjuures 12117 neist olid märgitud sarnasteks, millest omakorda 7862 olid duplikaadid. Kogu aeg lokaalselt, mis kulus alates päringu vastuvõtust kuni vastuse saatmiseni (Total CPU time, andmete saatmine üle võrgu ei ole sisse arvestatud), jäi vahemikku 20-22 sekundit. Tootekeskkonna kogu ajakulu oli vahemikus 12-14 sekundit".Autorid kirjutasid rakenduse paranduste kohta: "Kõige suurema mõjuga neist oli baasipäringute viimine tsüklitest väljapoole. Varasemalt tehti tsüklites kokku mitutuhat duplikaadist baasipäringuid. Tsüklites päringute tegemine tõi esile ka jõudlust suuresti mõjutava N+1 probleemi, mis lahendati baasolemiga seotud andmete kohese baasist välja pärimisega. Lisaks üritati võimalikult palju eemaldada Django Model tüüpi objektide kasutust, kuna nende loomine on väga kulukas protsess. Selle asemel küsiti välja ning kasutati andmeid primitiivsete väärtustena. Optimeerimise tulemusena toodi baasipäringute arv alla 9-le päringule, mille tegemiseks kulus 10-14ms. Kusjuures enam ei tehta mitte ühtegi sarnast või duplikaadist baasipäringut. Lokaalselt kulub varasema 20-22 sekundi asemel päringule nüüd 140-160ms. Tootekeskkonnas aga veidi üle 300ms, mis tähendab, et päring on ligi 70 korda kiirem."ORMis tulenevaid probleeme: tabelite struktuuri kirjeldamine ORMi koodis võib viia halvasti struktureeritud andmebaasini, päringute kirjeldamine ORMi koodis võib viia vigaste või ebaefektiivsete andmebaasi päringute täitmiseni, suunab tegema valikuid, mis on rakenduse kiire valmimise seisukohast mugavad, kuid teises olukorras vähendab andmete kasutamise mugavust, surrogaatvõtme veeru nimega id automaatne lisamine,  kas on ikka meeles teisi võtmeid leida ja jõustada? tabelite ühendamise päringute käsitsi kirjutamine on tänu sellisele nimevalikule ebamugavam. oskamatu kasutus võib viia liigsete andmebaasipäringute käivitamiseni, loetakse rida ühest tabelist ja siis tsüklis seotud read teisest tabelist (iga rea küsimiseks eraldi lause), selle asemel, et kõiki neid andmeid ühe lausega küsida. Mõttearendus sellel teemal, kuidas ORM pakutav (objektorienteeritud) mõtteviis ja relatsiooniline mõtteviis on põhimõtteliselt erinevad, sest esimene nendest töötab üksikute olemitega teine aga nende hulkadega ning kuidas ORM propageeritav mõtteviis viib selleni, et andmebaasisüsteem peab tegema liigselt tööd (täitma liiga palju SQL lauseid) ning selle all kannatab süsteemi jõudlus.. ORM vahendi(te) probleemidele osutab see uuring 67 avatud lähtekoodiga tarkvara põhjal. Siin on veel üks suure hulga põhjendustega selgitus, miks üks arendaja loobus ORMi kasutamisest ning eelistab ise SQL lauseid kirjutada. Siin on arutelu, kus kõrvutatakse ORMi ja andmebaasiserveris talletatud rutiinidest, vaadetest ja hetktõmmistest koosneva virtuaalse andmete kihi kasutamist.Isegi ORMi kasutamise korral saab teha nii, et  rakendus kasutab andmebaasi läbi avaliku andmebaasi liidese e virtuaalse andmete kihi. Sellisel juhul loeks rakendus andmeid vaadetest (näiteks Djangos on see võimalik) ning muudaks andmeid kasutades andmebaasiserveris talletatud rutiine (näiteks Djangos on see võimalik). Andmete kitsendustele vastavuse kontroll toimuks andmebaasi tasemel (kasutades deklaratiivseid kitsendusi ja reegleid), mitte rakenduse tasemel nagu ORM vahendid üldiselt propageerivad. Rakenduse tasemele andmete kontrolli probleemiks on: üleliigsed päringud andmebaasi põhjal, mis kokkuvõttes aeglustavad ORM abil loodud programmi tööd, kontrollide ebapiisavus selles mõttes, et juhul kui samu andmeid kasutab samaaegselt mitu kasutajat, siis võivad need kontrollid lasta läbi reeglitele mittevastavaid andmeid. Kuigi eelnev näitab, et ORMi ja andmebaasi avalikku liidest saab koos kasutada, siis praktikas on need alternatiivid. Alternatiiv 1: Rakendus kasutab andmebaasi läbi ORMi. ORM vahend genereerib ise SQL koodi, millega loetakse ja muudetakse andmebaasis andmeid otse baastabelites. Selleks, et piirata kasutajate juurdepääsu teatud tingimustega tabeli ridadele, pakuvad andmebaasisüsteemid vahendeid nagu turvapoliitikad (PostgreSQL) või peeneteralised juurdepääsupiirangud. Alternatiiv 2: Rakendus kasutab andmebaasi läbi avaliku andmebaasi liidese, mille realiseerimiseks kasutatakse andmebaasis loodud vaateid, rutiine ja materialiseeritud vaateid e hetktõmmiseid. Rakendus ei pöördu otse baastabelite poole, vaid kasutab nendes olevaid andmeid läbi avaliku liidese. **Märksõnad:** rutiin, funktsioon, protseduur, hetktõmmis, materialiseeritud vaade, virtuaalne andmete kiht, andmebaasi avalik liides ## Küsimus: Kas kuskil on nähtav andmebaasitehnoloogiate suur pilt? **Vastus:** Suur pilt (1. juuni 2015 seisuga) erinevatest andmebaasitehnoloogiatest ning neid realiseerivatest tarkvarasüsteemidest. Kindlasti on nii mõnigi seal esitatud süsteem välja surnud ning on juurde tulnud uusi süsteeme (eriti erinevaid pilvepõhiseid süsteeme). Samas illustreerib ka see pilt andmebaasisüsteemide maailma liigirikkust ja keerukust. Siin ja siin aga on iga kuu uuendatav andmebaasisüsteemide populaarsuse indeks. ## Küsimus: Kas leidub kergesti kättesaadavat eestikeelset kirjandust SQL-andmebaaside kavandamisel ettetulevatest probleemidest ja nende lahendustest? **Vastus:** Tallinna Tehnikaülikooli üliõpilased on lõputöödena koostanud mustrite katalooge. Need lõputööd on kättesaadavad Tallinna Tehnikaülikooli digikogust. Muster on nimega kirjeldus, milles on esitatud probleem ja lahendus sellele probleemile. Samuti on kirjeldatud, millal seda lahendust rakendada ja kuidas rakendada lahendust uues kontekstis. Antimustrid, vastupidiselt, kirjeldavad probleemide halbu lahendusi, koos soovitustega, kuidas probleemi paremini lahendada. Analüüsi mudelite antimustrid. Disainimustrid üldistusseoste esitamise kohta SQL-andmebaasides. Disainimustrid kitsenduste jõustamise kohta PostgreSQL andmebaasis. Disainimustrid klassifikaatorite esitamiseks SQL-andmebaasides. Mitmekeelsete SQL-andmebaaside disainimustrid. Disainimustrid isikunimede hoidmiseks SQL‑andmebaasides. Selles töös on hea ülevaade nii maailma rahvaste kultuurilisest rikkusest nimede andmisega seoses kui ka nimede hoidmise tehnilistest lahendustest. Hierarhiliste andmete esitamine SQL-andmebaasides. Graafide esitamine SQL-andmebaasides. Infosüsteemi põhiolemite seisundite esitamine SQL-andmebaasides. Mõned failide salvestamise disainimustrid SQL-andmebaasi kasutavate andmebaasirakenduste jaoks. Mustrite teemaga seostub ka: Andmebaasi loogilise ja füüsilise disaini antimustrite esinemine mõnedes vaba tarkvara poolt kasutatavates SQL-andmebaasides. Lisaks sellele on tehtud lõputöid, kus mustreid pole kirja pandud, kuid kus on uuritud andmebaaside disaine ja tehtud nendega eksperimente. Mitme väite ühe andmeväärtusena esitamise eelised ja puudused SQL-andmebaasides. Mõned uuritavad disainid kasutavad JSON, JSONB või massiivitüüpi veergu. Lisan, et peale selle lõputöö kirjutamist on lisandunud PostgreSQLi arsenali jsonb_set funktsioon, mis muudab andmete muutmise lihtsamaks, st ei ole enam vaja tervet hierarhia väärtust uuesti andmebaasi kirjutada. Universaalne andmebaasi disain ja selle probleemid. Puuduvate andmete esitamine SQL-andmebaasides. Sisulise tähendusega võtmed vs. surrogaatvõtmed SQL-andmebaasides. Mõned võimalused ridade ajaloo säilitamiseks SQL-andmebaasides. Denormaliseerimise praktika uurimine ühe SQL-andmebaasi näitel. SQL-andmebaasides olevate andmebaasiobjektide nimetamine. Töös keskendutakse kitsendustele, kuid tehakse ka üdisemaid tähelepanekuid nimede andmise kohta. Andmebaasi optimeerimine ning selles toimuvate operatsioonide jõudluse analüüs ühe Oracle andmebaasi näitel. Päringu filtri predikaadi automaatne lihtsustamine kahe SQL-andmebaasisüsteemi näitel. Reapõhise ja veerupõhise andmete salvestamise võrdlus kahe SQL-andmebaasisüsteemi näitel. Vaadete mõju päringute täitmisplaanide koostamisele kahe andmebaasisüsteemi näitel. Isikute nime alusel otsimise erinevad võimalused PostgreSQLis. Andmebaasis kirjutamise skeemi ja JSON dokumentide kasutamise mõju PostgreSQL ja MongoDB andmebaasirakenduste loomisele. **Märksõnad:** bakalureusetöö, magistritöö, teemad, eesti keel ## Küsimus: Kas olemasolevate "päriselu" SQL-andmebaaside disaini kvaliteet on hea? **Vastus:** Selliseid andmebaase on loodud nii palju, et üldistavalt kõigi kohta midagi öelda on võimatu. Saan öelda, et andmebaasides, mida olen ise lähemalt uurinud, mida on uurinud minu juhendatavad üliõpilased või mida on uuritud avaldatud teadustöödes, leidub kahjuks palju probleeme.Järgnevaga tahan ma öelda, et Te saate, võite ja isegi peate tegema paremini! Hästi kavandatud andmebaasi on palju lihtsam ja mugavam kasutada kui halvasti kavandatud andmebaasi. Hästi kavandatud andmebaasile on lihtsam ja mugavam luua andmebaasirakendust kui halvasti kavandatud andmebaasile.Toon järgnevalt näiteid.Magistritöös "E-kaubandusettevõtte X andmekvaliteedi analüüs ja parendamine" uuriti e-kaubanduse ettevõtte andmebaasi andmekvaliteedi seisukohast, pakuti välja protseduur selle püsivaks parandamiseks ning viidi parandusi ka ellu. Ettevõtte e-poe andmebaas põhineb maailmas ülipopulaarsel sisuhaldusprogrammil WordPress ning pistikprogrammil WooCommerce ja teistel väiksematel pistikprogrammidel. Autor kirjutab, et "W3techs andmete järgi on 2022. aasta oktoobrikuu seisuga sisuhaldussüsteemi WordPressi turuosa sisuhaldussüsteemide hulgas 64.2%. 43% maailma veebisaitidest on loodud WordPressi põhjal. WordPressil põhineva WooCommerce tarkvaral on suurim – 29% suurune – turuosa e-poe tarkvarade hulgas." Teiste sõnadega - kõik leitud andmebaasi disaini probleemid ja nende esinemise võimalikud tagajärjed kummitavad kõiki nende süsteemide kasutajaid, keda on palju. Autor toob välja kuus erinevat tüüpi probleemi (vt jaotis 9.1), kusjuures igal probleemi tüübil on hulk erinevaid alamprobleeme e märke nende probleemide esinemisest.Bakalaureusetöös "Ettevõttesisese tarkvara täiendamine - kasutajaliidese ja andmebaasi kavandamine ning sobivuse hindamine" täiendati tuntud ettevõtte poolt enda tarbeks loodud tarkvara inimressursside planeerimise funktsionaalsusega. Töö üheks osaks oli olemasoleva andmebaasi dokumenteerimine (dokumentatsioon puudus) ja selle andmebaasi analüüsimine disainiprobleemide seisukohalt. Autorid leidsid 20 erinevat tüüpi probleemi (vt jaotis 4.2).Bakalaureusetöös "E-poe andmete migreerimine PostgreSQL andmebaasist Microsoft SQL Serveri andmebaasi" kanti e-poe tarkvara asendamise raames e-poe andmed PostgreSQL andmebaasist Microsoft (MS) SQL Serveri andmebaasi. Lähteandmebaas oli osa valmislahendusest ehk karbitootest ja sihtandmebaas oli ettevõtte enda arendajate kätetöö. Töö ühe tulemusena analüüsiti sihtandmebaasis olevat nelja tabelit, kuhu andmesiirde tulemusel andmeid üle kantakse. Autor leidis sihtandmebaasi tabelite disainis 20 erinevat tüüpi probleemi (vt jaotis 5.1). Töös dokumenteeriti ka lähteandmebaasi (karbitoote) andmebaas. Igaüks võib ise seda uurida, kuid ka seal on palju andmebaasi disaini probleeme.Bakalaureusetöös "Andmebaasi loogilise ja füüsilise disaini antimustrite esinemine mõnedes vaba tarkvara poolt kasutatavates SQL-andmebaasides" otsitakse andmebaasi disaini antimustrite esinemisi avatud lähtekoodiga rakenduste Postbooks (ettevõtte ressursside planeerimise süsteem; andmebaas tehtud PostgreSQLis) ja OpenEMR (arstipraksise haldustarkvara; andmebaas tehtud MySQLis) andmebaasidest. Autor leidis uuritud andmebaasides 12 erineva andmebaasi disaini antimustri esinemisi. Autor kirjutas: "Mõlema andmebaasi disain kannatab liigse denormaliseerimise, paralleelsete veergude, välisvõtmete ebapiisava deklareerimise ja klassifikaatorite tabelite puudumise tõttu.". Töös viidatakse M. Blaha 2001. aastal avaldatud uurimusele 35 päriselu andmebaasi disaini kvaliteedi kohta. Blaha leidis nendest andmebaasidest palju vigu nagu näiteks erinevat tüüpi kitsenduste puudumine. Lõputöö autor tõdeb: "Võib väita, et alates Blaha uurimuste avaldamisest on olukord mingil määral paranenud, aga mitte palju."Bakalaureusetöös "EE Tele2 müügiandmete andmetabelite kvaliteedikontroll ja dokumenteerimine" kontrolliti ja parandati Tele2 olulise müügiprogrammi poolt kasutatud andmetabelites olevate andmete kvaliteeti. Andmekvaliteedi probleeme oli palju. Lk 20 toodi autori poolt välja ka mõned andmebaasi disaini probleeme (kokku viis erinevat tüüpi probleemi). Paljud autori viidatavad andmekvaliteedi probleemid osutavad sellele, et süsteemis on ebapiisavalt realiseeritud andmete reeglitele vastavuse kontroll, sh ilmselt on andmebaasides palju deklaratiivseid kitsendusi puudu. Samuti esineb liigset andmete dubleerimist (sama info erinevates veergudes) ja puudub klassifikaatorite tabeleid.PostgreSQL andmebaaside disainivigade otsimise päringute abil tehtud uurimuste kohta kirjutatud teadusartiklites (Eessaar, 2021; Eessaar, 2022; Eessaar 2023) on uuritud nelja pika arenduse ajalooga ja endiselt aktiivselt kasutuses oleva rakenduse PostgreSQL andmebaasi. Kolm nendest rakendustest on avatud lähtekoodiga. Need programmid on FusionForge (avatud lähtekoodiga arenduse haldamise tarkvara; andmebaasis 206 baastabelit), LedgerSMB (avatud lähtekoodiga ettevõtte ressursside planeerimise tarkvara; andmebaasis 162 baastabelit), OTRS Community Edition (avatud lähtekoodiga lahendamist vajavate probleemide haldamise tarkvara; andmebaasis 116 baastabelit) ja Stansoft (finantsarvestuse tarkvara; andmebaasis 174 baastabelit). Eessaar (2021) leidis nendest andmebaasidest kokku 36 erinevat tüüpi probleemi seoses deklaratiivsete kitsendustega. Eessaar (2022) leidis nendest andmebaasidest kokku veel 31 erinevat tüüpi probleemi seoses andmebaasi kontseptuaalse (loogilise) skeemiga. Eessaar (2023) leidis 30 erinevat tüüpi probleemi seoses andmebaasiobjektide nimetamisega. Paljudel nendel probleemidel on veel alamprobleeme e märke nende probleemide esinemisest.Artiklis Documenting Database Usages and Schema Constraints in Database-Centric Applications analüüsisid autorid 3113 avatud lähtekoodiga andmebaasirakendust, mis suhtlevad andmebaasisüsteemiga JDBC draiveri vahendusel ja mille korral tuleb andmebaasi skeem luua SQL lausete käivitamise tulemusel, mitte ei looda skeemi automaatselt ORM vahendi poolt. Igal rakendusel oli üks või rohkem SQL faili. Autorid leidsid primaarvõtme deklaratsioone 5086 SQL failist. Primaarvõtmeid deklareeriti 725 rakenduse korral, mis on 23.29% kõigist vaadeldud rakendustest. Autorid leidsid välisvõtme deklaratsioone 2196 SQL failist. Välisvõtmeid deklareeriti 379 rakenduse korral, mis on 12.17% kõigist vaadeldud rakendustest. Mis lahendust autorid sellele probleemile pakkusid? Luua programm, mis analüüsib staatiliselt rakenduse lähtekoodi ja andmebaasi skeemi ning annab tulemuseks rakenduse lähtekoodi dokumentatsiooni selle kohta, millistes meetodites/operatsioonides jõustatakse milliseid piiranguid andmetele. Kui rakenduse lähtekood või andmebaasi skeem muutub, siis saab kohe genereerida parandatud dokumentatsiooni. Seotud tööde all viidatakse uuringutele, kuidas olemasolevas kitsendusteta andmebaasides olevate andmete analüüsimise kaudu leida tabelite kandidaatvõtmeid, välisvõtmeid ja muid piiranguid (assotsiatsioonireeglid - kui kehtib tingimus A, siis peab ka kehtima tingimus B).Nimetatud töödest leiab viiteid veel erinevatele teadusartiklitele, milles on uuritud olemasolevate SQL-andmebaaside disaini. Kõik need uuringud on leidnud palju probleeme.Nagu öeldud, on paljudes SQL-andmebaasides probleemiks, et andmebaasi tasemel kitsendusi ei jõustata (arendajatele ei ole see "loomulik tegevus" ja "hügieeni osa"). See on omakorda viinud selleni, et süsteemide mittefunktsionaalsetesse nõuetesse on hakatud nõudeid andmebaasis loodavatele kitsendustele kirja panema.  Näiteks SIIN on viide Eesti riigi infosüsteemidele kehtestatud üldistele mittefunktsionaalsetele nõuetele, mida kõikide selliste süsteemide loomisel peab järgima. Täpsemalt viidatakse andmebaaside kohta käivale alamosale ning sealt on näha, et ilmutatult on toodud välja nõue primaarvõtmete ja välisvõtmete deklareerimise kohta. **Märksõnad:** Wordpress, WooCommerce ## Küsimus: Kas olemasolevates "päriselu" SQL-andmebaasides jõustatakse välisvõtme kitsendusi? **Vastus:** Mitte nii palju kui peaks.B. Karwini SQL-andmebaasi disaini antimustrite raamatu peatükis 5 (Keyless Entry) esitatakse antimuster Leave Out the Constraints, et andmebaasis puuduvad välisvõtme kitsendused.M. Blaha 2001. aasta artiklis A Retrospective on Industrial Database Reverse Engineering Projects-Part 2 uuris 35 pöördprojekteeritud andmebaasi. Ta tõdes, et vaid 10% andmebaasidest deklareerib välisvõtmeid ning isegi nendes, kus välisvõtmeid deklareeritakse, on osad puudu.Artiklis Managing Technical Debt in Database Schemas of Critical Software räägitakse andmebaasi tehnilisest võlast ja võla näitena kasutatakse välisvõtme kitsenduste puudumist andmebaasist. Autorid viitavad OSCAR Electronic Medical Record tarkvarale, mida kasutavad sajad Kanada tervishoiuasutused. Selle andmebaasis on üle 450 tabeli ja mõnes tabelis on üle tuhande veeru.  Autorid täheldasid, et suhteliselt palju välisvõtme kitsendusi on andmebaasist puudu ja andmebaasis on seega palju üksteisega sidumata tabeleid. Kasutatav andmebaasisüsteem toetab välisvõtme kitsenduste deklareerimist. Viidete terviklikkuse kontroll toimub enamasti rakenduses.Artiklis Feral Concurrency Control: An Empirical Investigation of Modern Application Integrity kirjeldatakse Ruby on Rails raamistikus loodud 67 avatud lähtekoodiga rakenduse uurimise tulemusi. Artiklis uuritakse unikaalsuse ja viidete terviklikkuse kitsenduste jõustamist rakenduse tasemel olukorras, kus andmeid muudab korraga mitu kasutajat. Stressitestil väga suure samaaegsete kasutajate arvuga (64) muutus rakenduse tasemel realiseeritud viidete terviklikkuse kontroll peaaegu väärtusetuks, sest andmebaasi jõudis väga palju viidete terviklikkust rikkuvaid andmeid. Samas, kui tabelites olid deklareeritud välisvõtme kitsendused, siis ei juhtunud seda kunagi.  Artikli järeldustes tõdeti: "Andmete samaaegse kasutamise reguleerimise lahenduste sisseehitamine rakendusraamistikesse või üksikutesse rakendustesse on kallis, veaohtlik ja raske ettevõtmine, mis eirab andmebaaside valdkonnas aastakümneid sellel suunal tehtud tööd. Kuigi see lähenemine on piisav, et tagada meie analüüsitud süsteemide puhul umbes 87% kitsenduste korrektne jõustamine, võib ülejäänute puhul andmete kontrollimine paljudes kaasaegsete ORMides viia kitsendustele mittevastavate andmete registreerimiseni." Bakalaureusetöös "Ettevõttesisese tarkvara täiendamine - kasutajaliidese ja andmebaasi kavandamine ning sobivuse hindamine" täiendati tuntud ettevõtte poolt enda tarbeks loodud tarkvara inimressursside planeerimise funktsionaalsusega. Töö üheks osaks oli olemasoleva andmebaasi dokumenteerimine (dokumentatsioon puudus) ja selle andmebaasi analüüsimine disainiprobleemide seisukohalt. Autorid leidsid 20 erinevat tüüpi probleemi (vt jaotis 4.2). Üks nendes probleemidest (vt jaotis 4.2.14) on mõned puuduvad välisvõtme kitsendused (st enamik nendest kitsendustest on siiski jõustatud).Bakalaureusetöös "Andmebaasi loogilise ja füüsilise disaini antimustrite esinemine mõnedes vaba tarkvara poolt kasutatavates SQL-andmebaasides" otsitakse andmebaasi disaini antimustrite esinemisi avatud lähtekoodiga rakenduste Postbooks (ettevõtte ressursside planeerimise süsteem; andmebaas tehtud PostgreSQLis) ja OpenEMR (arstipraksise haldustarkvara; andmebaas tehtud MySQLis) andmebaasidest. Autor leidis uuritud andmebaasides 12 erineva andmebaasi disaini antimustri esinemisi. Autor kirjutas xTuple Postbooks kohta: "Välisvõtmed on üldiselt deklareeritud, samas on palju kohti, kus oleks võinud kasutada välisvõtit." Samas OpenEMR andmebaasis välisvõtme kitsendused puudusid.Magistritöös "E-kaubandusettevõtte X andmekvaliteedi analüüs ja parendamine" oli eesmärgiks saavutada väikese e-kaubandusettevõtte andmekvaliteedi püsiv paranemine. Ettevõte peab e-poodi kasutades ülipopulaarset sisuhaldussüsteemi WordPress ja selle pistikprogrammi WooCommerce. Ettevõtte andmebaas oli realiseeritud MySQLis ja ja see moodustus WordPressi ning selle pistikprogrammide tabelitest. Ühelgi ettevõtte andmebaasi tabelil ei olnud välisvõtme kitsendusi. Autor kirjutas: "Andmebaasi 52 tabelist 39 põhinevad salvestumootoril MyISAM, mis ei toeta välisvõtmete kitsendusi. Ülejäänule 13-le andmebaasi tabelile oleks võimalik välisvõtme kitsendusi määrata."PostgreSQL andmebaaside disainivigade otsimise päringute abil tehtud uurimuste kohta kirjutatud teadusartiklites (Eessaar, 2021; Eessaar, 2022) on uuritud nelja pika arenduse ajalooga ja endiselt aktiivselt kasutuses oleva rakenduse PostgreSQL andmebaasi. Kolm nendest rakendustest on avatud lähtekoodiga. Need programmid on FusionForge (avatud lähtekoodiga arenduse haldamise tarkvara; andmebaasis 206 baastabelit), LedgerSMB (avatud lähtekoodiga ettevõtte ressursside planeerimise tarkvara; andmebaasis 162 baastabelit), OTRS Community Edition (avatud lähtekoodiga lahendamist vajavate probleemide haldamise tarkvara; andmebaasis 116 baastabelit) ja Stansoft (finantsarvestuse tarkvara; andmebaasis 174 baastabelit). Eessaar (2021) leidis, et Stansofti andmebaasis ei ole ühtegi välisvõtme kitsendust deklareeritud. Ülejäänud andmebaasides on välisvõtme kitsendusi deklareeritud, kuid uuring leidis, et kindlasti on paljud kitsendused deklareerimata. Näiteks on FusionForge andmebaasis 31.6% (65), OTRS andmebaasis 15.5% (18) ja LedgerSMB andmebaasis 4.9% (8) tabelitest sellised, mis on justkui saared - nendes ei ole ühtegi välisvõtme kitsendust ja nendele ei viita mitte ükski välisvõtme kitsendus. Olemasolevate unikaalsuse kitsenduste ja veerunimede alusel leiti, et FusionForge andmebaasis on 7.9% (87), Stansofti andmebaasis on 4.4% (84), OTRS andmebaasis on 3.7% (36) ja LedgerSMB andmebaasis on 3% (29) veergudest sellised, millel puudub välisvõtme kitsendus. Artiklis Documenting Database Usages and Schema Constraints in Database-Centric Applications analüüsisid autorid 3113 avatud lähtekoodiga andmebaasirakendust, mis suhtlevad andmebaasisüsteemiga JDBC draiveri vahendusel ja mille korral tuleb andmebaasi skeem luua SQL lausete käivitamise tulemusel, mitte ei looda skeemi automaatselt ORM vahendi poolt. Igal rakendusel oli üks või rohkem SQL faili. Autorid leidsid välisvõtme deklaratsioone 2196 SQL failist. Välisvõtmeid deklareeriti 379 rakenduse korral, mis on 12.17% kõigist vaadeldud rakendustest. Miks neid kitsendusi siis ei jõustata? Mõned põhjused. Andmebaasis juba kasutusel olevate lahenduste jäljendamine uute arendajate poolt. Soov realiseerida andmebaasi läbivalt ühes stiilis. Üldine käegalöömine – teised lasevad üle jala, mis siis minagi pingutan. MySQLi MyISAM salvestusmootor, mis oli MySQLis vaikimisi valik kuni 2009. aasta detsembrini ja on ühe valikuna kasutusel praeguseni, ei toeta välisvõtme kitsendusi. InnoDB salvestusmootor, mis on praegu vaikimisi valik, toetab välisvõtme kitsendusi. Välisvõtmed võivad mõnikord puududa ka vanast harjumusest ja teadmatusest uute võimaluste kohta. Artiklis Managing Technical Debt in Database Schemas of Critical Software nimetatakse üleminekut MyISAM salvestusmootorilt InnoDB salvestusmootorile, kui võimalikku põhjust, miks tervishoiutarkvara Oscar andmebaasis on suhteliselt palju välisvõtme kitsendusi puudu - salvestusmootori muutumisel ei muudetud andmebaasi skeemi. Internetiavarustes kohtab endiselt küsimusi, kas välisvõtme kitsendused halvendavad andmete muutmise operatsioonide töökiirust ja arvamusi, et halvendavad ja seega ei peaks neid deklareerima. Kes nii arvavad ei võta muidugi arvesse, et viidete terviklikkuse kontroll rakenduses nõuab päringuid andmebaasist ja kuidas see saaks olla eriliselt kiirem. Samuti ei arvesta niimoodi arvajad, et välisvõtme kitsendused garanteerivad andmebaasisüsteemi jaoks andmete vastavust viidete terviklikkuse reeglile ja võimaldavad selle kaudu andmebaasisüsteemil rakendada tabeli elimineerimise teisendust, mis on üks päringute optimeerimise meetod. Seega väga väike mõju andmete registreerimise kiirusele on igati sobiv hind, et hiljem oleksid päringud nende andmete põhjal kiiremad. Ütleksin, et välisvõtme kitsenduste puudumine on teatud maailmavaate (andmebaas on passiivne koht andmete hoidmiseks, kogu töö andmetega käigu rakenduses), arenduskultuuri ja arendusfilosoofia tunnuseks. Eelnimetatud Oscar tarkvara puhul viidatakse juhtarendajate rakendusekesksele maailmavaatele, kui põhjusele, miks viidete terviklikkuse kontroll selles süsteemis toimub suures osas rakenduse tasemel. **Märksõnad:** võõrvõti, välisvõti, foreign key, fk, deklaratiivne kitsendus, declarative constraint, Wordpress, WooCommerce ## Küsimus: Kas puhta koodi põhimõtted on olulised ka andmebaaside korral? **Vastus:** Jah on! O'Reilly digitaalse platvormi vahendusel pääsete Te ligi Robert C. Martini raamatule Clean Code (Kuidas kasutada O'Reilly digitaalset platvormi?). Selle raamatu ideed kehtivad ning on olulised ka andmebaaside ja infosüsteemide ainete jaoks. See raamat jagab juhiseid vastutustundlikule arendajale. Täpselt nii nagu vastutustundlik arendaja üritab luua võimalikult puhast rakenduse koodi, üritab ta ka luua puhast andmebaasikeele koodi ja puhtaid mudeleid. Üldine idee on täpselt sama! Suure tõenäosusega hakkate neid tehiseid ise tulevikus lugema. Või kui ei hakka ise, siis hakkab keegi teine. Puhast artefakti (tehist) on hea ja meeldiv lugeda, sellest saab kergesti aru ning kokkuvõttes on tehist tänu sellele lihtsam edasi arendada. Samal ajal "räpane" tehis võib küll oma hetke eesmärki täita (hetkel see "töötab" nagu vaja), aga halva arusaadavuse ning loetavuse tõttu on seda raske parandada ja edasi arendada. Sellised tehised vajavad refaktoreerimist. Refaktoreerimist vajavad kohad leiab üles halva lõhna järgi. Eaglesoni seadus ütleb, et kui vaatasite viimati enda kirjutatud koodi rohkem kui kuus kuud tagasi, siis arusaamise mõttes võib see kood olla ka kellegi teise kirjutatud – arusaamiseks/meeldetuletamiseks tuleb sama palju vaeva näha. Mõned ütlevad, et Eagleson oli optimist ja tegelik ajaperiood on palju lühem. Mida puhtam kood, seda lihtsam on aru saada, mida olete ise kunagi teinud. Mida puhtam tehis, seda lihtsam on Teil ja teistel sellest aru saada. Täpselt nagu on olemas halvasti lõhnav lähtekood, leidub ka: halvasti lõhnavaid arhitektuure, halvasti lõhnavaid disaine, halvasti lõhnavaid andmebaasi disaine (Sama raamat elektrooniliselt) ja halvasti lõhnavaid mudeleid. Mudelite halbadest lõhnadest annab ülevaate ka see bakalaureusetöö ja selle töö edasiarendusena loodud kataloog. Kui Te ei taga enda loodavate tehiste puhtust, siis Te kogute tehnilist võlga. Tehniline võlg tähendab, et tehise muutmiseks on vaja liigselt pingutada. Nagu me kõik inimeste elust teame, siis võlg võib kiiresti kasvada ja kontrolli alt väljuda. Laenu võtta (võlgu jääda), võib teadlikult - lootuses, et see tasub ennast ära, aga see on risk. Samamoodi, kui näiteks inimene kodu ei korista ja selle käest ära laseb, siis kui ükskord keegi külla tuleb või on vaja see maha müüa, siis kulub selle uuesti üleslöömiseks väga palju aega ja vaeva. Halvasti lõhnava mudeli illustratsiooniks on teatele lisatud ekraanipilt Enterprise Architect abil loodud modelleerimise projektist. Mudeli elemendid on seal süsteemitult segamini nagu puder ja kapsad ning mida suuremaks see projekt kasvab seda raskem oleks sealt vajalikku üles leida. **Märksõnad:** puhas kood, clean code ## Küsimus: Kas saaksite tuua mõne näite valesti valitud väljapikkustest ja selle põhjustatud probleemidest? **Vastus:** Valed valikud võivad põhjustada kannatusi, segadust, lisatööd ja mainekadu (süsteemi omanikule): https://reisile.postimees.ee/4484884/reisija-pidi-lisatasu-maksma-sest-tema-nimi-ei-mahtunud-lennupiletile. Antud näite korral oli isikunimede registreerimiseks mõeldud tekstiväljades lubatud maksimaalne märkide arv liiga väike. Andmebaasis võiks veergude eesnimi ja perenimi maksimaalne väljapikkus olla 50 märki. See võimaldaks registreerida ka pikemaid nimesid. Teatavasti on mõned isikunimed väga pikad. Kui arvestada väljapikkuste määramisel selliste nimedega, siis peaks nende veergude väljapikkus MS Accessi andmebaasis olema 255 märki (maksimaalne lubatud väljapikkus VARCHAR tüüpi veergude korral) ning andmebaasisüsteemides PostgreSQL ja Oracle võibolla isegi 1000 märki (sest seal pole 255 märgi piirangut nagu MS Accessis). Leian, et sellised väga suured väljapikkused pole siiski mõistlikud, sest: ülipikkade nimedega inimesi on väga vähe, neil on oma nimest ka lühivorm, liiga suur väljapikkus annaks kliendiks registreerijale võimaluse registreerida kahjulikku sisu nagu ründeskripti, kasutajaliideses tuleb sisestusvälja näidata suuremana kui valdava enamiku nimede puhul on vajalik. Leian, et oleks vale kasutada kõikide tekstitüüpi veergude puhul järjekindlalt maksimaalset võimalikkus väljapikkust või suurimat väärtust võimaldavat andmetüüpi ilma täiendavate kitsendusteta. Kui näiteks veerg perenimi on PostgreSQLis tüüpi Text ilma kitsenduseta, et maksimaalne väärtus selles veerus võib olla näiteks kuni 50 märki, siis see jätab skeemi lugejale (programmid, inimesed) vale mulje sellesse veergu oodatavatest andmetest. Rusikareegel: valige iga veeru jaoks selline andmetüüp + täiendavate kitsenduste komplekt, et kõik vajalikud väärtused saaksid sellesse veergu salvestatud, kuid suurim võimalik väärtus oleks võimalikult väike. **Märksõnad:** kitsendus, constraint, väljapikkus, isikunimi, isikunimed ## Küsimus: Kas saaksite tuua näite mõnest andmebaasis puuduvast kitsendusest, mis on tekitanud probleeme? **Vastus:** Hea näite kahe silma vahele jäänud kitsendusest toob Amazoni asutaja ja boss Jeff Bezos. Amazoni algusaastatel avastas ta sellest vea, mis lasi kliendil tellida negatiivse arvu raamatuid, mille järel kanti raha kliendi krediitkaardile. Hr Bezos viskas ühel videol nalja, et ilmselt tuli siis jääda ootama, kuni klient neile raamatud saadab. ## Küsimus: Kas sain aru õigesti, et iga klassifikaatori jaoks pole atribuutide definitsioonide tabelis vaja teha eraldi kirjeldust (et lihtsalt kui mõnel klassifikaatoril on olemas atribuut, mida teistel ei ole, siis lihtsalt täpsustan, millel klassifikaatoril on see olemas) ? **Vastus:** Vaatame näidet. Oletame, et olemi suhte diagrammis on sellised olemitüübid koos neid siduvate üldistustega:[Töötaja_seisundi_liik]-----------|>[Klassifikaator]<|---------[Töötaja_roll]Klassifikaatori atribuudid: kood, nimetusTöötaja rolli atribuut: kirjeldus Olemitüüpide definitsioonide tabelis on olemitüüpide Klassifikaator, Töötaja_seisundi_liik ja Töötaja_roll definitsioonid. Atribuutide definitsioonide tabelis on atribuutide Klassifikaator.kood, Klassifikaator.nimetus, Töötaja_roll.kirjeldus definitsioonid.Töötaja rollil ja töötaja seisundi liigil on pärimise kaudu ka atribuudid kood ning nimetus, kuid neid atribuutide definitsiooni tabelis eraldi välja ei tooda.Kui atribuutidele kood või nimetus kehtivad erinevate klassifikaatori alamtüüpide korral erinevad piirangud, siis tuleb need kirja panna vastavalt Klassifikaator.kood või Klassifikaator.nimetus definitsiooni. Näiteks piirang "Töötaja rolli kood peab olema täisarv, ning kõige väiksem võimalik väärtus on 100" pannakse kirja atribuudi Klassifikaator.kood definitsiooni. ## Küsimus: Kas see on tavapärane praktika koostada registrite vaheliste seoste puhul nn vahetabelid, ning kas on juhte, kus see pole vajalik? **Vastus:** Kui kontseptuaalses andmemudelis on mitu-mitmele seosetüüp, nagu näiteks:   [Protseduur]-0..*---------------0..*-[Protseduuri_kategooria]   , siis selle realiseerimiseks tekib SQL-andmebaasis vahetabel. See on kõige tavapärasem viis, kuidas sellist tüüpi seost realiseerida.   Kui kontseptuaalses andmemudelis on üks-mitmele seosetüüp, nagu näiteks   [Isik]-0..*-------------1-[Riik]   , siis tekib seosetüübi mitu-poolel oleva olemitüübi alusel tekkivasse tabelisse (antud juhul Isik) välisvõtme veerg ja kitsendus.   Mitu-mitmele seosetüübid on kontseptuaalses andmemudelis ülevaatamist vajav koht, sest väga võimalik, et selle taga peidab ennast eraldi olemitüüp koos täiendavate atribuutidega e lisainfo säilitamise vajadusega.   Seega näiteks selle asemel, et modelleerida:   [Töötaja]-0..*------0..*-[Töötaja_roll]   , oleks parem modelleerida   [Töötaja]-1------0..*-[Töötaja_rolli_omamine]-0..*------1-[Töötaja_roll]   ning olemitüübil Töötaja_rolli_omamine on atribuudid nagu alguse_aeg ja lõpu_aeg.   Mis puudutab seosetüübi alusel defineeritud olemitüüpi ja selle alusel tekkinud tabelit, siis see on valiku koht, kumba registrisse see paigutub. Paigutus tuleks otsustada selle järgi, millises funktsionaalses allsüsteemis hallatakse neid andmeid. Kui protseduuride kategooriate omamisi hallatakse protseduuride funktsionaalses allsüsteemis, siis kuuluks Protseduuri_kategooria_omamine protseduuride registrisse. Kui töötajate rolli omamisi hallatakse töötajate funktsionaalse allsüsteemi kaudu, siis kuuluks Töötaja_rolli_omamine töötajate registri alla. **Märksõnad:** kontseptuaalne andmemudel, erd, olemi-suhte diagramm, registrid, allsüsteemid, modelleerimine ## Küsimus: Kas SQL-andmebaasis saab jõustada deklaratiivsete kitsendustena assotisatsioonireegleid? **Vastus:** Jah saab. Vaatame konkreetset näidet. Oletame, et SQL-andmebaasis on tabel Kaup:Kaup(kauba_kood, hind, on_aktiivne)Primaarvõti(kauba_kood)Oletame, et kehtib reegel: Kui kaup on aktiivne, siis selle hind peab olema registreeritud."kaup on aktiivne" ja "hind peab olema registreeritud" on tingimused.Tähistame neid tähtedega P ja Q. Reegel "Kui kaup on aktiivne, siis selle hind peab olema registreeritud" on assotsiatsioonireegel (association rule). See reegel ütleb, et kui kehtib tingimus P, siis peab kehtima ka tingimus Q.Selle saab üldkujul kirja panna P=>Q => on implikatsiooni operaator. Sellist operaatorit SQL keeles kasutada ei saa, küll aga saab kasutada loogikaoperaatoreid AND, OR ja NOT. P=>Q on loogiliselt samaväärne kui NOT (P) OR QSeda, et need on loogiliselt samaväärsed, näitab lisatud failis olev loogikatabel e tõeväärtustabel. Sellises tabelis esitatakse loogikafunktsiooni kõik võimalikud väljundväärtused.  Seega saaks andmebaasis tabeli Kaup luua CHECK kitsenduse:CHECK(NOT (on_aktiivne=TRUE) OR hind IS NOT NULL)Andmete registreerimine ebaõnnestub vaid juhul, kui esimene tingimus (on_aktiivne=TRUE) on täidetud ja teine tingimus (hind IS NOT NULL) ei ole täidetud. Kõikidel ülejäänud juhtudel registreerimine õnnestub. **Märksõnad:** assotsiatsioonireegel, implikatsioon, tingimuslause ## Küsimus: Kas tühja stringi esinemise keelamine ja NOT NULL kitsendus on üks ja sama asi? **Vastus:** Ei ole! Tühi string on väärtus (kuigi väga lühike).NULL on tähis, et väärtust ei ole.NOT NULL veergu saab seega tühja stringi panna, sest see täidab tingimuse, et väljas peab väärtus olema.Kui näiteks soovida keelata veerus perenimi tühjad stringid, siis tuleb lisada CHECK kitsendusCHECK(perenimi<>'')MS Accessi graafilise kasutajaliidese kaudu määratav Allow Zero Length = No on selle alternatiiv.Tühja stringi ja NULLi võib kasutada selleks, et registreerida erinevad põhjused, miks väärtus puudub. Näiteks kui vastaval olemil ei ole sellist atribuuti (näiteks organisatsiooni perenimi), siis kasutatakse tühja stringi aga kui olemil on atribuut, aga selle väärtus pole teada, siis kasutatakse NULLi. Samas leian, et tühjade stringide lubamine tekitab asjatut segadust. Tabelid tuleks kavandada nii, et kui olemil ei ole mingit atribuuti, siis vastavas tabelis pole ka sellist veergu.CREATE TABLE Isik(isik_id INTEGER PRIMARY KEY,perenimi VARCHAR(50));INSERT INTO Isik (isik_id, perenimi) VALUES (1, '');INSERT INTO Isik (isik_id, perenimi) VALUES (2, NULL);Ülesanne: Leia isikud, kelle perenimi puudub.SELECT * FROM Isik WHERE perenimi=''; --tulemuses üks ridaSELECT * FROM Isik WHERE perenimi IS NULL; --tulemuses üks ridaSeega parem on nii - kui nime ei ole, siis NULL, kui on, siis midagi muud kui tühi string. Siin on võimalik neid lauseid viie andmebaasisüsteemi põhjal testida.NB! Andmebaasisüsteem Oracle käitub SQL standardis ettenähtust ning teistest andmebaasisüsteemidest erinevalt. Nimelt teeb Oracle automaatse asenduse ''=>NULL. Seega korrates eelnevaid lauseid Oracles (testitud nii 12c Enterprise Edition kui 23ai Free) on tulemus:SELECT * FROM Isik WHERE perenimi=''; --tulemuses null ridaSELECT * FROM Isik WHERE perenimi IS NULL; --tulemuses kaks ridaKui Oracles käivitada järgnev kood, siis rea lisamisel tekib NOT NULL kitsenduse viga.CREATE TABLE Isik(isik_id NUMBER(10) PRIMARY KEY,perenimi VARCHAR2(50) NOT NULL);INSERT INTO Isik (isik_id, perenimi) VALUES (1, '');Tulemus: SQL Error: ORA-01400: cannot insert NULL into ("SYSTEM"."ISIK"."PERENIMI") ## Küsimus: Kuidas jõustada PostgreSQL andmebaasis kitsendus, et tabeli veerus hoitakse rahasummat eurodes? **Vastus:** Kitsendust eurode kohta ei saa ega pea andmebaasi lisama! Oletame, et andmebaasis on tabel:Amet (amet_kood, nimetus, min_palk)Primaarvõti (amet_kood)Alternatiivvõti(nimetus)Veerus min_palk on ametikohal makstav minimaalne palk eurodes. Eeldame, et selles veerus olevad arvud esitavad palka eurodes - see on see, kuidas veerus olevaid andmeid interpreteeritakse ja andmebaasi kasutajale peab selle selgeks tegema. Veerg min_palk peaks olema tüüpi DECIMAL(täpsus,skaala) e NUMERIC(täpsus, skaala) ning ära tuleks määrata täpsus (precision) - kui mitu numbrikohta on väärtuses lubatud ja skaala (scale) - kui mitu numbrikohta on peale koma. Näiteks kui veerg min_palk oleks tüüpi DECIMAL(5,2), siis suurim võimalik minimaalne palk, mida saaks registreerida oleks 999.99 (viis numbrikohta, kaks kohta peale koma).Kui soovime mõne päringu tulemuses näha palka nii, et seal on ka juures euro sümbol, siis tuleb päringu (SELECT lause) tulemuses palga väärtust formaatida. Selleks saab kasutada näiteks to_char funktsiooni.SELECT amet_kood, nimetus, TO_CHAR(min_palk, '99999D99l') AS min_palk_formaaditudFROM AmetORDER BY amet_kood; "l" to_char mustris tähendab, et tuleks kasutada serveri lokaliseeringuga määratud valuutat. Kui päringu tulemuses on näiteks dollari sümbolid, siis saaks teha hoopis sellise päringu. || on stringide ühendamise e konkateneerimise operaator. SELECT amet_kood, nimetus, TO_CHAR(min_palk, '99999D99') || ' EUR' AS min_palk_formaaditudFROM AmetORDER BY amet_kood; **Märksõnad:** euro, valuuta, kitsendus, constraint, konkatenatsioon ## Küsimus: Kuidas määrata kindlaks, millises andmekesksesse allsüsteemi e registrisse (andmebaasi loogilisse alamosasse) mingid andmed kuuluvad? **Vastus:** Kui kasutada lähenemist, et iga registri kohta on infosüsteemi äriarhitektuuris ette nähtud eraldi funktsionaalne allsüsteem, mille kaudu toimub registris olevate andmete haldamine (lugemine ja muutmine), siis tuleks olemitüüp/tabel paigutada registrisse, millele vastava funktsionaalse allsüsteemi kaudu toimub selle andmete haldamine.Oletame, et süsteemis oleks vaja pidada arvet klientide, sadamakaide ning klientide poolt sadamakaide rentimise kohta. Millises registris peaksid olema andmed sadamakaide rentimiste kohta?Kolm valikut: Klientide register Juhul, kui kaide rentimiste andmeid hallatakse klientide funktsionaalse allsüsteemi kaudu. See tähendab, et kaide rentimisega seotud funktsionaalsus kirjeldatakse klientide funktsionaalse allsüsteemi all ning see funktsionaalsus realiseeritakse klientide halduse rakenduses/äpis. Kaide register Juhul, kui kaide rentimiste andmeid hallatakse kaide funktsionaalse allsüsteemi kaudu. See tähendab, et kaide rentimisega seotud funktsionaalsus kirjeldatakse kaide funktsionaalse allsüsteemi all ning see funktsionaalsus realiseeritakse kaide halduse rakenduses/äpis. Kaide rentimiste register Antud juhul arvatavasti parim valik. Kaide rentimistel on infosüsteemi seisukohast huvipakkuv elutsükkel (rentimiste võimalikud seisundid oleksid näiteks tasumata, tasutud, lõpetatud, tühistatud, ...) ja seetõttu oleks süsteemi äriarhitektuuri osaks ka kaide rentimiste funktsionaalne allsüsteem, mis haldab kaide rentimiste registris olevaid andmeid. ## Küsimus: Kuidas salvestada PostgreSQL andmebaasis tabelite muudatuste ajalugu? Lahendus peaks olema üldine, mitte ühe konkreetse tabeli spetsiifiline. Kas siin artiklis toodud lahendus on mõistlik? https://www.cybertec-postgresql.com/en/tracking-changes-in-postgresql/ **Vastus:** Andmebaasi kasutamise (sh andmemuudatuste jälgimist) nimetatakse auditeerimiseks (auditing). Andmebaasisüsteemid pakuvad sageli selleks erinevaid sisseehitatud võimalusi kuid kui neid ei ole või need pole sellised nagu vaja, siis trigerid on andmemuudatuste logimise realiseerimiseks sobilik valik. Artiklis pakutud lahendus on kahtlemata võimalik. Enne selle kasutusele võttu lugege palun siiski järgnevat.Trigeripõhiste lahenduste üldine probleem (mistahes andmebaasisüsteemis) Kuna trigereid ei saa panna reageerima SELECT sündmustele, siis ei saa trigerite abil logida andmete vaatamist. Trigeripõhise lahenduse üldine probleem PostgreSQLis Kui andmemuudatus ebaõnnestub, siis tühistatakse andmebaasisüsteemi poolt kõik vastavast transaktsioonis tehtud andmemuudatused ja kõik nende poolt algatatud muudatused (sh käivitunud trigerite tehtud muudatused). Seega ei saa trigerite abil logida ebaõnnestunud muudatusi. Oracles saaks näiteks andmemuudatuse logimise realiseerida autonoomse transaktsioonina, mis tähendab, et logi kirjutamine õnnestub isegi siis, kui muudatus, mis logi kirjutamise algatas, ebaõnnestub ja rullitakse tagasi. Konkreetse trigeripõhise lahenduse probleemid/nõrkused/mõttekohad. Triger ei logi kõikide ridade kiiret kustutamist (TRUNCATE operatsioon). Kui UPDATE lause reas midagi ei muuda, siis operatsiooni toimumise kohta registreeritakse kirje ikkagi. UPDATE lause puhul logitakse ka need väljad, milles andmed ei muutunud. Tuleks kaaluda, kas veergude old_val ja new_val puhul kasutada tüüpi JSON või JSONB (erinevus on väärtuse sisemises esitusviisis), arvestades kummagi eeliseid ja puuduseis. PostgreSQL juhendmaterjalides on igatahes öeldud: "In general, most applications should prefer to store JSON data as jsonb, unless there are quite specialized needs, such as legacy assumptions about ordering of object keys." Logitabeli maht läheb kiiresti väga suureks ja võiks mõelda selle sektsioonideks jagamisele (partitioning). SIIN kirjeldatakse veel erinevaid võimalusi PostgreSQLi andmebaasis toimuvate andmekäitluse operatsioonide logimiseks. Juttu on: andmebaasisüsteemi sisseehitatud logimise funktsionaalsusest (log_statement = all), mis tuleb administraatori poolt sisse lülitata, universaalsest trigeripõhisest lahendusest (Audit trigger 91plus), Küsimuses pakutud lahendusest eristab seda see, et saab logida TRUNCATE operatsioonide tulemusi, logitakse rohkem metaandmeid muudatuse kohta ja UPDATE operatsiooni puhul logitakse ainult muutunud väärtuseid. pgAudit laiendusest. Veel üheks lahenduseks ajalooliste andmete hoidmisel oleks disainida tabelid nii, et nendes saaks hoida ka ajaloolisi andmeväärtuseid. Sellist lähenemist pakub näiteks ankurmodelleerimine (siin on veidi eesti keeles). Põhimõtteliselt tekib selle kasutamisel iga olemitüübi atribuudi kohta eraldi tabel. Tabelite mugavamaks kasutamiseks luuakse vaated ja funktsioonid. Arendustööd aitab automatiseerida modelleerimiskeskkond, kus on muuhulgas ka koodigeneraator PostgreSQL jaoks (arendatud ühe meie ülikooli magistritöö tulemusena). Kui kartust tekitab see, et suure hulga tabelite ühendamine vähendab jõudlust, siis seda aitab kiirendada tabelite elimineerimise teisendus, mida oskab teha ka PostgreSQL. Selles lõputöös (on küll Oracle näitel, aga siiski) katsetatud ankurmodelleerimise andmebaasi.Selles magistritöös kirjeldatakse veel  ühte võimalust andmemuudatuste ajaloo säilitamiseks ja realiseeritakse märkimisväärne osa seda toetavast taristust (operaatorid, vaated, trigerid) PostgreSQL jaoks. **Märksõnad:** Postgres ## Küsimus: Kui tabelis Riik on (nimetus) alternatiivvõti, siis miks ei piisa selle jõustamiseks UNIQUE kitsendusest? Miks on vaja veerule nimetus ka NOT NULL kitsendust? **Vastus:** Hästi kavandatud tabelis peaks olema üks või rohkem kandidaatvõtit. Kandidaatvõtme väärtus + kandidaatvõtme veergude nimed + tabeli nimi on loogiline aadress, mille järgi andmebaasist tabeli rida üles leida. Kui aadressi pole või see on väärtuste puudumise tõttu mittetäielik, siis rida leida ei saa.Tüüpiliselt valitakse üks kandidaatvõti primaarvõtmeks e esmasvõtmeks, ülejäänud on alternatiivsed võtmed e alternatiivvõtmed.Primaarvõtme väärtus peab SQL reeglite järgi olema alati registreeritud. Isegi kui primaarvõtme veerule ei deklareerita NOT NULL, siis kontrollib andmebaasisüsteem, et igas reas oleks primaarvõtme väärtus olemas. Alternatiivvõti pole millegi poolest halvem. See oli võrdväärne kandidaat primaarvõtmeks, aga jäi valimata. Unikaalsuse tagamiseks on veerule vaja UNIQUE. Kuna vaikimisi on SQLis kõik mitte-primaarvõtme veerud valikulised (lubavad NULLe), siis on vaja veerule ka NOT NULL.Teiste sõnadega, kui süsteemianalüüs oleks näidanud, et mõnel riigil võib nimetus puududa, siis poleks (nimetus) selles tabelis kandidaatvõti ega ka alternatiivvõti. ## Küsimus: Kui teha töövihiku järgi projekti, siis millistele veergudele oleks mõistlik lisada vaikimisi väärtus? **Vastus:** Vaikimisi väärtused võiks lisada: Isik.isiku_seisundi_liik_kood - välisvõtme veerg; seisund, millesse isik läheb registreerimisel (elus) Isik.reg_aeg - hetke kuupäev + kellaaeg Isik.viimase_muutm_aeg - hetke kuupäev + kellaaeg Isikuandmete muutmisel jääb registreerimisaeg samaks, kuid viimase muutmise aeg muutub Kuna viimase muutmise aeg lisatakse juba rea lisamisel, siis saab veeru deklareerida kohustuslikuks ja vähendada andmebaasis seega NULLide kasutamist Klient.on_nõus_tülitamisega - vaikimisi andmekaitse põhimõttest lähtuvalt FALSE - see nõue on ka töövihikus Klient.kliendi_seisundi_liik_kood - välisvõtme veerg; seisund, millesse klient läheb registreerimisel (valige ise) Töötaja. töötaja_seisundi_liik_kood - välisvõtme veerg; seisund, millesse töötaja läheb registreerimisel (valige ise) X.x_seisundi_liik_kood - välisvõtme veerg; seisund, millesse x läheb registreerimisel (ootel) - selle määrab ära X seisundidiagramm X.reg_aeg - hetke kuupäev + kellaaeg X.viimase_muutm_aeg - hetke kuupäev + kellaaeg Kasutajakonto ning kõik klassifikaatorite tabelid - veerg on_aktiivne - pigem TRUE, sest selle väärtuse kasutamine uue rea lisamisel on tõenäolisem kui väärtuse FALSE kasutamine Töötaja_rolli_omamine.lõpu_aeg - kui kasutate PostgreSQLi, siis spetsiaalväärtus 'infinity' Nii saab lõpu aeg olla kohustuslik veerg ning päringud selle kohta, milline töötaja omab praegu millist rolli, on lihtsamad Kontseptuaalse andmemudeli atribuutide definitsioonides peaks kõigil atribuutidel, millel on vaikimisi väärtus, selle definitsioonis ära märkima. Meenutan, et kontseptuaalne andmemudel ei kajasta "välisvõtme" atribuute: Isik.isiku_seisundi_liik_kood, Klient.kliendi_seisundi_liik_kood, Töötaja. töötaja_seisundi_liik_kood, X.x_seisundi_liik_kood **Märksõnad:** töövihik, vaikimisi väärtus, default value ## Küsimus: Kui tekstilist väärtust hoidev väli või olla ka tühi, kas parem on lubada NULL väärtust või tühja stringi? Kas võib olla põhjust lubada ka mõlemat? **Vastus:** Tabeli väljast võivad väärtused puududa erinevatel põhjustel. Näiteks väärtus ei ole veel andmete sisestajateni jõudnud või sellist väärtust kunagi ei tekigi.  Üheks põhjenduseks, miks lubada tekstilises veerus NULLi ja tühja stringi oleks see, et need kodeerivad erinevaid puudumise põhjuseid.Siiski võib kergesti juhtuda, et NULLid ja tühjad stringid satuvad tabelisse juhuslikult ja kokkuvõttes on vaja kirjutada keerukamaid päringu tingimusi.SELECT isik_id FROM Isik WHERE eesnimi='' OR eesnimi IS NULL;(leia isikud, kellel eesnimi puudub)SELECT isik_id FROM Isik WHERE eesnimi<>'' AND eesnimi IS NOT NULL;(leia isikud, kellel on eesnimi olemas), selle asemel, et kirjutada lihtsalt:SELECT isik_id FROM Isik WHERE eesnimi IS NULL;SELECT isik_id FROM Isik WHERE eesnimi IS NOT NULL;Minu soovitus:- Keelake tekstilises veerus tühjad stringid ja tühimärkidest koosnevad stringid.- Kui väärtused võivad puududa, siis lubage NULLe.- Kui tabelis on veerg, millele vastavasse välja teatud ridade puhul väärtust kunagi ei teki, siis tuleb parandada andmebaasi disaini. liigutada veerg teise tabelisse ja muuta seal see veerg kohustuslikuks või luua algses tabelis seda olukorda kirjeldavad kitsendused Näiteks oletame, et tabelis Subjekt, kus on andmed nii füüsiliste isikute kui organisatsioonide kohta, on selline veerg nagu isiku isikukood. Parem oleks, kui oleks eraldi tabelid Osapool (isikute ja organisatsioonide ühiste atribuutide/seosetüüpide jaoks), Isik ja Organisatsioon. Veerg isikukood peaks olema tabelis Isik kohustuslik veerg. Kui tabelite struktuuri muutmine pole võimalik, siis tuleks jõustada reeglid nagu: kui (organisatsiooni) registrikood on määratud, siis isikukood peab puuduma. kui (isiku) isikukood on määratud, siis peab (organisatsiooni) registrikood puuduma. P => QKui kehtib tingimus P, siis peab ka kehtima tingimus QLoogiliselt samaväärne kui: NOT (P) OR QCHECK (NOT (reg_kood IS NOT NULL) OR isikukood IS NULL)CHECK (NOT (isikukood IS NOT NULL) OR reg_kood IS NULL)Puuduvate andmete kohta saab pikemalt lugeda SIIT. **Märksõnad:** puuduvad andmed, tühi string, empty string, allow zero length ## Küsimus: Küsimus kontseptuaalse andmemudeli kohta. Ma saan aru, et peame atribuute lisama X'le ja näiteks kliendile (on_nõus_tülitamisega), aga kuidas on erinevate standartsemate atribuutidega teiste olemitüüpide puhul. Nagu näiteks Töötaja_seisundi_liik, X_seisundi_liik või Riik: kas neile peaks ka lisama atribuudid nagu näiteks seisundi_liik_id, nimetus, kirjeldus. Vaadates vastuvõtuaegade näidisprojekti, siis seal näiteks pole neid atribuute kontseptuaalses andmemudelis välja toodud, kuid füüsilises disainis on. Samas X'i jaoks toome me ka kontseptuaalses andmemudelis selle koodi ja nimetuse välja. Seetõttu olen veidi segaduses ja lootsin, et ehk oleks võimalik natukene selgitust või suunamist saada sellele, missugused parameetrid lähevad kontseptuaalsesse andmemudelisse ning mis ainult füüsilisse disaini. **Vastus:** Kõikidel klassifikaatoritel (sh Riik, X_seisundi_liik, Töötaja_seisundi_liik jne) on pärimise kaudu atribuudid kood ja nimetus. Need atribuudid on kirjeldatud olemitüübis Klassifikaator ja alamtüüpide juures ei ole vaja neid uuest kirjeldada. Alamtüübi juures tuleb kirjeldada täiendavad atribuudid, mis on spetsiifilised konkreetsele alamtüübile - nii nagu Amet puhul on esitatud atribuut kirjeldus. Kirjeldusi on plaanis registreerida ainult ametite puhul, kuid mitte näiteks riikide ja töötaja seisundi liikide puhul. Teisendusreeglite rakendamise tulemusena tekivad taolisest kontseptuaalsest andmemudelist sellised tabelid nagu Töötaja_seisundi_liik (töötaja_seisundi_liik_kood, nimetus) ja Amet (amet_kood, nimetus, kirjeldus). Eraldi tabelit Klassifikaator ei looda, sest sellel oleks palju puuduseid. Kontseptuaalne andmemudel kirjeldab nõudeid andmetele, mitte andmebaasi tehnilist realisatsiooni konkreetse andmemudeli põhjal ja konkreetses andmebaasisüsteemis. Kontseptuaalses andmemudelis EI ESITATA:- "välisvõtme" atribuute - näiteks riigi_kood EI OLE Isik atribuut,- "surrogaatvõtme" atribuute - näiteks kui isik_id väärtused on kasutusel tarkvara siseselt, kuid mitte lõppkasutajate maailmas, siis olemitüübi Isik puhul atribuuti isik_id ei kirjeldata. X_kood on X atribuut seepärast, et see on sisuline ja tarkvara välises maailmas tähendust omav kood (nagu isikukood, auto registrikood, VIN kood, ainekood, üliõpilaskood jne). Kuna X_kood on sisuline atribuut, siis seda kirjeldatakse kontseptuaalses andmemudelis. **Märksõnad:** kontseptuaalne andmemudel, olemi-suhte diagramm, atribuut, atribuudid ## Küsimus: Meil on küsimus aadressi kohta. Kuidas on parem viis pakiautomaadi (kaupluse/kino/treeningsaali/...) aadressi andmebaasis salvestada? Me nägime, et Omniva lehel näidatakse seda niimoodi: "Ida-Viru maakond, Kohtla-Järve linn, Ahtme linnaosa, Maleva tn, 23". Tundub, et iga koma vahel on eraldi veerg, kuhu kirjutatakse andmed ja veerude nimed oleksid "asukoht_maakond, asukoht_linn, asukoht_linnaosa, asukoht_tänav, asukoht_tänava_nr". Kas me kasutame selle viisi, või saame parema loetavuse jaoks lihtsalt salvestada kogu stringi ühe veergu nimega "asukoht"? **Vastus:** Aadressiandmetel on keeruline struktuur ja palju erinevaid võimalikke komponente (riik, maakond, linn, vald, küla, talu, linnaosa, tänav, korter, hooneosa, ...). Erinevates riikides on võimalike komponentide hulk erinev. Kui ülesanne oleks pakkuda kasutajatele detailset aadresside otsimise võimalust, siis andmebaasi mõttes tähendaks see märkimisväärset hulka täiendavaid tabeleid, mille vahel komponentideks jagatud aadress ära jagada. Näitena saab Eesti Aadressiandmete Süsteemiga liidestumise juhendi jaotisest 3.2.4 Aadressi komponendid (tasemed) vaadata Eesti aadresside komponente.Kui eesmärk on pakkuda taustainfot pakiautomaadi kohta (nagu antud projektis), siis piisab vabatekstilisest atribuudist aadress."Sulgude ette" võib tõsta Maakonna. Maakond on klassifikaator.[Pakiautomaat]-0..*---------+asukoht-1-[Maakond]​Siit näete maakondade klassifikaatori väärtuseid. Kui pakiautomaadid võivad olla eraldi riikides, siis tõstaksin maakonna asemel "sulgude ette" riigi.​[Pakiautomaat]-0..*----------+asukoht-1-[Riik]Saaksite kasutada sama riikide klassifikaatorit, mis on juba seotud olemitüübiga Isik. Maakonna klassifikaatorit ma siis ei kasutaks, sest kõigis riikides ei pruugi olla haldusüksust "maakond" ning erinevate riikide maakondade üle võib olla raske arvet pidada.​    Kokkuvõttes oleks näite korral pakiautomaadi atribuudi aadress väärtuseks "Kohtla-Järve linn, Ahtme linnaosa, Maleva tn, 23" ning pakiautomaat oleks seotud maakonnaga Ida-Virumaa. ## Küsimus: Mida kujundab endast elementaarvõtme normaalkuju (EVNK)? **Vastus:** Kui ma vaatan C.J Date ja J. Celko töid, siis nad mainivad seda normaalkuju lühidalt, ajaloolise tagasivaate ja esitluse täielikkuse huvides. C.J. Date osundab, et EVNK-le viidatakse kirjanduses vähe.EVNK on kolmanda normaalkuju (3NK) ja Boyce/Coddi normaalkuju (BCNK) vahel - kui tabel on elementaarvõtme normaalkujul, siis on see ka kolmandal normaalkujul. Eesmärk on ikkagi jõuda Boyce/Coddi normaalkujuni. Muide, see artikkel, kus EVNK välja pakutakse, annab head 3NK ja BCNK definitsioonid. EVNK käsitleb olukorda, kui tabelil on rohkem kui üks liitvõti ja need võtmed osaliselt kattuvad (st neil on ühiseid veerge). Sellisel juhul võib kattuvates veergudes olla korduvaid andmeid.C. J. Date defineerib EVNK järgnevalt: "Tabel on elementaarvõtme normaalkujul (EVNK) siis ja ainult siis kui iga mittetriviaalse funktsionaalse sõltuvuse X=>Y korral on kas a) X tabeli supervõti või b) Y on mõne elementaarvõtme alamvõti. K on tabeli T elementaarvõti siis ja ainult siis kui tabelis T on selline veerg V, mille puhul funktsionaalne sõltuvus K=>{V} on mittetriviaalne ja täielik." (https://learning.oreilly.com/library/view/database-design-and/9781449330187/ch13.html#concluding_remarks-id4)J. Celko esitab tabeli sellele normaalkujule viimise kohta näite.https://learning.oreilly.com/library/view/joe-celkos-sql/9780123693792/9780123693792_ch02lev1sec5.html Aine_deklareerimine (yliopilaskood, ainekood, aine_nimetus)Primaarvõti (yliopilaskood, ainekood)Alternatiivvõti (yliopilaskood, aine_nimetus)Mittetriviaalsed täielikud funktsionaalsed sõltuvused selles tabelis:(yliopilaskood, ainekood) => aine_nimetus(yliopilaskood, aine_nimetus) => ainekoodainekood=>aine_nimetusaine_nimetus=>ainekoodÜlekanduvaid sõltuvusi selles tabelis ei ole ja seega on see tabel kolmandal normaalkujul.Leidub funktsionaalseid sõltuvusi, mille determinant ei ole kandidaatvõti ning seega pole see Boyce/Coddi normaalkujul.ainekood=>aine_nimetusaine_nimetus=>ainekoodLähemal vaatlemisel ilmneb, et tabelis võivad ainete andmed olla erinevates ridades dubleeritud, st selles tabelis on andmete liiasust, mida saaks täiendava normaliseerimisega vähendada.Tabeli elementaarvõtmed on minu arusaamise kohaselt. (yliopilaskood, ainekood) (sest leidub veerg aine_nimetus, nii et (yliopilaskood, ainekood) => aine_nimetus) (yliopilaskood, aine_nimetus) (sest leidub veerg ainekood, nii et (yliopilaskood, aine_nimetus) => ainekood) Need on kandidaatvõtmed, st nende atribuutide pärisalamhulk ei ole enam võti. Järelikult eelnevalt välja kirjutatud neljast funktsionaalsest sõltuvusest kaks viimast ei rahulda EVNK tingimusi.Lahendus oleks luua tabelidAine (ainekood, aine_nimetus)Primaarvõti (ainekood)Alternatiivvõti (aine_nimetus)Aine_deklareerimine (yliopilaskood, ainekood)Primaarvõti (yliopilaskood, ainekood)Välisvõti (ainekood) Viitab Aine (ainekood)Need tabelid on ka BCNK-l. **Märksõnad:** elementary key normal form, EKND, normaliseerimine, normalization ## Küsimus: Mida ma võiksin teada NoSQL süsteemidest? **Vastus:** Teemas 1 ja 11 on juttu NoSQL süsteemidest. Kes tahab nende kohta rohkem teada saada, siis võiks alustada sellest Martin Fowleri umbes tunni pikkusest videost. Kes eelistab lugeda, saab vaadata seda materjali, laenutada raamatukogust raamatu, mille kokkuvõtteks see materjal on või lugeda seda sama raamatut elektrooniliselt (Kuidas kasutada O'Reilly digitaalset platvormi?). Hilisemast ajast tasub vaadata arvutiteadlase Michael Stonebrakeri ettekannet suurandmete ja nendega töötamise vahendite (sh NoSQL süsteemid) kohta. Vastukaaluks positiivsele "uus ja lahe läikiv mänguasi" tüüpi käsitlusele võiksid huvilised vaadata ka 2013. aastast pärit artiklit "History repeats itself: sensible and NonsenSQL aspects of the NoSQL hoopla", mis annab minu arvates realistliku vaate NoSQL süsteemide headele ja mitte nii headele külgedele. Kokkuvõte artiklist - kes minevikku ei mäleta, on määratud selle vigu kordama (väide, mis kehtib igal elualal). NoSQL and Technical Debt. Ajaveebi postitus, mis selgitab, miks NoSQL süsteemide ilmumine pole muutnud väärtusetuks SQLi ning andmebaaside projekteerimise õppimist. Nende oskuste puudumine on arendajatel võlg, mis tuleb hiljem intressidega tagasi maksta. NoSQL oma "skeemitute" andmetega loob tegelikult tehnilist võlga. Aina rohkemates NoSQL süsteemides saab andmebaasi tasemel kirjeldada ja jõustada andmebaasi struktuuri (näide) (kirjutamise skeemi e schema-on-write). Saadakse aru, et struktuur on eelis mitte puudus. Aina rohkemates NoSQL süsteemides saab kasutada deklaratiivset andmebaasikeelt (näide), mis paraku (SQL pole just kõige paremini disainitud keel) enamasti meenutab SQLi. Saadakse aru, et deklaratiivset keelt on palju kergem kasutada ja õppida kui imperatiivset. Irvhambad juba ütlevad, et NoSQL = Not Yet SQL.Siin on päris pikk ja põhjalik eestikeelne materjal, mille teine pool on pühendatud NoSQLil. ## Küsimus: Miks ei ole hea mõte kasutada kõikides tabelites surrogaatvõtit? **Vastus:** Surrogaatvõti on lihtvõti, mille väärtused on süsteemi genereeritud unikaalsed täisarvud. Need väärtused on kasutusel tarkvara siseselt ridade identifitseerimiseks, kuid andmebaasi kasutavatele inimestele ei tähenda need väärtused midagi ja ta ei oska nende alusel olemeid üksteisest eristada. Näide: kes on töötaja, kelle id=34583?Sisulise tähendusega võtme väärtus on seevastu ka arusaadav inimkasutajale ja ta oskab nende väärtuste alusel olemeid üksteisest eristada. Näide: kes on töötaja, kelle meiliaadress on Erki.Eessaar@taltech.ee?Vaatleme kahte tabelite disaini.Disain 1 (kõikides tabelites surrogaatvõti - "id" veerg).Riik (riik_id, riik_kood, nimetus)Primaarvõti (riik_id)Klient (klient_id, riik_id, e_meil, eesnimi, perenimi)Primaarvõti (klient_id)Välisvõti (riik_id) Viitab Riik (riik_id)Toode (toode_id, toote_kood, hind)Primaarvõti (toode_id)Tellimus (tellimus_id, klient_id, reg_aeg)Primaarvõti (tellimus_id)Välisvõti (klient_id) Viitab Klient (klient_id)Tellimuse_rida (tellimus_id, toode_id, kogus)Primaarvõti (tellimus_id, toode_id)Välisvõti (tellimus_id) Viitab Tellimus (tellimus_id)Välisvõti (toode_id) Viitab Toode (toode_id)Disain 2 (kõikides tabelites, kus võimalik, on sisulise tähendusega võtmed).Riik (riik_kood, nimetus)Primaarvõti (riik_kood)Alternatiivvõti (nimetus)Klient (e_meil, riik_kood, eesnimi, perenimi)Primaarvõti (e_meil)Välisvõti (riik_kood) Viitab Riik (riik_kood)Toode (toote_kood, hind)Primaarvõti (toote_kood)Tellimus (tellimus_id, e_meil, reg_aeg)Primaarvõti (tellimus_id)Välisvõti (e_meil) Viitab Klient (e_meil)Tellimuse_rida (tellimus_id, toote_kood, kogus)Primaarvõti (tellimus_id, toote_kood)Välisvõti (tellimus_id) Viitab Tellimus (tellimus_id)Välisvõti (toote_kood) Viitab Toode (toote_kood)Millised on disaini 1 probleemid võrreldes disainiga 2?Probleem 1: Päringud on keerukamad, sest tuleb lugeda andmeid suuremast hulgast tabelitest. Päringutes tuleb ühendada rohkem tabeleid. Lause täitmine võtab rohkem aega.Ülesanne: Leia PostgreSQL andmebaasis kordusteta selliste toodete koodid, mida on ostnud Eesti kliendid.Disain 1SELECT DISTINCT toote_koodFROM Riik INNER JOIN Klient USING (riik_id)INNER JOIN Tellimus USING (klient_id)INNER JOIN Tellimuse_rida USING (tellimus_id)INNER JOIN Toode USING (toode_id)WHERE Riik.riik_kood='EST';Disain 2SELECT DISTINCT toote_koodFROM Klient INNER JOIN Tellimus USING (e_meil)INNER JOIN Tellimuse_rida USING (tellimus_id)WHERE Klient.riik_kood='EST';Disain 2 korral leian riigi koodi tabelist Klient ja toote koodi tabelist Tellimuse_rida. Disain 1 korral tuleb lugeda viit tabelit, disain 2 korral tuleb lugeda kolme tabelit.Probleem 2: Surrogaatvõtmete läbival kasutamisel tekib sageli olukord, et sisulised võtmed lähevad andmebaasi arendajal täiesti meelest ära ja neid ei jõustata andmebaasis. Disain 1 korral peaksid Riik tabelis olema unikaalsed (riik_kood) ja (nimetus). Klient tabelis peaks olema unikaalne (e_meil). Toode tabelis peaks olema unikaalne (toode_kood). Enamikes andmebaasisüsteemides tekivad PRIMARY KEY ja UNIQUE kitsenduste toetuseks indeksid, seega suureneb indeksite ja nende kasutatav kettaruumi hulk. ## Küsimus: Miks mitte luua klassifikaatoritele ühist tabelit Klassifikaator, kus on kõikide klassifikaatorite koodid ja nimetused? **Vastus:** Vastuse leiate selle artikli esimesest punktist.Selle ülevaate alajaotus "One True look-up Table" on pühendatud ühisele klassifikaatorite tabelile:https://www.red-gate.com/simple-talk/databases/sql-server/t-sql-programming-sql-server/look-up-tables-in-sql/Kes tunneb teema vastu sügavamat huvi võib vaadata bakalaureusetööd: Vellemaa, A.S., 2015. Mõned disainimustrid klassifikaatorite esitamiseks SQL andmebaasides. Bakalaureusetöö. TTÜ Informaatikainstituut [WWW] https://digi.lib.ttu.ee/i/?3484. ## Küsimus: Miks on halb mõte kasutada erinevates tabelites ühesuguse nimega (id, kood või code) primaarvõtme veergu? **Vastus:** See muudab keerulisemaks tabelites olevatest andmetest arusaamise ja tabelite põhjal päringute tegemise.Sellise nimega primaarvõtme veerud on üks sümptom, mis viitab sellele, et andmebaasi disainis esineb "Üks suurus kõigile" andmebaasi disaini antimuster. Antimuster on struktuurse kirjutamise viis, kuidas panna kirja halbu lahendusi levinud probleemidele.Selline nimi on liiga üldine ja tuleb päringute tulemuses enamasti ümber nimetada. Vastasel juhul tekib päringu tulemusse mitu sama nimega veergu, mis vormiliselt on küll SQLis lubatud, kuid sisuliselt muudab see päringu tulemuse raskesti kasutatavaks.Oletame, et andmebaasis on tabelid:Mark (id, nimetus)Primaarvõti (id)Auto (id, mark_id, registri_nr)Primaarvõti (id)Välisvõti (mark_id) Viitab Mark (id)Kui ülesandeks on leida iga auto kohta margi identifikaator, nimetus, auto identifikaator ja registri number, siis tuleks kirjutada päringSELECT Mark.id AS mark_id, nimetus, Auto.id AS auto_id, registri_nrFROM Mark INNER JOIN Auto ON Mark.id=Auto.mark_id;Samas, kui andmebaasis oleksid tabelid:Mark (mark_id, nimetus)Primaarvõti (mark_id)Auto (auto_id, mark_id, registri_nr)Primaarvõti (auto_id)Välisvõti (mark_id) Viitab Mark (mark_id), siis saab selle ülesande lahendada SQL standardit hästi järgivas andmebaasisüsteemis (nt PostgreSQL) oluliselt lühema lausega. USING võimaldab teha ühendamist üle samanimeliste veergude. Ühendamise tulemuses on see veerg (antud juhul mark_id) ühekordselt, st SELECT klauslis pole veeru nime ees vaja täpsustada tabeli nime.SELECT mark_id, nimetus, auto_id, registri_nrFROM Mark INNER JOIN Auto USING (mark_id);Veel üks, veidi pikem näide, kus koodi kirjutamise mugavus tuleb paremini välja. Leia ilma kordusteta milliseid kaupu on millised kliendid ostnud.SELECT DISTINCT klient.id AS klient_id, klient.perenimi, kaup.id AS kaup_id, kaup.nimetus AS kauba_nimetusFROM Klient INNER JOIN Tellimus ON Klient.id=Tellimus.klient_idINNER JOIN Tellimuse_rida ON Tellimus.id=Tellimuse_rida.tellimus_idINNER JOIN Kaup ON Tellimuse_rida.kaup_id=Kaup.id;Tuleb olla tähelepanelik, et mitte valesid veerge kokku ühendada (tegin ka ise selle vea seda näidet kirjutades).vs.SELECT DISTINCT klient_id, klient.perenimi, kaup_id, kaup.nimetus AS kauba_nimetusFROM Klient INNER JOIN Tellimus USING (klient_id)INNER JOIN Tellimuse_rida USING (tellimus_id)INNER JOIN Kaup USING (kaup_id);Vastukaaluks saab öelda, et võtmeveeru nimi id võib lihtsustada mingites rakenduse ehitamise vahendites andmebaasi kasutuse realiseerimist. Lõppkokkuvõttes, nagu väga sageli (andmebaasi) tehnilise lahenduse loomise juures, on kõik valikute küsimus ning igal valikul on oma head ja halvad tagajärjed. ## Küsimus: Millal kasutada kontseptuaalses andmemudelis kompositsiooniseost (seose ühes otsas on täidetud romb e täidetud teemant)? **Vastus:** Kompositsioon tähistab osa-terviku seost, kus osad sõltuvad eksistentsiaalselt tervikust e terviku kadumine/hävimine tähendab ka osade kadumist/hävimist.Romb oleks selle olemitüübi poolel, millesse kuuluva olemi kustutamine tingib seotud olemite kustutamise.[Käsi]<*>-1------------0..*-[Sõrm]NB! Pange tähele võimsustikku (0..*), sest mitte kõigil inimestel pole käel täpselt viite sõrme. Näiteks sellele küsimusele/vastusele lisatud joonisel (vt vastuse lõpust) on kompositsiooniseoseid kindlasti liiga palju.Mulle meeldib kõige rohkem nõuanne, et kui kahtled, siis jäta osaks/tervikuks olemine märkimata.Andmebaaside taustaga inimest võiks nende määramise juures aidata küsimus: Milliste seoste puhul kasutaksin ma SQL-andmebaasis ON DELETE CASCADE (e kustutades terviku kustuvad automaatselt ka selle osad)? Nende puhul võib (ei pea) UMLi klassidiagrammis kasutada täidetud rombi (kompositsiooni).Kindlasti kasutaksin mina seda joonisel oleva näite puhul vaid ühes kohas: Isik-Isik roll.Isik-Isiku roll puhul kasutaksin kontseptuaalses andmemudelis kompositsiooni ja SQL-andmebaasis ON DELETE CASCADE, sest tegemist on registri põhiobjekti ning sellega seotud selle sama registri mittepõhiobjektiga.Valikukoht on minu arvates, kas kasutada kontseptuaalses andmemudelis kompositsiooni ja andmebaasis ON DELETE CASCADE ka järgnevate puhul:Koer-Varjupaigas_viibimineKoer-Koera_tervise_ankeetKoer-AdopteerimisavaldusLoogiline oleks, et kas kasutada seda kõigi kolme puhul või mitte ühegi puhul. **Märksõnad:** kompositsioon, UML, olemi-suhte diagramm ## Küsimus: Millal modelleerida kontseptuaalses andmemudelis mingit olemitüübi omadust atribuudina ja millal klassifikaatorina (eraldi olemitüübina)? **Vastus:** Selle üle otsustamine, mida modelleerida olemi-suhte diagrammis atribuudina ja mida eraldi olemitüübina, on selle mudeli tüübi kasutamise üks põhilisi keerukusi.Modelleeri klassifikaatorina kui vähemalt üks tingimus on täidetud: kasutaksite vastavate andmete registreerimise kasutajaliideses väärtuste valimist nimekirjast (nt liitboksist või hüpikanast), kusjuures kasutaja näeb valiku tegemiseks nimetust, kasutaksite rakenduse lähtekoodis vastavas tarkvaraklassis atribuudi tüübina loendustüüpi, lisaks tekstilisele nimetusele on omaduse väärtusega seotud täiendavaid andmeid, mida on vaja andmebaasis hoida ja mis võivad ka aidata valikut teha (näiteks töötaja rollil on lisaks nimetusele kirjeldus, näiteks riigil on lisaks nimetusele rahvusvahelised suunakoodid telefoniga helistamisel), näete ette, et andmebaasis võib tulevikus tekkida vajadus täiendavate eelmises punktis nimetatud andmete registreerimiseks, omaduse võimalike väärtuste hulk on määratud mingi standardiga (näiteks riigid, keeled, valuutad, isikute sood). Muudel juhtudel modelleeri atribuudina. Näiteks modelleeri atribuudina juhul kui: omaduse väärtus on vabatekst (näiteks kirjeldus, kommentaar), omaduse väärtus on kuupäev, kellaaeg või ajatempel (näiteks registreerimise aeg, sünni kuupäev), omaduse väärtus on tõeväärtus (true või false), omaduse väärtus on arv arvude vahemikust (näiteks sünniaasta vahemikus 1900 kuni 2100, pikkus vahemikus 100 kuni 250, kõrgus vahemikus 1 kuni 2000). **Märksõnad:** olemitüüp, atribuut, olemi-suhte diagramm, kontseptuaalne andmemudel, ERD, klassifikaator, klassifikaatorid ## Küsimus: Mille alusel otsustada olemite vaheliste seoste alustel leitud olemitüüpide kuuluvuse üle konkreetsesse registrisse? **Vastus:** Vastan sellele küsimusele näite põhjal. Oletame, et andmebaasi kontseptuaalses struktuuris on olemitüübid:[Kaup]-1----0..*-[Kauba laoseis]-0..*----------1-[Ladu]Olemitüübil Kauba laoseis on atribuut kogus. Süsteemi äriarhitektuuris on sellised allsüsteemid nagu: kaupade register (ja selles andmeid haldav kaupade funktsionaalne allsüsteem), ladude register (ja selles andmeid haldav kaupade funktsionaalne allsüsteem). Olemitüüp Kaup kuulub kaupade registrisse. Olemitüüp Ladu kuulub ladude registrisse. Millisesse registrisse peaks kuuluma olemitüüp Kauba laoseis? Kas olemitüübil Kauba laoseis on oma elutsükkel, erinevate võimalike süsteemile huvipakkuvate seisunditega (midagi rohkem kui seisundid "aktuaalne" ja "mitteaktuaalne")? Kui  jah, siis võib Kauba laoseis olla eraldi põhiolemitüüp. Sellisel juhul oleks süsteemi äriarhitektuuris ka eraldi kauba laoseisude register ning kauba laoseisude funktsionaalne allsüsteem. Kui ei, siis kuulub Kauba laoseis kas kaupade registrisse või ladude registrisse, ning nende andmete haldamine käib vastava funktsionaalse allsüsteemi kaudu. Mõeldes kasutajaliidesele, siis kuidas peaks toimuma põhiliselt laoseisude haldamine? Kui nii, et otsitakse konkreetne kaup ja siis registreeritakse selle kauba kogused erinevates ladudes, siis kuulub Kauba laoseis kaupade registrisse. Kui nii, et otsitakse konkreetne ladu ja siis registreeritakse selles laos olevate kaupade kogused, siis kuulub Kauba laoseis ladude registrisse. Millisele teisele olemitüübile viidatakse olemitüübi nimes või kui viidatakse kahele erinevale olemitüübile, siis millise nimi on esimene? Kui nimi on Kauba laoseis või Kaup laos, siis ilmselt kuulub see olemitüüp kaupade registrisse. Kui nimi on Lao kaup, siis ilmselt kuulub see olemitüüp ladude registrisse. Kas peaks saama kustutada konkreetse kauba andmed, kui selle kaubaga on seotud ladusid? Kui jah, siis see on märk, et Kauba laoseis kuulub kaupade registrisse. Kas peaks saama kustutada konkreetse lao andmed, kui selle laoga on seotud kaupasid? Kui jah, siis see on märk, et Kauba laoseis kuulub ladude registrisse. On ka võimalik, et vastus küsimusele 1 on "ei". Küsimusele 2 on vastus, et mõlemat pidi peab saama. Vastused küsimustele 4 ja 5 on kas mõlemad "jah" või mõlemad "ei". See on tunnus, et olemitüübi Kauba laoseis paigutuse registrisse saab vabalt valida.Antud juhul paigutaksin ma olemitüübi Kauba laoseis kaupade registrisse. ## Küsimus: Milleks läheb vaja kontseptuaalses andmemudelis olevaid olemitüüpide ja atribuutide definitsioonide tabeleid? **Vastus:** Kontseptuaalse andmemudeli (on ka Teie projektis) üheks osaks on olemitüüpide ja atribuutide definitsioonid. Seal tuleb täpselt lahti selgitada, milliste andmete vajadusele kontseptuaalne andmemudel osundab. Näiteks hotelli "ruum" - kas mõeldakse kõiki ruume (ka köök ja fuajee) või ainult ööbimiseks mõeldud numbritubasid või hoopis numbritubades sisalduvaid ruume (vannituba, hoiuruum, eluruum). Näiteks kauba "tootja" - kas mõeldakse brändi (nt Apple, Olympus) või hoopis tehast, mis selle kauba kokku paneb. Kontseptuaalne andmemudel ning olemitüüpide ja atribuutide definitsioonid osutuvad näiteks kasulikuks siis, kui on vaja hakata andmeid integreerima - erinevates andmebaasides olevatest andmetest tervikpilti kokku panema. Siis on näiteks vaja aru saada, kas "Klient" andmebaasis A ja "Klient" andmebaasis B on üks ja sama asi või mitte. Lõpetuseks näide tänasest päevast, mis osutab infosüsteemide vahelise koostöö ja andmete integreerimise vajadusele. Intervjuu ajal justiitsminister olnud Urmas Reinsalu hinnangul pole normaalne olukord, kus tagaotsitav võib saada endale autojuhiload kätte. "Esimene loogiline lahendus peaks e-riigis olema suuremate andmebaaside omavaheline seotus, et kui tagaotsitav isik ilmub kasvõi e-tervisesüsteemi, siis lööb punane tuluke põlema," leidis Reinsalu. (Reinsalu: korduvalt karistatud inimesi tuleks vähemal määral usaldada. ERR Uudised 10.03.2016) ## Küsimus: Milleks läheb vaja olemitüüpide ja atribuutide tähenduse e semantika kirjeldusi? **Vastus:** Olemitüüpide ja atribuutide definitsioonid: aitavad saavutada arenduse osalistel ühise arusaama valdkonna mõistetest, aitavad luua kasutajaliidest ja kasutusjuhendeid, on aluseks valikute tegemisel andmebaasi andmestruktuuride disainimise e tehnilise kavandamise käigus, on vajalik sisendinfo, kui soovida erinevatest allikatest saadud andmeid kokku panna e integreerida (näiteks, kas klient andmebaasis A on sama, mis tarbija andmebaasis B?). Toon näiteid selle kohta, kui selline informatsioon puudus.1. Bakalaureusetöös "Ettevõttesisese tarkvara täiendamine - kasutajaliidese ja andmebaasi kavandamine ning sobivuse hindamine" täiendatakse ettevõttesisest tarkvara inimressursside planeerimise funktsionaalsusega. Lõputöös pakutakse välja uue funktsionaalsuse jaoks vajalik kasutajaliides ning samuti andmebaasi täiendused . Selleks, et neid täiendusi saaks välja pakkuda, tuli kõigepealt aru saada, milliseid andmeid täiendatava tarkvara andmebaasi juba kogutakse. Näiteks, kui tahta kasutajale uues kasutajaliideses mingit aruannet kuvada, siis peab teadma, kas vajalikke lähteandmeid võimaldab olemasolev tarkvara juba koguda või tuleb nende andmete kogumise võimalus alles lisada.  Paraku selgus töö tegemise käigus, et olemasoleva andmebaasi dokumentatsioon puudus täielikult. Seetõttu tuli töö tegemise käigus olemasolev andmebaas dokumenteerida ja see võttis palju aega. 40% töö tegemiseks kulunud ajast oli pühendatud dokumenteerimisele, mille alla kuulus ka olemasoleva andmebaasi dokumenteerimine. Töö üks autor kirjutas  (lk 134): "Kõige keerulisemaks osutus olemasoleva andmebaasi dokumenteerimine, eelkõige andmeväljade defineerimine. Esmalt oli keeruline leida ettevõttes isikut, kes oskaks konkreetse andmebaasi kohta detailset informatsiooni jagada. Samuti selgus hiljem, et nii mõndagi tabelit andmebaasis enam ei kasutatagi."2. Bakalaureusetöös "E-poe andmete migreerimine PostgreSQL andmebaasist Microsoft SQL Serveri andmebaasi" kirjutatakse e-poe tarkvara uuendamise käigus toimuvast andmete ülekandmisest PostgreSQL andmebaasist MS SQL Serveri andmebaasi. Lähteandmebaas oli osa valmislahendusest ehk karbitootest ja sihtandmebaas oli ettevõtte enese arendajate käsitöö. Selleks, et ülekannet läbi viia, oli vaja saada aru, milliseid andmeid hoitakse lähteandmebaasis ja milliseid sihtandmebaasis. Ettevõttel puudus nende andmebaaside kohta dokumentatsioon ja autor pidi kulutama märkimisväärse osa töö tegemise ajast selle dokumentatsiooni loomisele. Alles siis kui see töö oli tehtud, sai hakata koostama vastavustabeleid lähte- ja sihtandmebaasi tabelite/veergude vahel ning seejärel kirjutama andmete ülekandeks mõeldud SQL lauseid.3. Bakalaureusetöös "EE Tele2 müügiandmete andmetabelite kvaliteedikontroll ja dokumenteerimine" kontrolliti ja parandati Tele2 olulise müügiprogrammi 4sale poolt kasutatud andmetabelites olevate andmete kvaliteeti. Ka selle töö tegemise käigus selgus, et müügiprogrammi aktiivselt kasutavad tabelid (61 kokku) olid korralikult dokumenteerimata (töö sellega algas ettevõttes alles 2020. aastal) ja töö pühendas suure osa ajast selle dokumentatsiooni loomisele. Autor kirjutas: "Puuduliku 4sale dokumentatsiooni tõttu lisatakse loodavatesse raportitesse andmed teistest schemadest, asendades 4sale tabelite puuduvaid andmeid. Selliselt toimides tekib olukord, kus saadakse sarnased andmed teistest keskkondades, mille korral andmete terviklikus ei ole kindel." Puuduva dokumentatsiooni koostamiseks kulus kolm nädalat. Kuna tabelite haldajad ei osanud kõigile küsimustele ise vastata, pidi autor taotlema juurdepääsu nendele tabelitele, et vajalikud vastused saada. Samuti pidi autor suhtlema juba töölt lahkunud andmeanalüütikutega. Konsultatsiooni käigus selgus, et puudub ülevaade tabelitest, mida aktiivselt enam ei täiendata. Dokumentatsiooni koostamiseks (andmebaasis olevate andmete tähendusest arusaamiseks) pidi autor võrdlema andmetabelite sisu 4sale rakenduses kuvatava infoga (milline andmebaasis olev väärtus on rakenduses mis väljas). Osad tabelid ja veerud jäidki tundmatuks ja nende tähenduse teada saamiseks tuleks suhelda 4sale arendajatega.4. Magistritöös "E-kaubandusettevõtte X andmekvaliteedi analüüs ja parendamine" oli eesmärgiks saavutada väikese e-kaubandusettevõtte andmekvaliteedi püsiv paranemine. Selleks võeti kasutusele Eesti riigi infosüsteemi andmekvaliteedi juhtimise raamistik, seda vastavalt vajadusele kohandades. Töö tulemusena viidi ettevõtte andmekvaliteet esimeselt (kõige madalamalt) küpsustasemelt (reaktiivselt tasemelt) kolmandale küpsustasemele (viietasemelisel skaalal) e standardiseeritud tasemele. Ettevõte peab e-poodi kasutades ülipopulaarset sisuhaldussüsteemi WordPress ja selle pistikprogrammi WooCommerce.  Ettevõtte andmebaas moodustus WordPressi ning selle pistikprogrammide tabelitest. W3techs andmete järgi oli 2023. aasta novembri seisuga sisuhaldussüsteemi WordPressi turuosa sisuhaldussüsteemide hulgas 62.2% (aastaga vähenes turuosa kaks protsendipunkti). 43% maailma veebisaitidest olid loodud WordPressi põhjal. WordPressil põhineva WooCommerce tarkvaral oli suurim – 29% suurune – turuosa e-poe tarkvarade hulgas. Ja ometigi tuli kohe töö tegemise algul välja, et WooCommerce ja WordPress andmebaasi dokumentatsioon on ebapiisav - laiali erinevates kohtades, erineval viisil esitatud ning tabelite ja veergude vabatekstilised kirjeldused olid nendes olevate andmete tähenduse mõistmiseks mõnikord ebapiisavad. Samas, kui tahta hakata parandama andmekvaliteeti, siis tuleb kõigepealt aru saada milliseid andmeid üldse kogutakse, mis on nende andmete tähendus ja millised võimalikud piirangud kehtivad andmeväärtustele. Seetõttu kulus märkimisväärne osa töö tegemise ajast tabelite ja veergude tähendusest arusaamisele ja selle vabatekstilise kirjeldusena kirja panemisele. Töö autor dokumenteeris need ettevõtte wikis, et ettevõtte töötajatel oleks tulevikus ühes kohas koos olev dokumentatsioon andmebaasi kohta. **Märksõnad:** kontseptuaalne andmemudel, Wordpress, WooCommerce ## Küsimus: Millised on erinevad tabelite võtmete tüübid ja kuidas need on omavahel seotud? **Vastus:** Supervõtmel peab olema: - unikaalsuse omadus.   Kandidaatvõtmel peab olema: - unikaalsuse omadus JA - mitteliiasuse omadus. Mitteliiasus tähendab, et sealt ei saa enam ühtegi veergu ilma unikaalsuse omadust kaotamata eemaldada.   Kõik kandidaatvõtmed on supervõtmed. Iga supervõti ei pruugi olla kandidaatvõti. Kandidaatvõtme kohta öeldakse mõnikord ka minimaalne supervõti.Andmebaasis tuleb jõustada (primaar- ja alternatiivvõtmetena) kandidaatvõtmed.Primaarvõti e esmasvõti on kandidaatvõti, mis on teiste kandidaatvõtmete hulgast esile tõstetud (võrdseim võrdsete seas).Nii nagu riigil on korraga maksimaalselt üks kuningas või president on ka tabelis korraga maksimaalselt üks primaarvõti.Alternatiivvõtmed on kõik need kandidaatvõtmed, mis ei saanud primaarvõtmeks. **Märksõnad:** kandidaatvõti, võtmekandidaat, supervõti, primaarvõti, esmasvõti, alternatiivvõti, võti ## Küsimus: Milliseid probleeme tekitab andmete liiasus operatiivandmete andmebaasides? **Vastus:** Andmete liiasus tähendab, et sama fakti on võimalik andmebaasist tuletada kahel või rohkemal erineval viisil. Andmete liiasus tähendab, et andmemaht suureneb, andmete muutmiseks tuleb teha rohkem tööd ja andmebaasi võivad tekkida mittekooskõlalised väited. Toon näite Tallinna Tehnikaülikooli õppeinfosüsteemi (ÕIS) põhjal. ÕISis tuleb aine deklareerimise (õpingukavasse valimise) võimaldamiseks defineerida aine-õppejõu paar. Kui selline paar on loodud, siis vastavat õppejõudu näidatakse ÕISis ainekaardil ainet õpetava õppejõuna. Samal ajal on süsteemis tunniplaanid, kus näidatakse milliseid õppeained õppejõud semestris õpetab. See pole aine-õppejõu paaridega seotud. Seega info, milline õppejõud õpetab semestris millist ainet, on dubleeritud - aine-õppejõud paaris ja tunniplaanis. Kui aine-õppejõu paar on süsteemis veel loomata, siis tekib olukord, kus tunniplaanis on õppejõud ainega seotud, kuid ainekaardil ei ole. See tekitab süsteemi kasutajates (üliõpilastes) segadust, sest nad ei saa aru, kas õppejõud õpetab järgmisel semestril mingit ainet või mitte. ## Küsimus: Mis andmeid võiks registreerida tanklate kohta? Millised võiksid olla tanklaga seotud klassifikaatorid? Kas tanklat pidav organisatsioon võiks olla üks tanklaga seotud klassifikaator? **Vastus:** Näited andmetest, mida üks register kogub erinevate ettevõtete peetavate tanklate kohta: https://kytus.envir.ee/source-of-pollution/view/146241Olemitüübi Tankla tekstiliste atribuutide näiteid: Aadress Lahtiolekuajad Olemitüübi Tankla arvuliste atribuutide näiteid: X-koordinaat Y-koordinaat Olemitüübiga Tankla seotud klassifikaatorite näiteid: Tankla tüüp (automaatne, operaatoriga) Müügi tüüp (jaemüük, hulgimüük) Vald/Linn Selle registreerimiseks kasutatakse Eesti haldus- ja asustusjaotuse klassifikaatorit https://et.wikipedia.org/wiki/Eesti_haldus-_ja_asustusjaotuse_klassifikaator Tankla võiks olla seotud valla või linnaga ja see omakorda maakonnaga Tanklat pidava ettevõtte andmed tuleks andmebaasis siduda tankla andmetega kui tegemist oleks tanklate registriga, kus on andmed erinevate tanklapidajate tanklate kohta (võivad kuuluda erinevatele ettevõtetele). Sellisel juhul oleks selle registreerimiseks valida, et 1) registreerida ettevõtted kui klassifikaatorid või 2) kui organisatsioonid (olemitüüp Organisatsioon, mis on seotud olemitüübiga Tankla). Variant 1:[Klassifikaator]<|----------[Tanklaoperaator]-1--------0..*-[Tankla]Variant 2:[Organisatsioon]-1-+tanklaoperaator--------0..*-[Tankla]Valik sõltub sellest, kas tanklapidajatel on süsteemis teistsugused võimalikud seisundid (st andmete haldamise protsess) kui muudel klassifikaatoritel. Kui ei ole, siis sobib variant 1, kui on, siis tuleks valida variant 2. Kui teete ühe konkreetse tanklaoperaatori infosüsteemi, siis pole Tanklaoperaator eraldi olemitüüp/klassifikaator. Vastuse alguses viidatud süsteemis on Organisatsioon eraldi olemitüüp (st tanklapidaja ei ole klassifikaator). Organisatsioonil on antud juhul seisund e staatus "aktiivne". Selle registreerimiseks on kasutatud seisundiklassifikaatorit Organisatsiooni_seisundi_liik. ## Küsimus: Mis asi on register? **Vastus:** Andmebaas on nagu päikesesüsteem. Päikese rollis on organisatsiooni eesmärgid. Kõik mis organisatsioonis IT vallas (sh andmebaasidega) tehakse, peab olema nende eesmärkide teenistuses, mitte vastupidi. Seega planeedid (andmebaasi osad) tiirlevad ümber päikese (organisatsiooni eesmärkide), mitte vastupidi. Päikese ümber tiirlevad planeedid vastavad põhiobjektidele e põhiolemitüüpidele. Planeetide ümber tiirlevad omakorda kaaslased e kuud, mis vastavad mitte-põhiobjektidele. Iga planeet-planeedi kaaslased süsteem vastab andmebaasi äriarhitektuuris ühele registrile. Nii nagu iga kuu tiirutab ümber kindla planeedi on ka iga mitte-põhiobjekt kindla registri tiiva all. Igal planeedil on null või rohkem kuud; igal põhiobjektil on null-või rohkem samasse registrisse kuuluvat mitte-põhiobjekti. Lisaks planeetidele tiirutavad ümber päikese ka asteroidid. Neist võib andmebaaside analoogias mõelda, kui andmestruktuuridest, mis on vajalikud ühe või teise rakenduse töö hõlbustamiseks, kuid mis ei kuulu ühtegi registrisse (nt disainitaseme abitabelid). Ümber planeetide (hetkel teadaolevalt ainul Maa, aga hiljem miks mitte ka mõni teine planeet) tiirutavad kunstlikud tehiskaaslased, mis on sinna planeedi asukate poolt saadetud, kuid mingil hetkel planeedile tagasi langevad ja selle käigus ära põlevad. Need on nagu registris olevad ajutiste andmetega andmestruktuurid, mida läheb vaja mingi konkreetse ülesande (nt konkreetse päringu) täitmiseks, kuid mis millalgi oma otstarbe kaotavad ja seega võib eemaldada. Nii nagu andmebaas või meie arusaam selle ülesehitusest ajas muutub, muutub ka päikesesüsteem (nt planeet püüab gravitatsiooni mõjul kinni mõne pisitaevakeha, mis muutub selle planeedi kuuks) või meie arusaam sellest (nt muutub arusaam sellest, millised taevakehad kuuluvad planeetide hulka). Nii nagu kunagi kustub päike, nii saab kunagi otsa ka organisatsiooni ja selle IT-süsteemide (sh andmebaasisüsteemi toega andmebaasi) elukaar. ## Küsimus: Mis erinevus on primaarvõtme ja kandidaatvõtme vahel? **Vastus:** See on nagu organisatsioonile juhi valimised. Oletame, et on kolm kandidaati. Üks valitakse peadirektoriks. Tema saab ametiauto ja eraldi kabineti. Ülejäänud kaks ei saa peadirektoriks, kuid saavad asedirektori tiitli ning samuti ametiauto ja eraldi kabineti.Igas tabelis on üks või rohkem kandidaatvõtit e võtmekandidaati (candidate key). Üks nendest kuulutatakse primaarseks e esmaseks võtmeks e primaarvõtmeks. Ülejäänud on alternatiivsed võtmed e alternatiivvõtmed.Primaarvõti deklareeritakse kasutades PRIMARY KEY kitsendust.Alternatiivvõtmed deklareeritakse, kasutades UNIQUE + NOT NULL kitsendusi.Näiteks oletame, et tabelis Amet on kaks kandidaatvõtit: (amet_kood) ja (nimetus)(amet_kood) valitakse primaarseks.Tabeli loomise lauses: CONSTRAINT pk_amet_kood PRIMARY KEY (amet_kood)(nimetus) jääb alternatiivseks.Tabeli loomise lauses: CONSTRAINT ak_amet_nimetus UNIQUE(nimetus)Lisaks on veerul nimetus NOT NULL kitsendus. Miks NOT NULL kitsendus? Primaarvõtme veerud on automaatselt kohustuslikud - primaarvõtme väärtus ei tohi üheski reas puududa. Kuna võti on võti, siis pole alternatiivvõtmed halvemad ja ka nende väärtus ei tohiks üheski tabeli reas puududa.Seos teiste tabelitega luuakse tavaliselt primaarvõtme alusel - selleks, et tabelis Töötaja registreerida töötaja hetke amet, registreeritakse seal ameti kood, mitte ameti nimetus. **Märksõnad:** primaarvõti, kandidaatvõti, esmasvõti, võtmekandidaat ## Küsimus: Mis on intelligentne võti ja millal seda kasutada? **Vastus:** Üheks SQL tabelite võtmete liigiks on intelligentsed võtmed. Selliste võtmete väärtused omavad inimkasutajale sisulist tähendust ning võtme väärtusesse on kodeeritud informatsiooni. Sellise võtme näiteks on isikukood. Näiteks nii Eestis kui Soomes sisaldab see infot sünniaja ja soo kohta. Intelligentse võtme kasutamise väljakutseks on, et kui kodeering muutub, tuleb kõik sellest kodeeringust sõltuvad programmid ümber teha. Sellise võtme probleeme illustreerib hästi juhtum Rootsist, kus isikukoodid said suure pagulaste tulva tõttu otsa. Kuna ka Eesti isikukoodi osaks on järjekorranumber samal päeval sündinute eristamiseks, siis samasugune probleem võib tabada ka Eestit. Seda näiteks siis, kui e-residentsuse programm osutub ootamatult edukaks, sest ka e-residendid saavad isikukoodi. Viimaste uudiste kohaselt on Soomes arutusele tulnud kodeeringu muutmine. Põhjus on nii koodide otsalõppemine (vana skeem ei võimalda kõigile isikukoodi vajajatele unikaalset koodi genereerida) kui ka soov sooneutraalsuse järele. Moraal - koode, mis on "kõrgemalt poolt" (riik, standardiseerimisega tegelev organisatsioon, ettevõtte peakontor jne) ette kirjutatud tuleb kasutada, kuid ise ei peaks selliseid koode leiutama hakata. ## Küsimus: Mis on (lihtsalt selgitades) normaliseerimine ja normaalkujud? **Vastus:** Normaliseerimine on nagu mäetipp, mille otsas on auhind. Auhinnaks on see, et andmete liiasust (mis aeglustab ja muudab keerukamaks andmete muutmist) on andmebaasis vähem kui mäe jalamil (aga seda ikkagi on - see pole midagi, millest ühe tipu vallutamisega pääseb). Tipule vastab (SQL-andmebaaside näitel) viies normaalkuju ning mäe nõlval on peatuskohad, mis vastavad erinevatele madalamatele normaalkujudele (sealhulgas ka Boyce/Coddi normaalkuju). Praktikule, keda tulemus huvitab rohkem kui protsess, on lõpuks oluline jõuda tippu. Sinna saab erinevatel viisidel - kas mööda mäekülge üles ronides ja peatuskohtades peatudes (viies tabeleid järk-järgult üha kõrgematele normaalkujudele) või ka lennukist/kopterist langevarjuga hüpates, tipule või selle lähedale maandudes ja GPSiga kontrollides, kas sai tipule pihta või mitte (kas kõik tabelid on viiendal normaalkujul). Hüppamine on nagu mustrite põhjal loodud kvaliteetsest kontseptuaalsest andmemudelist andmebaasi disaini kirjelduse genereerimine.  Lihtsalt öeldes tähendab viies normaalkuju, et tabelit ei saa enam tükeldada väiksemateks ja algse tabeli täpset taastamist võimaldavateks osadeks nii, et tükkides on andmete liiasust vähem. Andmete liiasuse vähendamise mõttes on viies normaalkuju maksimum ja kõige olulisem. On ka kõrgemaid normaalkujusid (nagu kuues), kuid nendeni jõudmisel on juba teised auhinnad (näiteks lihtsam toimetulek puuduvate andmete ja skeemi evolutsiooniga). Enamik tabeleid, mis on kolmandal või Boyce/Coddi normaalkujul (populaarsed peatuskohad mäetipule ronides), on ka viiendal. Selle kohta on sõnastatud ja matemaatilised reeglid. ## Küsimus: Mis on olemitüüp, atribuut ja olem? **Vastus:** Kogu selle temaatika juures on suureks probleemiks terminoloogiline segadus. Näiteks erinevate autorite tekstides tähistavad järgnevad sõnad (terminid) sisuliselt sama mõistet. Klass Objektitüüp Olemitüüp Olem Põhiobjekt Näiteks erinevate autorite tekstides tähistavad järgnevad sõnad (terminid) sisuliselt sama mõistet. Objekt Objekti eksemplar Olem Eksemplar Olemi eksemplar Eriti halb on, kui neid sõnu kasutatakse läbisegi. Näiteks üks räägib olemitest ja olemi eksemplaridest, teine olemitüüpidest ja olemitest, kolmas objektidest ja objekti eksemplaridest, neljas klassidest ja objektidest, kuigi tegelikult mõtlevad nad sama asja. Samasugune probleem on seostega. Üks räägib seosetüüpidest ja seostest, teine seostest ja seoste eksemplaridest ning kolmas seosetüüpidest ja seoste eksemplaridest, kuigi tegelikult mõtlevad nad sama asja. Selline terminoloogiline segadus on paraku reaalsus. Näide, kus üritan seda terminoloogiat järjekindlalt kasutada. Reaalses maailmas on isik (omaduste e atribuutidega) (meiliaadress, mis ühtlasi eristab seda isikut kõigist teistest isikutest e on tema unikaalne identifikaator=)mari.maasikas2@hot.ee (eesnimi=)Mari (perenimi=)Maasikas. Reaalses maailmas on isik (omaduste e atribuutidega) (meiliaadress, mis ühtlasi eristab seda isikut kõigist teistest isikutest e on tema unikaalne identifikaator=)juhan.juurikas@hot.ee (eesnimi=)Juhan (perenimi=)Juurikas. Reaalses maailmas on Mari Maasikas Juhan Juurika ülemuseks. Nende tähelepanekute alusel sõnastab andmebaasi kavandaja kontseptuaalses andmemudelis vajaduse hoida andmebaasis isikute andmeid (meiliaadress, eesnimi, perenimi ning kes on kelle ülemus). Selleks kirjeldab ta seal olemitüübi Isik, millel on atribuudid e_meil, eesnimi ja perenimi. See vajadus joonistatakse UML keele klassidiagrammi abil loodud olemi-suhte diagrammile üles luues seal klassi Isik ja määrates sellele atribuudid e_meil, eesnimi ja perenimi. Kontseptuaalses andmemudelis ei modelleerita olemeid (Juhan Juurikas või Mari Maasikas), vaid nende üldistust (Isik). Samuti modelleeritakse olemi-suhte diagrammil seosetüüp on ülemus, mille mõlemad otsad on seotud klassiga Isik. Kontseptuaalses andmemudelis ei modelleerita seoseid (Mari Maasikas on Juhan Juurika ülemus), vaid nende üldistust (on ülemus). Kontseptuaalses andmemudelis sõnastatud nõude rahuldamiseks luuakse SQL-andmebaasis tabel Isik, kus on veerud e_meil, eesnimi ja perenimi + välisvõtme veerg ylemuse_id. Iga rida, mis sellesse tabelisse lisatakse, peab vastama selle tabeli päisele (mis määrab isiku kohta andmebaasis kogutavad andmed). Iga rida on kujutus/peegeldus reaalse maailma olemist (nt reaalsest lihast ja luust Juhan Juurikast). Reaalse maailma olem (nt kindel füüsiline isik) ja tema kujutis süsteemis (nt rida tabelis, JSON dokument või XML dokument) on tegelikult ju kaks ise asja, aga kõnekeeles ollakse sageli lühiduse huvides ebatäpsed ja räägitakse lihtsalt olemitest ja nende andmetest. ## Küsimus: Mis vahe on identifitseerival ja mitteidentifitseerival seosel tabelite vahel? **Vastus:** Identifitseeriv seos tähendab, et vanemtabeli reas olev võtmeväärtus aitab identifitseerida lapstabelis olevat rida. Seetõttu on vanemtabeli võti, mis on lapstabelis välisvõtmeks, osaks lapstabeli võtmest. Teiste sõnadega, lapsel pole oma identiteeti, vaid ta on identifitseeritav vanema kaudu, laps ei saa eksisteerida ilma vanemata ja koos vanemaga tuleks kustutada ka laps. Eelnevast nähtub, et selliste seoste puhul tuleks määrata kompenseeriv tegevus ON DELETE CASCADE.Näiteks oletame, et igal isikul on null või rohkem meiliaadressi ja null või üks kasutajakonto. Need on andmed isiku kohta, kuid on pandud eraldi tabelitesse (Meiliaadress ja Kasutajakonto), mis on välisvõtme kaudu seotud tabeliga Isik. Seosed tabelite Isik ja Meiliaadress ning Isik ja Kasutajakonto vahel on identifitseerivad seosed.Isik(isik_id, perenimi)Primaarvõti (isik_id)Meiliaadress(isik_id, e_meil)Primaarvõti (isik_id)Alternatiivvõti (e_meil)Välisvõti (isik_id) Viitab Isik (isik_id)Kasutajakonto(isik_id, parool, on_aktiivne)Primaarvõti (isik_id)Välisvõti (isik_id) Viitab Isik (isik_id)Kontseptuaalses andmemudelis öeldakse olemitüüpide Meiliaadress ja Kasutajakonto kohta, et need on nõrgad olemitüübid (weak entity types).   Mitteidentifitseeriv seos tähendab, et last ei identifitseerita vanema kaudu, lapsel on oma identiteet ja nende vahel ei ole eksistentsiaalset sõltuvust. Vanemtabeli võti ei ole osa lapstabeli võtmest ja vastava välisvõtme puhul ei kasutata ON DELETE CASCADE.Isik(isik_id, perenimi)Primaarvõti (isik_id)Tellimus (tellimuse_kood, tellija, summa)Primaarvõti (tellimuse_kood)Välisvõti (tellija) Viitab Isik (isik_id) ## Küsimus: Märkasin et te kirjutate SQL muutujaid eesti keeles, näiteks "nimi VARCHAR(10)". Arvestades et kõik ettevõtted ning arendajad kirjutavad tänapäeval muutujaid ja koodi inglisekeelselt, kas ma võin ka praktikaülesannetes ning iseseisvas töös kasutada inglise keelt? **Vastus:** Kui Te mõtlete iseseisvat tööd, siis loomulikult võite koodis kasutada ingliskeelseid nimesid. Töö tegemisel tuleb juurde lisasamm, kus kontseptuaalsest andmemudelist genereeritud tabelite kirjelduses tuleb nimed tõlkida. Mis puudutab praktikaülesannetes andmete otsimise või muutmise lausete kirjutamist, siis seal on kirjutaja piiratud nimedega, mis on andmebaasis kasutusel. Mis puudutab praktikaülesandeid muuta olemasoleva andmebaasi struktuuri (lisada tabeleid, veerge, kitsendusi), siis kasutada ühes andmebaasis läbisegi erinevaid keeli ei ole ilus ega ka kooskõlas puhta koodi põhimõtetega. Tahan rõhutada et kõik puhta koodi (sh nimetamise) üldpõhimõtted kehtivad sõltumata kasutatavast inimkeelest. Eesti keel on keel nagu iga teinegi ja sobib asjade nimetamiseks täpselt sama hästi. Seega minu arvates ei ole õigustatud arvamus, et andes asjadele nimesid eesti keeles õpime või teeme midagi valesti. Olulisemad on põhimõtted (ainsus vs. mitmus, snake_case vs. PascalCase vs. camelCase, regulaarne vs. piiritletud identifikaator), kui see, mis inimkeeles on see nimi kirjutatud. Aga veelkord - oma iseseisva töö projektis kasutage nimetamise stiili, mida ise paremaks peate. Peaasi, olge järjekindel.Kontseptuaalne andmemudel kirjeldab nõudeid. Nõuded tulevad süsteemi tellijatelt ja kasutajatelt. On täiesti loomulik, et nõuded esitatakse keeles, mis on tellijatele ja kasutajatele hästi arusaadav. Kui kasutate tabelite/veergude/kitsenduste nimetamisel inglise keelt, kuid kontseptuaalses andmemudelis eesti keelt, siis võiks kontseptuaalse andmemudeli olemitüüpide ja atribuutides definnitsioonide juures olemitüüpide ja atribuutide nimed olla nii eesti keeles kui ka sulgudes inglise keeles. **Märksõnad:** identifikaator, nimi, nimetamine ## Küsimus: Otsin omale põnevat lugemist andmebaaside (pigem relatsiooniliste, aga miks mitte ka teiste) antimustrite kohta. Mäletan Teiega andmebaaside kursust läbides, et erinevate materjalide nimed käisid läbi, aga mõtlesin küsida soovitust otse allikast. Mida võiks lugeda? Soovitatavalt võiks materjal olla inglise keeles (saaks jagada ka mitte-eestlastega), aga endale huvi pärast lugemiseks oleks eestikeelne materjal ka väga kasulik. Soovitused on teretulnud nii veebilinkide, dokumentide kui raamatusoovituste kujul. **Vastus:** Antimuster klassikalises mõttes on struktuurse kirjutamise viis, kus lisaks probleemile ja selle halvale lahendusele tuuakse välja ka see, kuidas seda probleemi paremal viisil lahendada ning ka see, millisel juhul võib halb lahendus osutuda väljakannatatavaks. SQL-andmebaaside disaini sagedased probleemid on antimustritena raamatusse kirja pannud Bill Karwin. Tema raamatut saab laenutada ülikooli raamatukogust (https://www.ester.ee/record=b2888667*est), seda saab lugeda O'Reilly digitaalselt platvormilt (https://learning.oreilly.com/library/view/sql-antipatterns/9781680500073/?ar; sellele on Tehnikaülikooli üliõpilastel juurdepääs).   Siis on olemas tasuta raamat kus kirjeldatakse 150-t võimalikku disainiprobleemi MS SQL Server andmebaasides: https://assets.red-gate.com/community/books/sql-code-smells.pdf Mõned nendest probleemidest on spetsiifilised MS SQL Serveri jaoks, kuid enamik võib esineda mistahes SQL-andmebaasides. Probleemide kirjeldamisel ei kasutata mustri formaati.Siia on kirja pandud viis viga, mida SQL-andmebaasi disainimisel tuleks üritada vältida: https://www.red-gate.com/simple-talk/databases/sql-server/database-administration-sql-server/five-simple-database-design-errors-you-should-avoid/   Mis puudutab NoSQL süsteeme, siis neid iseloomustab standardite puudus (kuid see on näiteks graafiandmebaaside puhul muutumas: https://www.gqlstandards.org/) ja lugemise skeemi eelistamine kirjutamise skeemile (andmete struktuuri ei kirjeldata andmebaasi tasemel ja andmebaasisüsteem ei kontrolli andmete struktuurile vastavust andmete salvestamisel) (kuid ka see on muutumas). Tulemuseks on, et turule jõudnud kümnetes, et mitte öelda sadadest NoSQL süsteemidest tehakse igaühes asju omamoodi ja paljusid süsteeme läbivaid disaini probleeme ei saa / on raske välja tuua. Probleemid ja nende kirjeldused on süsteemi-spetsiifilised. Raamatus "Seven NoSQL Databases in a Week" (Seitse NoSQL süsteemi nädalaga), mida saab O'Reilly keskkonna kaudu lugeda, kirjeldatakse seitset NoSQL andmebaasisüsteemi (https://learning.oreilly.com/library/view/seven-nosql-databases/9781787288867/?ar). Osade süsteemide peatükkides on antimustrite alapeatükk, kus kirjeldatakse lühidalt võimalikke probleeme. Need kirjeldused ei ole mustri formaadis.   Sellest raamatust hakkas valusalt silma tekstilõik: "Neo4j involves appropriately modeling the required queries. Relational modeling requires you to focus on how your data is stored, and not as much on how it is queried or returned." See esitab valeväiteid. Relatsiooniline mudel ei kirjuta ette, kuidas andmebaasisüsteemi tarkvara peab sisemiselt andmeid salvestama. See on andmebaasisüsteemide (mudeli realisatsiooni) küsimus. Mudel ja realisatsioon on kaks ise asja nii nagu projekt või tarkvara või plaan ning plaani täitmine on kaks ise asja. Ühes või teises relatsioonilist mudelit realiseerivas süsteemis võib andmete salvestamine olla tehtud nii, et andmete struktuur ja selle muutmine mõjutab ka andmete käitlemise operatsioonide jõudlust. Kuid see on konkreetse süsteemi realisatsiooni, mitte relatsioonilise mudeli probleem. Konkreetseid süsteeme tutvustavate, mitte üldistest põhimõtetest kirjutavate, allikate häda on selles, et need vananevad väga kiiresti ja saadud teadmine kehtib ühes konkreetses kohas - üks süsteem (sageli ainult mõnes selle kindlas versioonis).   Leidub päris mitmeid teadusartikleid, kus on uuritud SQL-andmebaaside disainiprobleeme. Need artiklid nimetavad probleeme ja uurivad nende esinemist erinevates andmebaasides, kuid probleeme ei esitata mustri formaadis. Nimetan järgnevalt mõningaid artikleid. Google Scholar (https://scholar.google.com/) kaudu otsides leiab nende artiklite avalikud täistekstid.   Blaha, M.: A retrospective on industrial database reverse engineering projects - part 2. In:  Eighth Working Conference on Reverse Engineering, pp. 147–153. IEEE, (2001). https://doi.org/10.1109/WCRE.2001.957818 Vana artikkel 35 SQL-andmebaasi pöördprojekteerimise tulemuste kohta. Nendes oli masendavalt palju puuduvaid kitsendusi. Minu kogemus näitab, et 20 aastat hiljem  pole taolised probleemid andmebaasidest kuhugi kadunud.   Blaha, M.R., Premerlani, W.J.: Observed idiosyncracies of relational database designs. In: 2nd Working Conference on Reverse Engineering, pp. 116–125. IEEE, (1995). https://doi.org/10.1109/WCRE.1995.514700 Jällegi vana artikkel, kuid siin nimetatud artiklitest üks kõige suurem hulk erinevaid SQL-andmebaasi disainiprobleeme. Paraku, kuna vigadest õppimine pole kombeks, siis see, et artikkel on vana ei tähenda, et neid vigu uutes andmebaasides ei tehta. Weber, J.H., Cleve, A., Meurice, L., Ruiz, F.J.B.: Managing technical debt in database schemas of critical software. In: Sixth International Workshop on Managing Technical Debt, pp. 43–46. IEEE (2014). https://doi.org/10.1109/MTD.2014.17 Puuduvatest välisvõtme kitsendustest ja sellest tulenevast tehnilisest võlast.   Al-Barak, M., Bahsoon, R.: Database design debts through examining schema evolution. In: 8th International Workshop on Managing Technical Debt, pp. 17–23. IEEE, (2016). https://doi.org/10.1109/MTD.2016.9 Esitatakse üks võimalik SQL-andmebaaside disainiprobleemide liigitus ja nimetatakse neid probleeme. Delplanque, J., Etien, A., Auverlot, O., Mens, T., Anquetil, N., Ducasse, S.: CodeCritics applied to database schema: Challenges and first results. In: 24th International Conference on Software Analysis, Evolution and Reengineering, pp. 432–436. IEEE, (2017). https://doi.org/10.1109/SANER.2017.7884648 Muuhulgas tutvustatakse SQL-andmebaaside disainiprobleemide otsimiseks mõeldud tarkvara ning nimetatakse 11 probleemi, mida see tarkvara suudab tuvastada.   Sharma, T., Fragkoulis, M., Rizou, S., Bruntink, M. and Spinellis, D.: Smelly relations: measuring and understanding database schema quality. In: 40th International Conference on Software Engineering: Software Engineering in Practice, pp. 55–64. ACM, (2018). https://doi.org/10.1145/3183519.3183529 Tutvustatakse SQL-andmebaaside disainiprobleemide otsimiseks mõeldud tarkvara. Nimetatakse 13 probleemi, mida see tarkvara suudab tuvastada. Uuritakse nende probleemide esinemist suures hulgas avatud lähtekoodiga süsteemide andmebaasides ja ka nende probleemide koosesinemist (kui esineb üks probleem, siis millised teised sellega sagedasti koos esinevad).   Dintyala, P., Narechania, A., Arulraj, J.: SQLCheck: automated detection and diagnosis of SQL anti-patterns. In: 2020 ACM SIGMOD International Conference on Management of Data, pp. 2331–2345. (2020). https://doi.org/10.1145/3318464.3389754 Muuhulgas tutvustatakse SQL-andmebaaside disainiprobleemide otsimiseks mõeldud tarkvara ning nimetatakse 26 probleemi, mida see tarkvara suudab tuvastada. Foidl, H., Felderer, M., Biffl, S.: Technical Debt in Data-Intensive Software Systems. In: 45th Euromicro Conference on Software Engineering and Advanced Applications, pp. 338 –341. IEEE, (2019). https://doi.org/10.1109/SEAA.2019.00058 Üks oluline mõte on, et viga ühes süsteemi osas võib tekitada probleeme teistes süsteemi osades. Näiteks puuduvad andmebaasi kitsendused vähendavad andmete kvaliteeti ja muudavad keerukamaks ning veaohtlikumaks andmebaasirakenduste realiseerimise. Eessaar, E.: Automating detection of occurrences of PostgreSQL database design problems. In: Robal, T., Haav, H.M., Penjam, J., Matulevičius, R. (eds) Databases and Information Systems. DB&IS 2020. Communications in Computer and Information Science, vol 1243. Springer, Cham. (2020) https://doi.org/10.1007/978-3-030-57672-1_14 Tutvustatakse PostgreSQL andmebaasi disaini kontrollimiseks mõeldud päringute kataloogi (https://github.com/erki77/database-design-queries). Suur osa nendest päringutest (problem detection queries) otsivad andmebaasi disaini probleemide esinemisi ja enamik nendest probleemidest ei ole PostgreSQL-spetsiifilised. Seega on ühtlasi tegemist ka disaini vigade kataloogiga ja selles esitatud päringud on nagu käivitatavad vigade spetsifikatsioonid. Võrreldes eelnevate artiklitega on selles kataloogis palju rohkem disaini probleeme. Balogh, G., Gergely, T., Beszédes, Á., Szarka, A., Fábián, Z.: Capturing expert knowledge to guide data flow and structure analysis of large corporate databases. Acta Polytechnica Hungarica 16(4), 7–26 (2019). Suurte süsteemide, sh andmebaaside analüüsimine tehniliste puuduste osas on keeruline ettevõtmine. Selleks on vaja toetavat tarkvara. Artikkel kirjutab esimestest sammudest, mis on tehtud reeglipõhise analüüsisüsteemi loomise suunas. Brass, S., Goldberg, C.: Semantic errors in SQL queries: A quite complete list. Journal of Systems and Software, 79(5), 630-644. (2006). https://doi.org/10.1016/j.jss.2005.06.028 SQL päringute vigade kataloog. **Märksõnad:** antimuster, anti pattern, muster, pattern ## Küsimus: Teeme projekti töövihiku järgi. Meil on andmebaasis järgmise kontseptuaalse andmemudeli järgi loodud tabelid: [Treening]-1----------0..*-[Treeningu_kategooria_omamine]-0..*---------1-[Treeningu_kategooria] [Treening]-1----------0..*-[Treeningu_põhimõttelise_toimumise_asukoht ]-0..*---------1-[Ruum] Milliste välisvõtmete puhul tuleks kasutada ON DELETE CASCADE ja milliste puhul mitte? **Vastus:** Teie andmebaasis on kaks sarnast (mitu-mitmele seost realiseerivat) tabelit. Treeningu_kategooria_omamine Treeningu_põhimõttelise_toimumise_asukoht Nendes on kokku neli välisvõtit. ON DELETE CASCADE kasutamise üle otsustamisel tuleks mõelda, milline oleks primaartabelist ühe rea kustutamise mõju sõltuvale tabelile. Analüüsin ükshaaval kõiki välisvõtmeid mõttega, et nende puhul oleks määratud "ON DELETE CASCADE". 1. Primaartabel: Treening Sõltuv tabel: Treeningu_kategooria_omamine Kui kustutan rea tabelist Treening, siis kustuvad ainult selle konkreetse treeningu kategooria omamised. Muudatus mõjutab ainult neid, kes kasutavad selle ühe treeningu andmeid. Kustutamine ei sega ega takista teistele treeningutele kategooriate määramist. Võib öelda, et muudatuse mõju on lokaalne. ON DELETE CASCADE toetaks kasutusjuhu Unusta treening läbiviimist. 2. Primaartabel: Treening Sõltuv tabel: Treeningu_põhimõttelise_toimumise_asukoht Sama, mis esimene. 3. Primaartabel: Ruum Sõltuv tabel: Treeningu_põhimõttelise_toimumise_asukoht Kui kustutan rea tabelist Ruum, siis mõjutab see kõiki treeninguid, millele see ruum on asukohaks märgitud (võib olla kümneid või isegi sadu). Võibolla mõni treening jääks üldse ilma ruumita. Kui treeningute haldur on treeningule märkinud ruumi ja siis selgub, et seda ruumi polegi tegelikult olemas või see kaob kasutusest, siis korrektne asjaajamine dikteerib, et treeningute haldurit tuleb sellest informeerida ning temaga koos leida lahendus, millist ruumi ikkagi treeningute jaoks kasutada. Äkki tuleb välja, et mõne treeningu läbiviimiseks ei olegi ühtegi sobivat ruumi ja seda treeningut ei saagi läbi viia (treening tuleb lõpetada või unustada). Võib öelda, et muudatuse mõju on globaalne. ON DELETE CASCADE ei peaks kasutama. Selle asemel sobib ON DELETE NO ACTION. Kui süsteemis on kasutusjuht Unusta ruum, siis ON DELETE NO ACTION aitab jõustada reegli, et kasutuses ruume ei saa unustada (andmeid kustutada), vaid need tuleb lõpetada ja vajadusel lõpetatavale ruumile sobiv asendus leida. 4. Primaartabel: Treeningu_kategooria Sõltuv tabel: Treeningu_kategooria_omamine Kui kustutan rea tabelist Treeningu_kategooria, siis mõjutab see kõiki treeninguid, mis on sellesse kategooriasse määratud (võib olla kümneid või isegi sadu). Võibolla peale seda ei kuulugi enam mõni aktiivne treening ühtegi kategooriasse. See läheb aga vastuollu analüüsi dokumendis seisundidiagrammis väljendatud reegliga, et iga aktiivne treening peab olema seotud vähemalt ühe kategooriaga. Kategooriaid kasutatakse treeningute otsimiseks. Kui treening pole üheski kategoorias, siis ei saa kliendid selle andmeid vaadata (vt kasutusjuhtu Vaata aktiivseid treeninguid). Võib öelda, et muudatuse mõju on globaalne.ON DELETE CASCADE ei peaks kasutama. Selle asemel sobib ON DELETE NO ACTION. Kui süsteemis on kasutusjuht Unusta klassifikaator, siis ON DELETE NO ACTION aitab jõustada reegli, et kasutuses klassifikaatori väärtuseid ei saa unustada (kustutada), vaid need tuleb lõpetada ja vajadusel lõpetatavale väärtusele sobiv asendus leida. ## Küsimus: Töövihiku järgi on juba olemas klassifikaator Riik, mis on siis seotud kliendiga seoses isikukoodiga. Kui me soovime lisada klassifikaatori Riik ka Pakettreisile, kas sobib kasutada sama klassifikaatorit või peaksime tegema lisaks Pakettreisi_Riik. Pakettreisi_Riigis ilmselt on vähem võimalikke väärtusi. **Vastus:** Mitte ainult ei sobi, vaid see on ainuõige lahendus.   Näiteks avaliku teabe seadus ütleb (põhjusega)"§ 43-3.  Andmekogu asutamine(2) Keelatud on asutada ühtede ja samade andmete kogumiseks eraldi andmekogusid."   Andmete dubleerimine võib küll mõnikord parandada töökiirust, kuid samas tekitab see andmete muutmise anomaaliaid. Klassifikaatorite dubleerimine samas andmebaasis ei paranda töökiirust, aga andmete muutmise anomaaliad tekivad ikka. **Märksõnad:** dubleerimine, klassifikaator --- # Teema: Korraldus - iseseisev töö ## Küsimus: Kas CASE vahendis tehtud mudelitesse tuleb lisada kõik põhiobjektid, mida oleme töövihikusse kirjutanud, või ainult need, millest räägitakse juhendis? Näiteks, meil on põhiobjektide hulgas "Partner" ja "Tätoveerija", kuid juhendis keskendutakse "Klient" ja "Töötaja" täiendamisele. **Vastus:** Ei. Kontseptuaalses andmemudelis tuleb kajastada ainult seda andmebaasi alamosa, mida on vaja kasutusjuhtude mudelis kirjeldatud funktsionaalsuste pakkumiseks.Tätoveerija ei peaks ilmselt olema põhiobjekt, sest selle elutsüklid ning neid kirjeldav seisundidiagramm pole erinev töötaja seisundidiagrammist. Põhiobjekt on Töötaja ja "tätoveerija" on üks töötaja roll.Põhiobjekti Partner peaks kontseptuaalses andmemudelis kajastama ainult siis, kui Teie töös leidub mõni kasutusjuht, mille täitmiseks peab lugema partnerite andmeid. Minu arvates töövihiku järgi projekti tehes sellist kasutusjuhtu ei leidu. ## Küsimus: Kas iseseisva töö ülevaatamisel peavad olema kohal kõik projekti tegijad? **Vastus:** Ei pea, kuid teadmiste saamise eesmärgil oleks mõistlik. See ei ole kaitsmine. Õppejõud vaatab koos vähemalt ühe autoriga töö üle ning teeb talle suuliselt teatavaks puudused mis tuleb arvestuse saamiseks kõrvaldada. Need tuleb üles kirjutada. Kui õppejõuga suhtleb ning märkmeid teeb mitu inimest, siis on väiksem võimalus, et midagi jääb kahe silma vahele. Kui kõik on kohal, siis jõuab kõigi osalisteni info vigade kohta kiiremini ja see võimaldab ka kiiremini ja paremini vigu parandada. ## Küsimus: Kas ma peaksin enne iseseisva töö prototüübi tegema hakkamist näitama õppejõule dokumentatsiooni ette? **Vastus:** See ei ole kohustuslik, kuid on mõistlik juhul kui olete otsustanud teha töö nullist ja omal teemal, mitte kasutada etteantud malli. Seda saab teha praktikumi ajal või alates 12. õppenädalast vastuvõtuajal. Kirja teel projekte üle ei vaadata. ## Küsimus: Kas ma võin minna üle ühest iseseisva töö tegijate rühmast teise üle? **Vastus:** Liitumine olemasoleva rühmaga (kaks üliõpilast), et nende projekti edasi teha on lubatud kuni kaheksanda õppenädala lõpuni. Peale seda on lubatud projektist eraldumine ja projekti üksinda tegemine, projekti liikme projektist väljaarvamine teiste liikmete poolt ning samuti kahe või kolme üksinda projekti tegija üheks tegijate rühmaks liitumine. Projekti liikmete muutmisel tuleb arvestada piiranguga, et projektis võib olla kuni kolm liiget. Projekti liikmete hulga muutusest õppejõu teavitamiseks on ainus viis muuta teema registreerimise ülesande vastust Mauruses. Kui seda pole tehtud, siis järelikult pole rühm muutunud. ## Küsimus: Kas ma võin muuta iseseisva töö registreeritud teemat? **Vastus:** Jah võib. Sellest mulle teada andmiseks muutke palun Mauruse keskkonnas iseseisva töö teema registreerimise ülesande vastust. Õppejõud näeb kui vastust on muudetud ja saab selle kaudu muudatusest teada. ## Küsimus: Kas ma võin vaadata teiste üliõpilaste projektide kaitsmisi? **Vastus:** Jah võite ja see on isegi väga soovitav. Ülevaatused toimuvad alates 13. õppenädalast täielikult MS Teamsis ja need kohtumised on kõigile huvilistele avalikud. Kui projekt pole veel valmis ja arvestust saanud, siis osalege vähemasti oma tunniplaani järgses praktikumis (loomulikult võite tulla ka mõnda teise tundi!) ja vaadake palun teiste üliõpilaste tehtud tööd. Enamik võimalikest probleemidest on ühised paljudele projektidele. Nii nagu haiguste ennetamine on kasulikum haiguste ravimisest on ka projekteerimise korral palju odavam ja mugavam vigu ennetada, mitte neid tagantjärgi parandada. Hindan, et vähemalt 80% vigadest kordub paljudes projektides. ## Küsimus: Kas me saame töövihiku projekti korral ära kustuta diagrammidelt mentor ja juhendatav seose? **Vastus:** Töövihiku valmistehtud osi projektist eemaldada ei tohi. Diagrammilt (nt X registri olemi-suhte diagramm) võite selle kustutada, kuid seda ei tohi kustutada mudelist. Räägin praegu seosetüüpi tähistava joone pildilt eemaldamisest. See seosetüüp peab olema kindlasti nähtav töötajate registri olemi-suhte diagrammil. Andmebaasis tuleb see seosetüüp realiseerida. ## Küsimus: Kas töövihiku tüüpi projekti korral võib mitu rühma teha projekti samal teemal? **Vastus:** Jah võib. ## Küsimus: Kas ühes "Andmebaasid I" aine projekti tegijate rühmas võivad olla inimesed erinevatest gruppidest? **Vastus:** Projekti rühmas võivad olla üliõpilased erinevatest gruppidest, kes käivad erinevatel aegadel praktikumis ja kes võivad ka õppida erinevate õppekavade järgi. Kõikidele üliõpilastele on nõuded projekti osas ühesugused. Kui praktikumis toimub projektiga tegelemine, siis on oluline, et kõik kohalkäinud annaksid oma tunni töö järgmisele tundi tulijale üle. **Märksõnad:** meeskond, rühm, tiim ## Küsimus: Kuidas esitada iseseisev töö? **Vastus:** Iseseisva töö esitamiseks (sõltumata sellest, kas tegemist on lõplikult valmis versiooniga või vaheversiooniga, millele soovite konsultatsiooni käigus tagasisidet) valige õppekeskkonna vasakpoolsest menüüst "Kiirvalik=>Ülesanded" ning avanenud leheküljelt ülesanne "Iseseiseva töö failide saatmine". Ülesande vastusena saab saata ka faile. Ülesandele esmakordselt vastamine.Vajutage ülesande juures "Lisa ainult faile". Avanenud aknas on iga küsimuse juures võimalus valida fail (nupp Browse) ning "Laadi üles" nupule vajutades see üles laadida.Ülesande vastuse parandamine.Vajutage ülesande juures "Paranda/Muuda vastust". Avanenud lehel saab kustutada küsimustega seotud faile ja lisada uusi faile.NB! Proovige kontrolli eesmärgil enda üleslaetud faile alla laadida!NB! Nupule "Salvesta teksti muutused" tuleb vajutada vaid siis, kui lisaks failidele kirjutasite midagi ka küsimuste vastuste lahtritesse. NB! Iseseisva töö lõpliku versiooni esitamisel peab vastuse saatma üks projekti liige. ## Küsimus: Kuidas registreerida iseseisva töö projekti teema? **Vastus:** Tähtajaga 14. veebruar 2025 (kaasa arvatud) tuleb vastata iseseisva töö valikuga seotud küsimustele (st saada selgeks ülesande püstitus, valida teema ja panna kokku tegijate rühm). Seda tuleb nii varakult teha, et saaks alates kolmandast nädalast praktikumides sisukalt ja efektiivselt kaasa töötada. Iseseisva töö registreerimiseks valige õppekeskkonna vasakpoolsest menüüst "Kiirvalik=>Ülesanded" ning avanenud leheküljelt ülesanne "Iseseiseva töö teema registreerimine". Kui teete iseseisvat tööd rühmatööna, siis peab teema registreerima üks rühma liige (iseseisvat tööd võib teha 1-3 liikmelistes rühmades). Enne vastamist on kindlasti vaja tutvuda ülesande püstitusega. Kui teete projekti üksinda, kuid otsite kaaslast, siis on võimalik seda soovi iseseisva töö teema registreerimisel väljendada. ## Küsimus: Kuidas toimub iseseisva töö projektide ülevaatamine? **Vastus:** Kuni 11. õppenädalani (kaasa arvatud) tuleb projekti näitamiseks tulla praktikumi (eelregistreerimist pole vaja). Alates 12. õppenädalast peab projekti näitamiseks Mauruses eelregistreeruma.Kuni 12. õppenädalani (kaasa arvatud) tuleb projekti näitamiseks tulla kas füüsiliselt klassi või siis saab seda teha ka Teamsis. Alates 13. õppenädalast toimuvad kõik projektide ülevaatused Teamsis.Kõik ettenäitamised on avalikud. See tähendab, et õppejõud vaatab töid oma arvutis ning jagab ekraanipilti MS Teamsis kohtumisel osalejatele. Soovitan tulle vaatama ja kuulama (link kohtumisel osalemiseks tekib MS Teamsis grupi Andmebaaside õppeained kanalisse ITI0206-K-2025). Vestluste käigus tulevad kiiresti välja tüüpilised vead ja saate neid oma projekti juures kasvõi kohe parandada, et tulla oma projekti ettenäitamisele parema projektiga.Iseseisva töö ülevaatamise protsessi visuaalset kirjeldust saate vaadata SIIT. **Märksõnad:** iseseisev töö, projekt, ülevaatus, ülevaatamine, ettenäitamine, kaitsmine, kaug, kaugtöö ## Küsimus: Kui meie projekti teemaks on "Spordiklubi infosüsteemi treeningu funktsionaalne allsüsteem", kas meie tohime panna nii, et treener ja treeningu haldur on üks ja sama inimene ehkki tegutsejate alla paneme ainult "Treener"? Ja edaspidi, kus mallis on kirjas X haldur asendame siis ainult "Treener"-iga. **Vastus:** Treener ja Treeningute haldur on rollid, mitte füüsilised isikud. Ühel ja samal füüsilisel isikul võib olla mitu erinevat rolli. Selle jaoks on töövihiku järgi valmivas andmebaasis andmed töötajate rollide ja nende rollide omamiste kohta. Mida vähem on rolle, seda vähempaindlikum on infosüsteemile juurdepääsu andmine ning see hakkab pärssima ettevõtte äriliste eesmärkide täitmist. Näiteks meie ülikooli õppeinfosüsteemis ei ole õppeained mitte õppejõudude registreeritud, vaid seda on teinud õppeainete halduri rollis isik, kelleks on mõni töötaja õppeosakonnast. Kui õppejõud saaks hallata õppeaineid, siis saaks ta seda teha erinevatel õppeainetel (ka nendes, mis temasse kuidagi ei puutu) ning saaks teha kooskõlastamata muudatusi. Samuti peaks teda siis tasustama tööülesannete eest, mis tema pädevusse ei kuulu.Seega Teie pakutud muudatus töövihikusse ei sobi. Küll aga peaks vastavalt töövihiku sammule lisama kasutusjuhtude mudelisse tegutseja e rolli Treener ning tema tööülesannete läbiviimise võimaldamiseks siduma kasutusjuhtudega "Tuvasta kasutaja" ning "Vaata kõiki treeninguid" (nii diagrammil e skeemil kui ka kõrgtaseme ja laiendatud formaadis tekstikirjeldustes). ## Küsimus: Kui palju andmebaasioperatsioonide lepinguid peab olema iseseisvas töös laialt kirjeldatud? Näidisprojekti kasutujuhtude kirjelduses (punkt 2.1.1) on neid üsna palju, kuid operatsioonide lepingute kirjelduses (punkt 2.2.2) neid leidub neid vähem. Millised on nõuded selle projekti osa kohta? **Vastus:** Operatsioonide lepingud tuleb kirjutada kõigi nende operatsioonide kohta, mis täidavad mõlemat järgnevat tingimust. a) neid vajavad projektis käsitletavad kasutusjuhud, b) nende käigus lisatakse/muudetakse/kustutatakse andmebaasis olevaid andmeid. Operatsioonide lepinguid ei tule kirjutada operatsioonide kohta, mille käigus ainult ainult loetakse andmebaasis olevaid andmeid. ## Küsimus: Kus on kirjas, millised projekti osad tuleb iseseisvas töös täita? **Vastus:** Kevadise iseseiseva töö dokument hõlmab mallis peatükke 1, 2, 3, 6 ja 7. Lisaks tuleb teha projekteeritud süsteemi andmebaasi prototüüp (kogu projekti mahus) ja rakenduse funktsionaalne prototüüp ühe töökoha ulatuses. Kui vaatate iseseisva töö dokumendi malli - kõik pealkirjad, mille alla peab aine projektis midagi kirjutama, EI OLE tähistatud sinisega (sinisega osa on õppeaine "Andmebaasid II" jaoks). ## Küsimus: Ma ei registreerinud õigel ajal iseseisva töö teemat. Mis nüüd saab? **Vastus:** Miinuseid selle eest ei saa. Kuid registreerige esimesel võimalusel oma vastused. Mida hiljem Te hakkate iseseisvat tööd tegema, seda hiljem see valmis saab ja seda vähem saab selle eest punkte. ## Küsimus: Ma ei tunne hästi ühtegi valdkonda, milles tegutseva ettevõtte/organisatsiooni kohta saab teha projekti töövihiku järgi? Mida teha? **Vastus:** Tarkvara kirjutamine vajab nõudeid ning nõuded tulenevad valdkonnast, millele tarkvara luuakse. Seega, ega valdkonna hästi tundmine loomulikult kahjuks ei tule. Samas ma kahtlustan, et enamik töövihiku järgi projekti tegijatest (keda on valdav enamik kuulajaskonnast) ei tunne oma projekti valdkonda (restoran, juuksurisalong, spordiklubi, tootmisettevõte, jne) süvitsi. Teisalt pole see minu arvates eriline takistus, sest: täiendused töövihikusse tegelikult ei nõua valdkonna süvitsi tundmist, piisavat taustainfot saab koguda ka lihtsalt selle valdkonna ettevõtete kodulehti vaadates ning suurtele keelemudelitele küsimusi esitades. Valdkonna mingil määral tundmist on vaja näiteprojektis/töövihikus alajaotise 1.1 täitmiseks ning samuti veidi kontseptuaalse andmemudeli juures. Muudes kohtades asendate X-e (nt X=>Teenus) ja saategi kas täiesti valmis või peaaegu valmis tulemuse. See ongi eesmärk, sest aine on ikkagi andmebaaside aine ja ei tahaks kulutada suure osa semestrist näiteks funktsionaalsete nõuete kogumisele ja kirjapanekule. Selline X-i asendamine annab need nõuded sisuliselt tasuta kätte. ## Küsimus: Miks tasub iseseisva töö projekti teha rühmatööna? **Vastus:** Selleks, et harjutada koostööd ja suhtemist. Artikkel Postimehes (15.02.2018) kirjutab, et IT ettevõtted tunnevad puudust spetsialistidest, kes on koostööaltid ja head suhtlejad. ## Küsimus: Mul on küsimus andmebaaside I projekti kohta. Kas me põhiobjektid, mis alguses töövihikus olid võime muuta ja mõned kustutada, või me peame ainult enda oma põhiobjektid juurde lisada originaalseid puudutamata? **Vastus:** Kustutada ei või: Isik, Töötaja, Klient, Klassifikaator, X. Nende olemasoluga arvestatakse järgnevates dokumendi osades. Ülejäänusid võib kustutada, kuid tuleb pidada silmas, et siis tuleb muuta ka teisi punkte alajaotises 1.1​Soovitan kustutamise asemel keskenduda sellele, mida ise lisate. Töövihikusse on kirja pandud asjad, millega üldiselt tuleb peaaegu igas organisatsioonis/infosüsteemis tegeleda. **Märksõnad:** töövihik ## Küsimus: Projekti juhend on liiga pikk. Mida teha? **Vastus:** Tagasisides kirjutati: "Küll aga leian, et andmebaasi projektiga seotud materjalid (nt "Projekti juhend" või "Kommentaarid iseseisvate tööde kohta" ja projekti töövihik) laskusid liigsõnalisusesse ja liigsesse detailsusesse, mis raskendab konkreetse info saamist. Täpseid näiteid selle kohta on keeruline tuua, kuna tegemist on pigem teksti kui terviku probleem, aga parema arusaamise nimel, toon arbitraarselt välja ühe lõigu failist "Projekti juhend" (lk 7):  "Kui seisate kunagi ülesande ees automatiseerida tööd ja võtta selleks kasutusele (uus) tarkvara  /---/  Väidan, et enamike selle aine teemade jaoks on selline tarkvara olemas, seega päriselus sellise uue tarkvara tegemiseks peab olema väga hea põhjus (innovatsioon)."  Saan aru, et see lõik (koos eelneva ja järgneva tekstiga) selgitab projekti tegemise tagamaid, aga küsimus on selles, kas taoline essee-laadne kõrvalepõige on õigustatud niigi mahukas dokumendis (33 lehekülge), mis peaks justkui olema praktilise töö juhend."Minu mõtted. Kõige lihtsam projekti juhend on vaadata näiteprojekti ja teha midagi samasugust. Ei pea ennast muude juhendite lugemisega vaevama. PDF failis on pealkirjade struktuur. Neid saab vaadata ka veebilehitsejas ja need võimaldavad dokumendis navigeerida. Viidatud lõik on sissejuhatavas osas samas kui projekti tegemise samm-sammuline juhend on peatükis 6. Juba õige pea peate tegema lõputöö. Võite seal esitada huvitava ja ägeda programmi või infosüsteemi, kuid kui Teie lõputöö dokumenti põhiosa moodustavad lakoonilised mudelid, programmi lähtekood, või kasutusjuhend ilma täiendavate selgitusteta, siis ei tasu oodata suurepärast, ega isegi mitte väga head hinnet. Lõputöös (igasuguses töös) tuleb aru saada ja osata teistele selgitada, mida teed, miks teed ning miks teed just nii ja mitte teisiti. Õppijana peaks olema eesmärk saada aru, milleks mingeid tegevusi tehakse ja mis olukorras neid sobib või ei sobi teha. Tuleviku tööturul on inimeste eelis tehisintellekti vahendite ees (mille esimene pääsuke on ChatGPT) see, et inimene saab asjadest rohkem ja paremini aru ning oskab oma teadmisi loominguliselt rakendada. Juhiste järgi korduvate tegevuste tegemisega saab arvutisüsteem kindlasti paremini hakkama kui inimene. ## Küsimus: Soovin leida kaaslast või kaaslaseid, kellega koos projekti teha. Mida teha? **Vastus:** Variandid (võib kasutada kõiki): Suhelge oma kaaslastega väljapool tunde. Registreerige Kiirvalik=>Ülesanded all vastuse selleteemalisele küsimusele. Seal saab oma soovi panna kirja nii siis, kui teete üksinda ja otsite kaaslast/kaaslaseid või kui teete projekti kahekesi ja otsite kolmandat projektirühma liiget. Annate loengu või praktikumi alguses või lõpus oma soovist teistele osalejatele teada. Annate oma soovist teada õppeaine MS Teamsi rühmas. NB! Kui leiate hiljem projekti tegemiseks kaaslase(d), siis tuleb sellest muudatusest mulle teada anda, muutes iseseisva töö teema registreerimise ülesande vastust. NB! Üksik üliõpilane ei saa liituda kahese projekti rühmaga peale kaheksanda õppenädala lõppu. Kõik muud liikumised rühmade sees ja vahel on lubatud kuni semestri lõpuni. ## Küsimus: Tahan teha projekti PostgreSQL või Oracle andmebaasisüsteemis. Mida tuleb selleks teha? **Vastus:** Saamaks juurdepääsu apex2.taltech.ee/apex.ttu.ee serveritele, kus on PostgreSQL/Oracle, täitke palun esimene punkt "Andmebaasid II" kodulehel (kasutajanimi: SIS2, parool: SIS2) olevast ülesandest 1. Loodavad kontod on individuaalsed, st kui teete iseseisvat tööd rühmatööna, siis iga rühma liige peab küsima eraldi juurdepääsu. Oma kasutajanime ja parooli kellelegi edasi anda ei ole lubatud. Kas ja kuidas pääseb väljastpoolt ülikooli ligi õppeserveris olevale PostgreSQL andmebaasisüsteemile kirjutatakse SIIN.PostgreSQL/Oracle kasutamise juhiseid leiate (kasutajanimi: SIS2, parool: SIS2) SIIT ja SIIT.Ülikooli serverite kasutamise lisandväärtus projekti tegemiseks on, et seal saab kasutada andmebaasi disaini automaatkontrolli vahendeid (need leiavad ka tõsist kasutust "Andmebaasid II" õppeaines).SQL ülesannete harjutamiseks saab kasutada ka keskkondi DBFiddle (toetab uuemaid PostgreSQL versioone) ja SQLFiddle. Seal on võimalik käivitada SQL tabelite loomise lauseid ning nende tabelite põhjal käivitada andmete otsimise ja muutmise lauseid. Niimoodi saate testida, kas Teie lause läheb tööle ja annab õige tulemuse. **Märksõnad:** Postgres, apex, apex2 ## Küsimus: Töövihiku järgi tehtava projekti teema on "Ürituste korraldamise ettevõtte peoruumide funktsionaalne allsüsteem"? Kas peame kõigepealt kavandama ja siis ka realiseerima broneeringute registri ja lisateenuste registri? **Vastus:** Kui ei taha, siis ei pea!Töö dokumendi osa võib tinglikult jagada kaheks. Süsteemi üldvaade - jaotis 1.1 - kus kirjeldatakse organisatsiooni (antud juhul peoruumide pakkuja)  infosüsteemi kui tervikut, sh seda, et vaja on hallata infot broneeringute, lisateenuste, lisateenuse tellimuste jne kohta. Detailne projekt - alates jaotisest 1.2 kuni dokumendi lõpuni - kus keskendutakse selle suure süsteemi ühele alamosale. Selleks alamosaks on antud juhul peoruumide funktsionaalne allsüsteem ning andmebaasi poole pealt registrid e andmebaasi alamosad, mis sisaldavad andmeid, mida on vaja peoruumide haldusega seotud funktsionaalsuse toetamiseks. Teiste sõnadega, sellistest registritest on vaja kas andmeid lugeda või on seal vaja andmeid muuta.    Teil oleks vaja teha andmebaasis tabelid nagu "Lisateenus", "Lisateenuse_tellimus", "Broneering" jne ainult sellisel juhul, kui jaotises "1.2.4 Allsüsteemi funktsionaalsed nõuded" sisalduks mõni kasutusjuht e kasutusmall, mille täitmiseks peab neid andmeid lugema. Rõhutan, et sellesse alajaotusesse pole töövihiku projekti korral vaja ühtegi kasutusjuhtu lisada. Näiteks kasutusjuht "Esita broneering" oleks "Broneeringute funktsionaalse allsüsteemi" kasutusjuht ning kasutusjuht "Telli lisateenus" oleks lisateenuste tellimuste funktsionaalse allsüsteemi kasutusjuht.    See on Teie enda otsustada, kas tahaksite näiteks, et kasutusjuhu "Vaata kõiki peoruume" läbija peaks nägema ka peoruumiga seotud detailseid broneeringuid või peoruumiga seotud aktiivsete broneeringute arvu.   Kui otsustate, et selliseid andmeid peaks selle kasutusjuhu kontekstis nägema, siis: tuleks täiendada vastava kasutusjuhu kirjeldust, funktsionaalne allsüsteem loeks broneeringute registrit, st tuleks täiendada ka jaotist "1.2.2 Seosed pädevusalade ja registritega", kontseptuaalne andmemudel ning selle alusel loodud andmebaasi disaini mudel ja realiseeritud andmebaas peaksid hõlmama ka broneeringute registrit.   Kui otsustate, et selliseid andmeid ei peaks nägema, siis eelnevalt kirjeldatud tegevusi ei ole vaja teha. See, kas peaks või ei peaks selliseid andmeid nägema, on projekti tegijate otsus, st seda pole ette kirjeldatud. --- # Teema: Korraldus - SQL kontrolltöö ## Küsimus: Kas ka siis peab SQL järeltööle registreeruma, kui olen põhitöö eest saanud vähemalt 50 punkti ja olen tulemusega rahul? **Vastus:** Siis palun ärge registreeruge! Kui olete juba registreerunud, siis palun kustutage oma registreerimine. **Märksõnad:** järeltöö ## Küsimus: Kas oleks võimalik saada iseseisvaks harjutamiseks mõeldud SQL ülesandeid? **Vastus:** Kõigepealt on palju selliseid ülesandeid SQL Lahendaja keskkonnas. Mõned ülesanded on seal sellised, mis annavad punkte SQL põhitööle, kuid paljud on lihtsalt harjutamiseks ning enese proovile panemiseks. Seal keskkonnas ülesande valesti lahendamine ei anna ei SQL põhitööl ega mingil muul viisil siin aines miinuspunkte - seega võite julgelt katsetada ja eksida.Ülesanded on lisamaterjalide lehe (kasutajanimi: SIS2, parool: SIS2) kataloogis AB 1 SQL praktika. Seal on neid palju ning igale maitsele.  Selle kataloogi alamkataloogis SQLi nuputamine on keerukamad ülesanded. Selle kataloogi alamkataloogis Lahendused on ülesannete (sageli kommenteeritud) vastused.Mõned (kuid kaugeltki mitte kõik) nendest ülesannetest on ka SQL Lahendaja keskkonnas. **Märksõnad:** lisaülesanne, lisaülesanded, ülesanne, harjutusülesanne, harjutusülesanded ## Küsimus: Kui kirjutan järeltööd 15. nädalal ja see ei õnnestu mul, kas tohib peale seda teha järeltööd sessiooniajal? **Vastus:** Jah, tohite küll. Sessiooni ajal on veel kaks järeltöö tegemise võimalust (üks sessiooni alguse- ja teine lõpuosas). ## Küsimus: Kui kirjutan SQL järeltööd esimest korda mingil muul ajal kui 15. õppenädalal, siis kas on lubatud kasutada kahte A4 lehekülge abimaterjali? **Vastus:** Jah on! Pidage silmas, et kahe A4 lehekülje mahus SQL abimaterjali koostamine on osa järeltööst. See abimaterjal tuleb esitada koos järeltöö vastusega. Kui  sellist faili ei ole,  õppejõu hinnangul pole see ise koostatud (see on koopia mingist valmismaterjalist), see on samasugune kui mõnel teisel üliõpilasel, siis saab järeltöö -10 punkti. ## Küsimus: Tahaksin küsida. Kui sel semestril projekt ei jõua teha aga SQL kontrolltöö on tehtud, nagu mina sain aru, et projekt on vaja järgmisel kevadel uuesti teha aga mis saab siis kontroltöö tulemusest? Kas kontrolltöö on vaja ka uuesti teha? **Vastus:** Projekti arvestus kehtib ka uuesti deklareerides. Hindamisel kasutatav projekti punktisumma määratakse kindlaks vastavalt jooksval semestril kehtivatele reeglitele. Kõik muud punktid (sh SQL kontrolltöö punktid) kehtivad ainult saamise semestril. Deklaratsioon kehtib ühe semestri. ## Küsimus: Tahan kirjutada järeltööd 15. nädalal. Kas selle saab kirjutada mitte oma grupi praktikumi ajal? **Vastus:** Jah. 15. nädalal toimuvadki järeltööd kahel ajal - neljapäeval ja reedel kell 15:45. --- # Teema: Korraldus - üldine ## Küsimus: Kas eksamit saab teha enne eksamisessiooni algust? **Vastus:** Kui väga vaja, siis kokkuleppel õppejõuga saab. Eksamieeldused peavad olema eelnevalt täidetud. Kui mõtlete, et see on vajalik selleks, et eksamisessiooni ajal oma lõputööd kaitsta, siis ärge muretsege - lõputööde kaitsmine toimub eksamisessiooni teises pooles ning tehes eduka eksami eksamisessiooni esimesel nädalal jõuate ilusti kaitsmisele. **Märksõnad:** eksam, eksamisessioon ## Küsimus: Kas eksamit saab teha enne, kui kõik eksamieeldused on täidetud? **Vastus:** Ei saa. Eksami tegemiseks peavad olema täidetud kõik eksamieeldused: SQL kontrolltöö tulemus on vähemalt 50 punkti, projekt on arvestatud. ## Küsimus: Kas erinevatel nädalatel võib käia erinevates praktikumides? **Vastus:** Jah, erandkorras ning kokkuleppel õppejõuga saab. Sisu poolest on kõik praktikumid ühesugused. Palun Teid väga osaleda võimalusel Teie tunniplaanijärgses tunnis, et üliõpilased oleksid praktikumide vahel ühtlaselt jaotatud ja et ei tekiks olukorda, kus mõnes tunnis on palju rahvast ja teises vähe. Mida rohkem on tunnis osalejaid, seda vähem jääb õppejõul iga osaleja jaoks aega. Mis puudutab üliõpilasi, kellel ei ole seda ainet tunniplaanis (nt Avatud Ülikooli õppurid), siis elu näitab, et lõpptulemusena võib olla mõnes praktikumis hästi palju osalejaid ja õppejõul jagub sedavõrra osalistele vähem aega aga mõnes teises praktikumis (eriti reedeti) on aga väga vähe osalejaid ja samavõrra on õppejõul igale osaleja jaoks rohkem aega. Seega tasub alates teises õppenädalast õppejõult uurida, millised on ajad, kus tunnis käijaid on vähe ning käia selles tunnis - et õppimine läheks võimalikult libedalt ja ainest oleks võimalikult palju kasu. ## Küsimus: Kas praktikume on võimalik teha ka arvutiklassi arvutites? **Vastus:** Jah, on küll võimalik. Enamik arvutiklasse on nüüd tehtud sellisteks, et pooltel töökohtadel on arvuti täiskomplekt, pooltel kohtadel aga ainult kuvar ja võrgukaabel (et soovi korral ühendada oma sülearvuti). Arvutiklassi arvutites on kogu vajalik tarkvara olemas. Arvutiklassi ustel on info kuidas saab klassi kasutada kui seal parajasti tundi sees ei ole. ## Küsimus: Kas tehes eksamit eksamisessiooni viimasel eksami tegemise ajal on veel võimalik seda parandada? **Vastus:** Kui teete eksamit eksamisessiooni viimasel päeval, siis saate vajadusel ikkagi teha eksamit 2+1 korda (kui teete põhieksamit) või 1+1 korda (kui teete lisaeksamit). Kuid kõik need eksami tegemised toimuvad samal päeval ja samas kohas, üksteise järgi (olen selleks aeg varunud). ## Küsimus: Kuidas arvestatakse teooria vahetestide punkte? **Vastus:** Aines saab erinevat tüüpi ülesannete lahendamisega koguda punkte. Punktid liidetakse kokku ja taandatakse hindamisskaalale, et saada hinne. Positiivse lõpphinde saamiseks tuleb ületada ka lävendid e täita teatavad lisatingimused. Teiste sõnadega ei piisa positiivse lõpphinde saamiseks ainult teatud hulga punktide kogumisest, vaid tuleb täita ka KÕIK lävendi tingimused.Lävendi tingimused: SQL kontrolltöö eest on saadud vähemalt 50 punkti. Projekt on arvestatud (ja seega saadud projekti eest ka punktid). Teooria eest on saadud vähemalt 50 punkti. Mis puudutab teooriat, siis välja jagatakse 130 punkti. Auditoorse õppetöö perioodil toimub kolm vahetesti, millest igaüks annab kuni 10 punkti. Eksamisessiooni ajal toimub lõpptest, mis annab kuni 100 punkti. Seega lävendi ületamiseks tuleb nende nelja testiga saada kokku vähemalt 50 punkti. **Märksõnad:** punkt, punktid, test, testid, teooria, eksam ## Küsimus: Kuidas kujuneb hinne? Milline mõju on SQL kontrolltööl, teooria testidel ja projektil? **Vastus:** Üks koht, kust seda kiiresti vaadata on aine korralduse kirjelduses. Hindamise põhimõtted on rasvase ja suure fondiga esile tõstetud. ## Küsimus: Kuidas peaks üliõpilane toimima, kui ta on haige? **Vastus:** Kui olete haige või haiguskahtlusega, siis ärge palun füüsiliselt klassi kohale tulge - õppetööd saab suures osas teha ka distantsilt. Kui toimumas on teadmiste kontroll, kus füüsiline kohalolu klassis on nõutud, siis võtke palun õppejõuga ühendust. **Märksõnad:** covid, haige, haigus, gripp, covid-19, nakkus ## Küsimus: Kuidas saada juurdepääs O'Reilly digitaalsele platvormile? **Vastus:** Juhend on SIIN. **Märksõnad:** oreilly ## Küsimus: Kuidas toimub valikvastustega teooria vahetestide tegemine? **Vastus:** Selliseid teste toimub kolm tükki. Neljanda õppenädalal test, mis annab kuni 10 teooria punkti. Kaheksandal õppenädalal test, mis annab kuni 10 teooria punkti. 12. õppenädalal test, mis annab kuni 10 teooria punkti Testi tegemine ei toimu praktikumis, vaid etteantud perioodi jooksul veebipõhiselt iseseisvalt. Punktide saamiseks tuleb etteantud ajaperioodi jooksul teha testi vähemalt etteantud arv kordi. Info täpse perioodi kohta saadetakse õppeaine kodulehe kaudu. Testi tegemine tähendab vastuste salvestamist. Teste võib teha ka ettenähtud miinimumarvust rohkem kordi. Tulemus arvutatakse tehtud testide keskmisena. Teste tuleb teha iseseisvalt, ilma abimaterjalid ning kõrvalise abi (sh teised inimesed või tehisintellekti vahendid) kasutamiseta.Testi tegemise perioodil on test tegemiseks avaldatud SIIN.Enne kõiki neid perioode on võimalik sellisel viisil tehtavateks testideks harjutada SIIN.Testi tegemisel peate väga täpselt jälgima, et Te ei ületataks testi tegemiseks ettenähtud aega, sest aja ületamisel vastuse salvestamine ebaõnnestub. Kuigi testi tegemise aknas on näha kell, siis see võib olla ebatäpne. Seega on ülioluline, et võtaksite testi tegemisel ise stopperiga aega. Kui kuritarvitate süsteemi, et selle abil küsimusi välja pumbata või saada meelepärasemaid küsimusi või ületate vastamiseks ettenähtud aega, siis automaatselt ja ilma eelhoiatuseta suletakse jäädavalt Teie juurdepääs sellele testile (sellisel viisil punktide/hinde saamine pole kohustus, vaid võimalus). Kuritarvituste näiteid: skripti kasutamine vastamiseks, küsimustiku genereerimine ilma vastuste salvestamiseta, küsimustiku genereerimine ja vastusteta salvestamine, vastamiseks ettenähtud aja ületamine, läbiklõpsutades liiga kiiresti vastamine. Teilt oodatakse, et need küsimused, mille süsteemilt saate, nendele ka vastate ja mõtlete sealjuures, mitte lihtsalt ei klõpsi. Panen Teile väga südamele, et Te kõigi nende nõuetega arvestaksite! **Märksõnad:** valikvastustega test, punktid, vahetest, vahetestid ## Küsimus: Kuidas valmistuda õppeaines toimuvateks testideks (vahetestid ja lõpptest)? **Vastus:** Kordamisküsimused leiab SELLEST DOKUMENDIST (kataloog Teooria). Testide tegemine toimub veebipõhise keskkonna kaudu, kuhu Teie konto luuakse õppejõu poolt peale seda, kui olete Mauruses õppeaine kodulehel registreerinud. NB! Süsteemis on olemas testideks harjutamise funktsionaalsus. Harjutamiseks minge lehele https://maurus.ttu.ee/testimine/valik_harjuta.php. Õppeaines toimub auditoorse õppetöö perioodil kolm vabatahtliku teooria vahetesti ning kohustuslik lõpptest (eksam) eksamisessiooni ajal. Kõikide nende jaoks saab selles keskkonnas harjutada. Kõikides vahetestides esitatavad küsimused võivad tulla ka lõpptesti. Millal on mingi test harjutamiseks avatud on kirjas õppeaine kodulehe ajakavas ning perioodi algusest teavitatakse ka eraldi meili teel. Järgnevalt loetlen harjutuskeskkonna mõned olulised põhimõtted. Sisselogimiseks on Mauruse kasutajanimi ja parool. Harjutamiseks võib olla avatud rohkem kui üks test - pöörake palun tähelepanu, mida valite. Testi omadused (vastamiseks ettenähtud aeg; küsimuste arv; küsimuste hulk, millest testiküsimused valitakse; küsimuste valiku põhimõtted) on samasugused nagu vastaval hinnataval testil. Iga testi tegemisel genereerib süsteem uue küsimustiku. Tehtavate testide arv ei ole piiratud. Süsteemi kuritarvitamisel, et selle abil küsimusi välja pumbata (skripti kasutamine vastamiseks; küsimustiku korduv genereerimine ilma vastamiseta), blokeeritakse vastaja juurdepääs sellele testile ilma eelhoiatuseta ning jäädavalt. Iga valitava testi juures on näha ajahetk, milleni on test harjutamiseks valitud. Tulemused salvestatakse ja õppejõud näeb tulemusi. Salvestamise järel näeb vastaja õigete vastuste arvu, hinnangut vastustele ja iga küsimuse korral ka seda, kas küsimusele vastati õigesti või valesti. Iga testi puhul on määratud, kui mitmel korral päevas näeb vastaja, juhul kui ta vastas küsimusele valesti (kuid ei jätnud vastamata), ka õiget vastust. Teste võib muidugi päevas teha rohkem kui on kordi, millal näeb õigeid vastuseid. Õigeid/valesid vastuseid näeb ainult salvestamise järel, kuid mitte hiljem. Harjutamise testide tulemusi näeb hiljem ka siit. Tulemusi ei võeta õppeaine hindamisel MITTE MINGIL VIISIL arvesse (st võite julgelt harjutada ja ka eksida). ## Küsimus: Milline on ebaväärikas käitumine antud aine kontekstis? **Vastus:** Infotehnoloogia teaduskonnas kehtib õppuri akadeemiliste tavade rikkumise ja ebaväärika käitumise menetlemise kord (dokument 09). Selles dokumendis määratakse ära, milliseid õppuri poolseid tegevusi loetakse akadeemiliselt väärituks käitumiseks ning millised on tegevused ja võimalikud ametlikud tagajärjed õppuri jaoks (noomitus, eksmatrikuleerimine) kui ta millegi sellisega hakkama saab. Palun Teilt järgnevat. Palun ärge jagage enda tehtud projekte teiste üliõpilastega. Palun ärge tehke kellegi teise eest tema tööd ära. Palun ärge taluge projekti rühmas liikmeid, kes teistega võrdselt töösse ei panusta. Sellega teete tegelikult neile palju halba, sest nad ei õpi midagi!!! Veel enam, Te teete kahju endale, sest teadmisteta/oskusteta lõpetajad kahjustavad tööandjate silmis kõigi diplomisaajate mainet. Kui mõni projekti kaaslane ei panusta piisavalt, siis arvake ta palun oma projektist välja ja teavitage sellest (nt õppekeskkonna kaudu) õppejõudu.Tehisintellekti vahendite kasutamine teadmiste kontrollides ei ole lubatud, kui selleks ei ole just eraldi luba antud. "Teeseldud meetodite ja valeandmetega või ebaeetiliselt/ebaausalt kogutud andmetega opereerimine on akadeemiline petturlus. Akadeemiline petturlus on ka igasuguse eelisolukorra loomine, mis ei ole kehtestatud reeglitega põhistatud, samuti valeandmete esitamine – tulemuste hindamise protsessis, rahastuse või positsiooni taotlemisel nii enda kui teiste suhtes. Siia alla kuulub ka hindajale teadmata abivahendite või keelatud andmete kasutamine;" (Birgi Lorenz) **Märksõnad:** OpenAI, ChatGPT, LLM, suur keelemudel, tehisintellekt, AI, TI ## Küsimus: Millised oleksid põhilised soovitused selle aine edukaks sooritamiseks? **Vastus:** Valige hinne, mida soovite, sellele vastav punktisumma, tehke kindlaks erinevad võimalikud teed kuidas selle punktisummani jõuda ning hakake esimesest päevast selle saavutamise suunas süstemaatiliselt tegutsema Tehke ainega iga nädal iseseisvat tööd Määrake näiteks kindel nädalapäev ja kellaaeg millal uurite materjale, lahendate SQL ülesandeid ja tegelete projektiga Ärge jätke SQL põhitöö või teooria vahetestide tegemist viimasele minutile Võib juhtuda, et tegemiseks ei jää piisavalt aega ning kaotate sellega punkte Mistahes tehnilised probleemid võivad plaanid sassi lüüa Võtke aega, et mõelda läbi, mis viisil, mis teemal, mis vahendeid kasutades ja kellega koos Te projekti teete Halvad valikud võivad maksma minna nii töörõõmu kui ka palju punkte Alustage projekti varakult ja lõpetage varakult Käige nädalatel 3.-12. praktikumis füüsiliselt kohal ja tehke projekti. Kohe võimalus küsida Nädalas on kindel aeg, millal projektiga tegeleda Aktiivsuspunkti saamiseks ei pea eraldi lühiaruannet kirjutama Kui jääte projektiga jänni, siis küsige kohe õppejõult Kõige operatiivsem Teamsi vestlus Kasutage kõiki pakutud võimalusi punktide kogumiseks - siin aines on neid palju See sunnib iganädalaselt ainega tegelema ja ka premeerib iganädalast ainega tegelemist Kasutage testideks harjutamise võimalust Harjutustestid on samade omadustega ja samade küsimuste põhjal kui tulemustele tehtavad testid Jälgige aine kohta e-posti aadressile tulevaid teateid Kasutage Mauruses seda aadressi, mida järjepidevalt jälgite Tehke kirjakastis reegel, mis suunab kõik Mauruselt tulevad kirjad eraldi kataloogi Võtke semestri alguses veidi aega, et vaadelda erinevaid kodulehe versioone ja valida sealt endale sobivaim Viite sellele saab järjehoidjasse panna ning ülejäänud saab soovi korral unustada Erinevad versioonid: Moodle Materjalid nädalate kaupa Algne koduleht Kohustuslikud materjalid (pole küll eraldi koduleht, aga võibolla mõni ei tahagi rohkem materjale näha) Logige oma tööaega. Kui ainega tegelemine jääb unarusse, siis tuleb see aruande jooksvast seisust kohe välja ja võiks motiveerida aine uuesti käsile võtta Annab punkte Aina rohkem üliõpilasi teeb lõputöö rühmatööna ja seal on iga rühma liikme individuaalselt kulutatud aja aruanne lausa nõutud Tehke aine kohta Google NotebookLM märkmik, kuhu saate üles laadida kõik aine materjalid ja mis pakub Teile sisuliselt ainepõhise juturoboti, mis võimaldab üle aine materjalide küsimusi esitada ja kokkuvõtteid genereerida. SEE on vaid üks paljudest headest videotest selle vahendi kohta. ## Küsimus: Millised on õppejõu lubadused Teile ja ootused Teie suhtes seoses õppeainega "Andmebaasid I"? **Vastus:** Luban, et: Vastan kiiresti Teie küsimustele. Olen küsimustele vastamiseks praktikumide ajal kättesaadav. Pingutan südamest, et leida Teie aine õppetööga seotud muredele ja probleemidele lahendus. Peaaegu kogu kursuse saab läbida virtuaalselt (vaid lõpptesti tegemiseks peab kindlasti klassi kohale tulema). Küsin tagasisidet ning arvestan sellega. Te saate iseseisva töö projekti näitamiseks valida konkreetse kuupäeva ja kellaaja ning üritan võimalikult hästi ajakavast kinni hoida. Annan kirjalikele töödele (sissejuhatav ülesanne, SQL järeltöö) vastuse hiljemalt nädal peale esitamist. Kui peaks juhtuma, et ma ei suuda seda lubadust pidada, siis teavitan sellest koheselt. Ootan Teilt, et: Küsite julgelt abi kui tekib mõni raskus või mure. Annate koheselt teada tehnilistest probleemidest seoses õppeaines kasutatavate ressurssidega. Annate koheselt teada, kui leiate vea SQL Lahendaja poolt tehtavas kontrollis. Tegelete õppeaine õppimisega igal semestri auditoorse õppetöö perioodi nädalalal. Regulaarne töö aitab õigeks ajaks valmis saada ning kinnistab õpitut. Kui Te ei saa mõnele teadmiste kontrollile tulla, siis annate sellest koheselt teada. Kui olete haiguskahtlusega või haige, siis hoiate ennast ja teisi ning ei tule klassi füüsiliselt kohale, vaid võimalusel osalete tunnis virtuaalselt või siis teete vajalikke töid hiljem järgi. Osalete aktiivselt praktikumides. Isegi kui ei käi loengutes kohal, siis vaatate loengut otseülekandes või järelvaatamise korras. Tutvute vähemalt materjalidega, mis on kodulehel märgitud kohustuslikuks. Teete iseseisvaks lahendamiseks mõeldud ülesandeid iseseisvalt. Vigadest saate Te õppida, aga plagiaat on tõsine eksimus ülikooli kõige olulisemate reeglite vastu ning ei aita Teid kuidagi edasi. Kasutate tehisintellekti vahendeid vaid nende hinnet mõjutavate ülesannete lahendamisel, kus see on lubatud. Kui teete projekti rühmatööna, siis panustate projekti võrdväärselt teiste rühmaliikmetega. Pingutate, et saada projekt varakult ning kvaliteetselt valmis.  Kui olete registreerunud projekti näitamisele, kuid ei saa tulla, siis kustutate oma registreerimise võimalikult varakult. Annate konstruktiivset tagasisidet, et kursus muutuks paremaks. Ei saada õppejõule e-kirjadega faile. Failid tuleb laadida SIIA või kokkuleppel õppejõuga kopeerida Teamsi vestlusesse. Kasutate õppeaine servereid vaid õppetööks, ei sega teisi kasutajaid ning Teil on kõigest enda poolt serverile pandust koopia.   **Märksõnad:** lubadused, soovid leping ## Küsimus: Millised piirangud on antud aines materjalide, tehisintellekti (TI) vahendite ja teiste inimeste abi kasutamisele teadmiste kontrollides? **Vastus:** Teiste inimeste abi võib kasutada ainult iseseisvas töös (kui teete rühmatööna). Sissejuhatav ülesanne, SQL põhitöö Lahendamisel võib kasutada mistahes materjale. TI vahenditelt (nt ChatGPT) võib paluda abi SQLi selgitamisel, kuid keelatud on küsida ülesande lahendust. SQL järeltöö Võib kasutada kahe A4 lk formaadis abimaterjali.  Iseseisev koostamine on osa järeltööst, tuleb esitada koos töö lahendusega. Muud abimaterjalid ja TI pole lubatud. Iseseisev töö Kõik materjalid ja TI kasutus on lubatud ning soositud. Iseseisva töö jaoks on kodulehel testid, mille abil saab töö osi suurte keelemudelite abil testida. TI kasutus tuleb esitatavas dokumendis välja tuua. Tulemuse õigsuse eest vastutavad autorid! Teooria Testid on materjalide ja TI vahendite kasutamiseta. SELLES YouTube videos on häid mõtteid, kuidas TI vahendeid õppetöös kasutada nii, et see soodustab õppimist, mitte ei pärsi seda. Näiteks saab generatiivset tehisintellekti kasutada aktiivse vestluspartnerina, kes esitab küsimusi ning kommenteerib vastuseid. Generatiivne tehisintellekt on nagu lõputu hulk erinevaid isiksusi ning küsimuse esitaja saab paluda vestluspartnerit panna sobivasse rolli.You said:Palun kujuta ennast ülikooli õppejõuna, kes peab seletama andmebaaside teooriat algajale. Palun esita mulle viis küsimust SQL välisvõtmete kohta ja kommenteeri, mis on minu vastuses valesti või õigesti. ChatGPT said:Siin on viis SQL välisvõtmetega seotud küsimust:   Mis on SQL-is välisvõti (FOREIGN KEY) ja milleks seda kasutatakse? Kuidas saab luua välisvõtme seose kahe tabeli vahel? Too SQL-i näide. Mis juhtub, kui proovime kustutada tabelist rea, millele viitab välisvõti teises tabelis? Mis vahe on ON DELETE CASCADE, ON DELETE SET NULL ja ON DELETE RESTRICT? Kas välisvõti võib viidata veerule, mis ei ole primaarvõti teises tabelis? Kui vastad nendele küsimustele, siis ma kommenteerin, mis on õigesti ja mida saaks parandada.   You said: SQLi välisvõti on veergude hulk, kuhu kuulub üks või mitu veergu, milles olevad andmed loovad seoseit teiste ridadega (samas või erinevas tabelis). ChatGPT said: Su vastus on üsna lähedal, kuid seda saaks täpsemaks ja selgemaks teha. Siin on mõned parandused ja kommentaarid:   Õigesti:   Välisvõti võib koosneda ühest või mitmest veerust. See loob seoseid teiste ridadega kas samas tabelis (eneseviitamine) või erinevas tabelis.   Parandamist vajav:   "Seoseit" peaks olema "seoseid". Selgitus võiks täpsustada, et välisvõti viitab tavaliselt primaarvõtmele või unikaalsele võtmele teises tabelis.   Parandatud versioon: "SQL-is on välisvõti (FOREIGN KEY) üks või mitu veergu, mis viitavad teise tabeli primaarvõtmele või unikaalsele võtmele. See aitab tagada andmete terviklikkuse, luues seoseid tabelite vahel."   Kas soovid järgmise küsimuse juurde liikuda?Veel üks kasulik võimalus on anda keelemudelile ette dokument ja paluda endale sellest kokkuvõte teha.Prompti näide: Palun pane ennast üliõpilase rolli, kes peab kaasüliõpilasele midagi seletama. Palun tee sellest failist lühikokkuvõte ja too välja kõige olulisem.Töötab hästi näiteks Google Gemini 2.5 Pro põhjal, kuhu tuleb ette anda pdf fail. ChatGPT 4 ei suutnud samas etteantud pdf faili lugeda ja ajas lihtsalt jama. **Märksõnad:** OpenAI, ChatGPT, LLM, suur keelemudel, tehisintellekt, AI, TI, prompt, viip ## Küsimus: Millises järjekorras ja millisel viisil soovitate aine õppimist alustada? Millele kõigepealt tähelepanu pöörata? **Vastus:** Soovitan alustada sellest, et jälgite pealehele ilmuvaid kuupäevi ja üritate täita nendega seotud ülesanded. Pealehel näidatakse lähenevaid tähtaegu. Kõiki kuupäevi saab vaadata aine tutvustuse alt. Kuluva aja ja üliõpilaste tagasiside järgi vaadates on õppeaine kõige raskem osa iseseisava töö projekt. On väga oluline, et teeksite selle tegemiseks head valikud (üksi või kaaslastega; kui kaaslastega, siis kellega; mis viisil teha (töövihik vs. omalooming), mis teemal teha, mis vahendeid kasutada) ja kui tuleb välja, et need ei olnud ikkagi head valikud, siis korrigeeriksite neid kiiresti. See on nagu süsteemiarendusega - mida hiljem viga avastada, seda kulukam on seda parandada. Leidke palun aega, et ülesande püstitus korralikult läbi lugeda ja valida meeldiv ja jõukohane teema. Selle arvelt kokku hoitud viis minutit võib hiljem valusalt kätte maksta. Töö tegemist nõuab iseseisev töö igal juhul, aga mõni teema/tegemise viisi korral kindlasti rohkem kui mõne teise korral. Soovitan iseseisva töö kiireks ja edukaks sooritamiseks sellega iga nädal kasvõi natukenegi tegeleda. Selleks annab hea võimaluse see, et praktikumides toimub nädalatel 3-12 projekti tegemine. Loodetavasti annab motivatsiooni juurde võimalus saada nendel nädalatel projektiga vähemalt 90 minutit tegelemise eest aktiivsuspunkt.Kui teete projekti rühmas, siis kasutage palun maksimaalselt paralleeltöö võimalust, et sama ajaga rohkem tehtud saada. Selles mõttes pole üldse paha mõte (pole muidugi kohustuslik), et sama projekti tegijad osalevad erinevates praktikumides 3*3*1.5 tundi projekti tegemist on kindlasti parem kui 3*1.5 tundi projekti tegemist. Siis tuleb muidugi oma tunnitöö järgmisena tundi tulijale edasi anda. ## Küsimus: Millist tarkvara läheb õppeaines vaja ja võiks seega võimalusel oma Windows arvutisse installeerida? **Vastus:** Kui kasutate sissejuhatava ülesande lahendamiseks andmebaasisüsteemi MS Access, siis võiks see olla installeeritud hiljemalt teise õppenädala alguseks. Soovitan kasutada MS Accessi, kui plaanite seda kasutada ka projekti prototüübi osa tegemiseks. Kui kasutate sissejuhatava ülesande lahendamiseks PostgreSQLi, siis saate kasutada veebikeskkonda DB Fiddle, mida ise installeerima ei pea Soovitan kasutada PostgreSQLi, kui plaanite seda kasutada ka projekti prototüübi osa tegemiseks. Kui kasutate projekti tegemiseks andmebaasisüsteemina PostgreSQLi, siis graafilist kasutajaliidest pakkuv andmebaasiga töötamiseks mõeldud programm PgAdmin Programmeerijatele (sh SQL lausete kirjutajatele) mõeldud tekstiredaktor: Notepad++ või SciTe Võiks olla installeeritud hiljemalt teise õppenädala alguseks Notepad++ puhul on võimalus kasutada meie ülikooli üliõpilaste välja töötatud pistikprogrammi, mis võimaldab käivitada sinna kirjutatud SQL lauseid MS Access või PostgreSQL andmebaasis ning neid lauseid ka vigade suhtes kontrollida. Erinevalt DBeaverist või DBbSchemast saab selle kaudu MS Accessi andmebaasis käivitada ka CREATE, ALTER ja DROP lauseid. CASE vahend: Enterprise Architect või Rational Rose Võiks olla installeeritud hiljemalt kolmanda õppenädala alguseks Enterprise Architecti korral võiksite lisaks installeerida meie ülikooli üliõpilase poolt välja töötatud täiendatud mudeliteisenduse kontseptuaalsest andmemudelist esialgse SQL-andmebaasi disaini mudeli genereerimiseks Enterprise Architecti korral võiksite lisaks installeerida meie ülikooli üliõpilase poolt välja töötatud programmi, mis suudab klassidiagrammi tõlkida inimkeelseteks lauseteks Soovi korral universaalne (erinevate andmebaasisüsteemide jaoks mõeldud) graafilise kasutajaliidesega programm SQL lausete käivitamiseks ja andmebaasi struktuuri visualiseerimiseks: DBeaver (versioon 22.3.2 või hilisem) Alternatiivina sobib ka DbSchema Saab kasutada alternatiivse graafilise kasutajaliidesena PostgreSQL andmebaasi tegemiseks projekti jaoks Saab kasutada alternatiivse graafilise kasutajaliidesena MS Accessi andmebaasis andmete otsimise ja muutmise lausete koostamiseks ja käivitamiseks. Paraku ei saa ei DBeaveri ega DbSchema kaudu käivitada MS Accessi andmebaasis CREATE, ALTER ja DROP lauseid - seega projekti tegemisel sellest abi ei ole Kui kasutate MS Accessi, siis soovi korral MS Accessi andmebaasi kasutamiseks alternatiivset kasutajaliidest pakkuvad programmid nagu MDB Admin või MDB Viewe Plus. ## Küsimus: Mis andmebaasisüsteeme antud kursuse kasutada saab? **Vastus:** Sissejuhatavat ülesannet (teisel õppenädalal) saab teha kasutades  PostgreSQLi, MS Accessi. SQLi põhitööd saab teha kasutades PostgreSQLi.SQLi järeltööd saab teha kasutades: PostgreSQLi, MS Accessi, LibreOffice Base'i (kasutab HSQLDB v1.8). Iseseisva töö andmebaasi võib luua kasutades mistahes SQL-andmebaasisüsteemi (PostgreSQL, MySQL, MS SQL Server, MS Access, Oracle jne). --- # Teema: Küsimused seoses jätkuainega ("Andmebaasid II") ## Küsimus: Arvestades sellega, et "Andmebaasid II" aines tuleb seda projekti edasi teha, siis millised oleksid soovitused "Andmebaasid I" projekti jaoks andmebaasisüsteemi valimisel? **Vastus:** Jätkuaines "Andmebaasid II" peate Te valima ühe serveri andmebaasisüsteemi, mille põhjal oma projekti edasi teha. Süsteemid, mille hulgast valik teha, on rangelt ette antud - PostgreSQL ja Oracle (ei näe põhjust seda valikut lähitulevikus muuta, sest tegu on väga heade süsteemidega). Projektis tuleb valitud serveri andmebaasisüsteemi abil realiseerida andmebaas ning samuti realiseerida seda andmebaasi kasutav rakendus valitud allsüsteemi ühe töökoha piires. Rakenduse tegemise vahendi valik on vaba, kuid tulemust peab olema muidugi võimalik mulle demonstreerida. Eelnevast tulenevalt soovitan kevadise projekti tegemiseks kasutada kas: MS Access PostgreSQL Oracle Kui kasutate MS Accessi, siis on Teil võimalik sügisel töötada MS Accessis tehtud rakendus ümber nii, et see hakkab ODBC andmeühenduse tehnoloogia vahendusel kasutama PostgreSQL andmebaasi. Kui kasutate MS Accessi ja plaanite ka sügisel projekti rakenduse osa MS Accessis teha, siis valige kevadises projektis realiseerimiseks töökoht, mis võiks ka reaalses elus kasutada kahekihilist klient-server süsteemi, kus rakendus on kliendi arvutis. Seega ei sobi MS Accessis realiseerimiseks kõikvõimalikud "kliendi" töökohad, mis kindlasti peavad olema tehtud veebirakendusena. Kui teete oma kevadise projekti PostgreSQLis või Oracles, siis saate sügisel tehtud serveri andmebaasi edasi arendada. Kindlasti on sügisel disaini parandamisega omajagu tööd, kuid kevadel saadud kogemus võib tööd lihtsamaks muuta. Huvilistele saan juba kevadel anda juurdepääsu serveritele, kus on PostgreSQL (15) ja Oracle (12c Enterprise Edition, Release 1). Kuna seal serveris on andmebaaside disaini automaatkontrollimise vahendid, siis palun PostgreSQLis või Oracles tehtud "Andmebaasid I" projekti andmebaas sinna enne ettenäitamist üles panna. **Märksõnad:** Postgres, MSAccess ## Küsimus: Kas aines "Andmebaasid I" tehtava projekti rühm peab jääma samaks jätkuaine "Andmebaasid II" raames? **Vastus:** Ei pea. ## Küsimus: Kas sügisel saab teha "Andmebaasid II" õppeainet, kui "Andmebaasid I" jäi kevadel tegemata? **Vastus:** Võite sügisel deklareerida "Andmebaasid II", kui "Andmebaasid I" on tegemata. Muidugi hoiatan, et üks on teisele sisuline eeldus ja kui eeldusaine pole selgeks saanud, siis on jätkuaine kindlasti selle võrra raskem. "Andmebaasid II" õppeaines arendatakse edasi "Andmebaasid I" projekti. Pakun välja kolm "Andmebaasid I" projekti, mille hulgast saavad üliõpilased, kellel on eeldusaine tegemata, valida projekti, mida sügisel edasi arendada. Nii saavad üliõpilased "Andmebaasid II" projekti tegemisega kohe semestri alguses pihta hakata. Teine võimalus on, et liitute sügiseks mõne rühmaga, kus "Andmebaasid I" projekt on tehtud. Nii nagu kevadel on ka sügiseses projektis lubatud osalejate arv 1-3 üliõpilast. "Andmebaasid I" projekti sügisel kaitsta ei saa. Seda saab teha järgmisel kevadel. Siis saate ka teenida varase esitamisega seotud soodustuse (suurem punktsumma). Selles mõttes pole paha mõte sügisel "Andmebaasid I" projekt ikkagi ära teha, et siis kohe järgmise aasta veebruaris/märtsis see ette näidata. Te ei pea valima uut "Andmebaasid I" projekti teemat. Piirang millega tuleb arvestada "Andmebaasid II" projekti teema valimisel on, et eelnevalt kirjeldatud viisidel projekti tehes ei tohi "Andmebaasid I" ja "Andmebaasid II" projekti teemad kokku langeda. Sellel semestril kogutud punktid "Andmebaasid I" uuesti deklareerides arvesse ei lähe, kuid saate neid koos ülejäänud üliõpilastega järgmisel kevadel uuesti koguda. SQL kontrolltöö tuleb õppeainet uuesti deklareerides uuesti teha ning lävend ületada. Kui saite projekti kevadel tehtud, siis saate sellega sügisel jätkata. Õppeaine uuesti deklareerimisel ei ole vaja projekti uuesti teha. Projekti punktisumma leitakse uuesti deklareerimise semestril kehtivate reeglite kohaselt. ## Küsimus: Kui nt üks liige peab ajateenistuse tõttu aasta vahele jätma, kas siis seda projekti võivad erinevad rühma liikmed erinevatel aastatel edasi teha "Andmebaasid II" aine raames, st kaks liiget selle aasta sügisel ja kolmas liige eraldi üksi järgmise aasta sügisel? Kas selline olukord on üldse võimalik või tuleks siis "Andmebaasid I" projekt üksi teha? **Vastus:** Kõigepealt tuleb muidugi öelda, et me keegi ei tea täpselt ette, mis juhtub mitme aasta pärast ning elu võib igasugustes nõuetes ja plaanides teha korrektiive. Järgnev on minu käesoleva hetke vaade ning praegu pole mul plaani selles vaates muudatusi teha. Jätkuaines "Andmebaasid II" peate Te valima ühe serveri andmebaasisüsteemi, mille põhjal oma ("Andmebaasid I") projekti edasi teha. Süsteemid, mille hulgast valik teha, on rangelt ette antud - PostgreSQL ja Oracle (ei näe põhjust seda valikut lähitulevikus muuta, sest tegu on väga heade süsteemidega). Eeldusel, et lähteprojektis kasutati teist andmebaasisüsteemi, on sisuliselt tegemist süsteemi migreerimise projektiga ühelt platvormilt teisele koos koodi puhastamisega ja selleks vajaliku refaktoreerimisega. Ainus lisaks realiseerimist vajav funktsionaalsus on kasutaja tuvastamine. Projektis tuleb valitud serveri andmebaasisüsteemi abil realiseerida andmebaas ning samuti realiseerida seda andmebaasi kasutav rakendus valitud allsüsteemi ühe töökoha piires. Rakenduse tegemise vahendi valik on vaba, kuid tulemust peab olema muidugi võimalik mulle demonstreerida. Ka sügisese aine projekti saab teha 1-3 üliõpilast. Nagu kevadel, ei sõltu ka sügisese aine projekti maht/nõuded/tähtajad tegijate arvust. Millised oleksid Teie kaaslase valikud järgmise aasta sügisel, eeldusel, et teete "Andmebaasid I" projekti mitmekesi? 1. Kaaslane teeb edasi kevadel alustatud ja arvestuse saanud projekti, kuid kasutab sügisese projekti tegemiseks teist andmebaasisüsteemi kui Teie sügisel kasutasite. Toon näite. Oletame, et töö teemaks on "e-poe infosüsteemi kaupade arvestus". Sellel sügisel realiseerib üks grupp selle kasutades Oracle andmebaasisüsteemi. Järgmisel sügisel realiseerib teine grupp selle kasutades PostgreSQL andmebaasisüsteemi. Vahendite valikus võiks muidugi omavahel aegsasti kokku leppida. 2. Kaaslane leiab järgmisel sügisel projekti, millesse ta läheb teiseks või kolmandaks liikmeks. 3. Kaaslane valib projekti tegemiseks ühe selleks otstarbeks "Andmebaasid II" kodulehele välja pandud (mõnede teiste üliõpilaste tehtud) "Andmebaasid I" projekti. --- # Teema: Loengud ## Küsimus: Millele oleks eriti oluline andmebaaside õppimisel tähelepanu pöörata? **Vastus:** Kui maailmas on üldse midagi kindlat, siis see, et kõik on pidevas muutumises. Kui loote infosüsteemi ja selle andmebaasi, siis tuleb neid ajaga kaasaskäimiseks pidevalt kohandada. Hoolduskulud võivad lõpuks moodustada kuni 80% süsteemi kogukuludest. Selles kontekstis on väga oluline andmebaasi hallatavus. Artiklis: Riaz, M., Tempero, E., Sulayman, M., & Mendes, E. (2013). Maintainability Predictors For Relational Database-Driven Software Applications: Extended Results From A Survey. International Journal of Software Engineering and Knowledge Engineering, 23(04), 507-522. esitatakse 40 tarkvaraarenduse spetsialisti hulgas läbiviidud küsitluse tulemused. Selle küsitlusega sooviti teada saada, millised tegevused aitavad parandada SQL-andmebaasil põhinevate andmebaasirakenduste hallatavust. Vastusele lisatud failis tuuakse välja kõik sellised aspektid, millel on küsitlusele vastanute arvates mõõdukas või suur positiivne mõju hallatavusele. See fail esitab artiklis esitatud diagrammi. ## Küsimus: Mul ei õnnestu vaadata loengute lindistusi, sest saan videote vaatamisel veateate. ERROR:Unable to process language file located at: language/ru.xml The file is either missing or corrupt. **Vastus:** Ilmselt on probleem selles, et veebilehitseja on vene keelne. Lahendus oleks kasutada inglise keelset veebilehitseja. Ehk siis peaksite ära muutma keele sätted. GoogleChromes saaks korda kui võtta Настройка и управление Google Chrome Настройки ->Показать дополнительные настройки -> Языки ->Настройка языков и способов ввода ja võtate kasutusse inglise keele (англиский (США)). ## Küsimus: Mul on veidi vaba aega ja tahaks kuulata audio- või videoloenguid. Kas oskate soovitada midagi andmebaaside kohta? **Vastus:** Kursus andmebaasisüsteemide kohta Carnegie Mellon ülikoolis. "Andmebaasid I" kursuse temaatika alla lähevad esimesed viis loengut. https://www.youtube.com/playlist?list=PLSE8ODhjZXjYutVzTeAds8xUt1rcmyT7x 01 Course introduction & Relational Data Model (Fall 2017) - täiendus teemale 2 02 Relational Algebra (Fall 2017) - täiendus teemale 3 03 Advanced SQL (Fall 2017) - täiendus teemadele 4, 5 04 Functional Dependencies (Fall 2017) - täiendus teemale 9 05 Normal Forms (Fall 2017) - täiendus teemale 9 Carnegie Mellon ülikoolis on andmebaaside teadusgrupp. Nende Youtube lehel leidub päris palju loenguid tehnilisemate (edasijõudnute) teemade kohta. Osasid nendest teemadest käsitleb ka sügisene "Andmebaasid II" õppeaine. https://www.youtube.com/channel/UCHnBsf2rH-K7pn09rb3qvkA Relatsioonilised andmebaasid: https://www.youtube.com/watch?v=qx0F7TfA8CI https://www.youtube.com/watch?v=kSZX3fBgg1A&index=5&list=PLWIxuiyTh_yY3w26sJMbdTDXuEYJp-GxT (puuduvate andmetega toimetulek. SQLis on selleks üks väga veider omamoodi elukas NULL - sellest ka loengu nimi) Esimene on küll väga lühike video, kuid lektoriks mõlemal on C.J.Date, kellel minu arvates on väga hea selgitamisoskus. NoSQL süsteemid ja suurandmed: https://www.youtube.com/watch?v=qI_g07C_Q5I (hea kõrgtaseme ülevaade; lektorist) https://www.youtube.com/watch?v=S79-buNhdhI (lektorist) --- # Teema: SQL ## Küsimus: Järeltöö ülesandeks on teha koopia tabelist X (SELECT ... INTO lausega) ning seejärel koopias ridu muuta või ridu kustutada. Kas võin selle asemel kirjutada lause, mis loob koopia ridadega kus kajastub muudatuste järgne seis? **Vastus:** Sellise ülesande eesmärgiks on teha kindlaks, kas lisaks andmetest koopia tegemisele oskate koostada UPDATE või DELETE lauseid. Seega, järeltöö ülesande lahendamisel oleks see vale lahendus. Peaksite kirjutama vähemalt kaks eraldi lauset - üks koopia tegemiseks ja teine nõutud muudatuste tegemiseks. Samas, kui kahe lausega ei oska, siis tehke ühe lausega, sest punkte võib saada ka lahenduste eest, mis pole päris õiged. ## Küsimus: Kas CHECK kitsendustes saab kasutada mittedeterministlikke funktsioone? **Vastus:** Deterministlik funktsioon tagastab samade argumentidega  (sisendandmetega) alati samasuguse väärtuse. Mittedeterministlik funktsioon võib tagastada samade argumentidega erinevatel ajahetkedel erineva tulemuse. Mittedeterministlikud funktsioonid on näiteks CURRENT_DATE (tagastab hetke kuupäeva), CURRENT_TIMESTAMP (tagastab hetke kuupäeva ja kellaaja koos ajavööndiga) ja LOCALTIMESTAMP (tagastab hetke kuupäeva ja kellaaja ilma ajavööndita).CHECK kitsendus on kujul CHECK(loogikaavaldis). Iga tabelisse lisatava rea korral peab selle loogikaavaldise väärtuse arvutamise tulemus olema TRUE või UNKNOWN (kui reas mõnes väljas väärtus puudub e on NULL). SQL:2011 standardi kohaselt:   "Certain <boolean value expression>s are identified as “retrospectively deterministic”. A retrospectively deterministic <boolean value expression> has the property that if it is True at one point time, then it is True for all later points in time if re-evaluated for the identical SQL-data by an arbitrary user with the identical set of privileges.   No integrity constraint shall be defined using a <search condition> that is not retrospectively deterministic.   Without Feature F672, “Retrospective check constraints”, conforming SQL language shall not contain a <check constraint definition> that generally contains CURRENT_DATE, CURRENT_TIMESTAMP, or LOCALTIMESTAMP."Järgnevas tabeli loomise lauses: kitsendus chk_pakkumine_alguse_aeg on retrospektiivselt deterministlik Kui lisada tabelisse rida, mis lisamise hetkel vastas sellele kitsendusele, siis see rida vastab sellele kitsendusele ka tulevikus. kitsendus chk_pakkumine_lopu_aeg ei ole retrospektiivselt deterministlik Kui lisada tabelisse rida, mis lisamise hetkel vastas sellele kitsendusele, siis mingil hetkel tulevikus see rida enam sellele kitsendusele ei vasta. Nii tekib kahetsusväärne olukord, kus tabelis on andmed, mis ei ole kooskõlas tabelile defineeritud kitsendusega. CREATE TABLE Pakkumine ( pakkumine_id INTEGER NOT NULL, alguse_aeg DATE NOT NULL, lopu_aeg DATE NOT NULL, CONSTRAINT pk_pakkumine PRIMARY KEY (pakkumine_id), CONSTRAINT chk_pakkumine_alguse_aeg CHECK (alguse_aeg<=CURRENT_DATE), CONSTRAINT chk_pakkumine_lopu_aeg CHECK (lopu_aeg>=CURRENT_DATE));Eelnevalt viidatud SQL standardi lõik ütleb, et kitsendusi, mis pole retrospektiivselt deterministlikud, ei tohiks saada defineerida. Kui andmebaasisüsteem ei toeta omadust  F672, “Retrospective check constraints”, siis ei peaks CHECK kitsendustes saama üldse CURRENT_DATE, CURRENT_TIMESTAMP ja LOCALTIMESTAMP kitsendusi kasutada.Milline on tegelik olukord andmebaasisüsteemides? Kasutasin katsetamiseks keskkondi DB Fiddle, SQL Fiddle ja db<>fiddle.Andmebaasisüsteemid jagunesid kaheks: CHECK kitsendustes ei saa üldse CURRENT_DATE, CURRENT_TIMESTAMP ja LOCALTIMESTAMP funktsioone kasutada (sulgudes veateade eelneva CREATE TABLE lause käivitamisel). MySQL 9 (Query Error: An expression of a check constraint 'chk_pakkumine_alguse_aeg' contains disallowed function: curdate.) MariaDB 10.7 (ERROR 1901 (HY000) at line 1: Function or expression 'curdate()' cannot be used in the CHECK clause of `chk_pakkumine_alguse_aeg`) Oracle 23ai (ORA-02436: date or system variable wrongly specified in CHECK constraint) IBM DB2 Developer-C 11.1 (SQL0546N  The check constraint "CHK_PAKKUMINE_ALGUSE_AEG" is invalid.) CHECK kitsendustes saab kasutada CURRENT_DATE, CURRENT_TIMESTAMP ja LOCALTIMESTAMP funktsioone piiranguteta, st saab luua ka kitsendusi, mis ei ole retrospektiivselt deterministlikud. PostgreSQL 17 SQLite 3.46 MS SQL Server 2022 (CURRENT_DATE tuli asendada GETDATE()) MS Access 2019 (CURRENT_DATE tuli asendada DATE()) Firebird 4 HSQLDB 1.8 (LibreOffice Base) Süsteemides, mis lubavad kitsendusi, mis pole retrospektiivselt deterministlikud, tuleb olla kitsenduste defineerimisel ise tähelepanelik! ## Küsimus: Kas Count(1) ridade arvu loendamiseks on kiirem kui Count(*)? **Vastus:** Oletame, et SQL-andmebaasis on tabel:Isik(isikukood, perenimi)Primaarvõti (isikukood)LauseSELECT Count(*) AS arvFROM Isik;leiab tabelis Isik olevate ridade arvu. Kui Count funktsiooni poole pöörduda nii: Count(<avaldis>), siis leitakse selliste ridade arv, mille korral avaldise väärtus ei ole NULL.SELECT Count(1) AS arvFROM Isik;Ühegi rea korral tabelis Isik ei ole sulgudes oleva avaldise väärtuse arvutamise tulemus NULL - seega tulemus on sama nagu eelmisel päringul. Need kaks lauset on seega loogiliselt samaväärsed. Võiks arvata, et nende lausete täitmise protseduur (täitmisplaan) ja seega täitmise kiirus on ühesugused. Enamikes andmebaasisüsteemides see ongi nii. Kuid nagu kirjutatakse SIIN, siis PostgreSQLis on Count(*) kasutava päringu täitmine kiirem kui Count(1) kasutava päringu täitmine.Katsetasin seda PostgreSQL (16) andmebaasis tabeli (hcv) põhjal, kus on üks miljon rida. Kasutasin töökiiruse leidmiseks EXPLAIN ANALYZE lauset, mille käivitamise korral näeb kasutaja lause täitmise plaani ja ka lause täitmiseks kulunud aega. Käivitasin neid lauseid vaheldumisi viis korda ja leidsin kummagi lause korral täitmisaegade geomeetrilise keskmise.Lause 1: EXPLAIN ANALYZE SELECT Count(*) AS arv FROM Hcv;Lause 2: EXPLAIN ANALYZE SELECT Count(1) AS arv FROM Hcv;Count(*): geomeetriline keskmine 69.1 msCount(1): geomeetriline keskmine 76.1 msMinu katsetus seega kinnitas seda väidet, kuid töökiiruse erinevused on kasutajale vähemärgatavad. **Märksõnad:** kokkuvõttefunktsioon, jõudlus, töökiirus, PostgreSQL ## Küsimus: Kas erinevates andmebaasisüsteemides on tekstiotsing vaikimisi tõstutundlik või tõstutundetu? **Vastus:** SELECT * FROM Isik WHERE perenimi='Mets';Tõstutundetu (case insensitive) otsingu korral leitakse nii isik perenimega Mets kui ka isik perenimega mets.Tõstutundliku (case sensitive) otsingu korral leitakse isik perenimega Mets, kuid ei leita isikut perenimega mets.Kuidas käituvad erinevad andmebaasisüsteemid? Oracle Database 23ai Free - tõstutundlikMicrosoft SQL Server 2022 - tõstutundetuMySQL 8 - tõstutundetuPostgreSQL 16 - tõstutundlik SQL Lite 3.27.2 - tõstutundetuMariaDB 10.7.8 - tõstutundetuMS Access 2019 - tõstutundetu ## Küsimus: Kas korduste eemaldamine IN/NOT IN alampäringus muudab lause täitmise kiiremaks või mitte? **Vastus:** Sõltub andmebaasisüsteemist. Näiteks PostgreSQLis on sellel suur mõju, MySQLis ei ole mõju. PostgreSQLis aeglustab korduste eemaldamine alampäringus IN päringu täitmist kolm korda kuid muudab NOT IN päringu täitmise absurdselt palju kiiremaks.Toon näite. Olgu meil PostgreSQL andmebaas, millel on järgmine kontseptuaalne struktuur[Facility]-1-------------0..*-[Health_care_visit]Tabelis Facility on 50_000 rida.Tabelis Health_care_visit on 1_000_000 rida.Järgnevad katsetused on tehtud PostgreSQL (16) põhjal. Täitmisplaanide ja täitmise kiiruse vaatamiseks kasutasin EXPLAIN ANALYZE lauset. Rõhutan, et nende ülesannete juures pakutud lahendusvariandid on loogiliselt samaväärsed e annavad alati sama tulemuse. Kõik need on kokku näide "abstraktsioonide lekkimise" kohta e selle kohta, kuidas andmete füüsilise ("süsteemi kaane all") salvestamise ja töötlemise küsimused "lekivad" andmete kasutaja maailma ja kokkuvõttes peab ta teadma, kuidas oleks konkreetses süsteemis kõige otstarbekam oma küsimusi formuleerida.Ülesanne: Leia tervishoiuasutused, kuhu on tehtud vähemalt üks visiit.Lahendus 1: Lause täitmiseks kasutatakse tabeli Facility primaarvõtmele ja tabeli Health_care_visit välisvõtmele loodud indekseid. Lause täitmine võtab umbes 100ms. SELECT * FROM Facility  WHERE facility_id IN (SELECT facility_id FROM Health_Care_visit);Lahendus 2: Lause täitmiseks loetakse ainult tabelite andmeid (st indekseid ei kasutata). Lause täitmine võtab umbes 300 ms. SELECT * FROM Facility  WHERE facility_id IN (SELECT DISTINCT facility_id FROM Health_Care_visit);Lahendus 3: Sama, mis lahendus 2. SELECT * FROM Facility  WHERE facility_id IN (SELECT facility_id FROM Health_Care_visit GROUP BY facility_id);Ülesanne: Leia tervishoiuasutused, kuhu pole tehtud ühtegi visiiti.Lahendus 1: Iga rea kohta tabelist Facility materialiseeritakse e arvutatakse välja ja salvestatakse mällu indeksi põhjal täidetud alampäringu tulemus. Lause täitmine võtab umbes 31 minutit. SELECT *  FROM Facility  WHERE facility_id NOT IN (SELECT facility_id  FROM Health_care_visit  WHERE facility_id IS NOT NULL); Lahendus 2: Peaaegu sama plaan kui esimese lahenduse korral, ainult et alampäringu tulemust ei materialiseerita. Lause täitmine võtab umbes 125 ms. SELECT *  FROM Facility  WHERE facility_id NOT IN (SELECT DISTINCT facility_id  FROM Health_care_visit  WHERE facility_id IS NOT NULL); Lahendus 3: Sama, mis lahendus 2. SELECT *  FROM Facility  WHERE facility_id NOT IN (SELECT facility_id  FROM Health_care_visit  WHERE facility_id IS NOT NULL GROUP BY facility_id);Proovisin alampäringus korduste eemaldamise mõju ka MySQL (8) andmebaasis ja seal ei paistnud sellel lause täitmisplaani koostamisele ja lause täitmise kiirusele mõju olevat. ## Küsimus: Kas olemasse tabelisse T ridade lisamiseks võib MS Accessis kasutada SELECT ... INTO T FROM ... lauset? **Vastus:** Ei! See oleks ränk viga. SELECT ... INTO T … põhjustab MS Accessis tabeli T kustutamise ja uuesti loomise. Uues tabelis T on: kaotsi läinud kõik seal varem olnud andmed, tabeliga seotud kitsendused, tabeliga seotud indeksid. Loodud tabelis on andmetüübid ja maksimaalsed lubatud andmete suurused valitud vastavalt päringus viidatud tabelite andmetüüpidele ja väljapikkustele.Andmete lisamiseks tabelisse (olgu selles andmeid või mitte) tuleb kasutada INSERT lauset.NB! SQL standardis ja paljudes teistes SQL-andmebaasisüsteemides on sarnaseks koopia loomiseks kasutusel CREATE TABLE ... AS ... lause. Kui üritate sellega luua tabelit T ja tabel T on juba andmebaasis vastavas skeemis olemas, siis lause täitmine ebaõnnestub (mitte ei kirjutata tabelit üle nagu MS Access seda teeb). Sama juhtub ka siis kui kasutada SELECT ... INTO lauset MS SQL Server andmebaasisüsteemis. **Märksõnad:** MS Access, MSAccess ## Küsimus: Kas otsingutingimus x10 saab olla täidetud, st kas sellise otsingutingimusega päringu tulemuses saab olla ridu? **Vastus:** Ei saa.AND tähendab, et mõlemad alamtingimused peavad olema täidetud - vaadake AND operatsiooni tõeväärtustabelit. Oletame, et tabelis T on veerg x, mis on täisarvu tüüpi.Kui käivitada päring: SELECT * FROM TWHERE x<1 AND x>10; , siis päringu täitmisel toimuvad kontseptuaalselt järgmised toimingud. Iga rea korral tabelist T leitakse x väärtus, pannakse see tingimuses oleva x asemele, saadakse väide ja kontrollitakse selle väite täidetust e kehtivust. Kui kontrolli tulemus on TRUE e rida vastab tingimusele, siis see rida on päringu tulemuses. Kui kontrolli tulemus on FALSE või UNKNOWN, siis rida ei ole tulemuses. Neli näidet: x=5 - väide: 5<1 AND 5>10 - kumbki alamtingimus pole täidetud - vale väide e kontrolli tulemus on FALSE - rida pole tulemuses. x=0 - väide: 0<1 AND 0>10 - esimene alamtingimus on täidetud ja teine ei ole - vale väide e kontrolli tulemus on FALSE - rida pole tulemuses. x=20 - väide 20<1 AND 20>10 - teine alamtingimus on täidetud ja esimene ei ole - vale väide e kontrolli tulemus on FALSE - rida pole tulemuses. x on NULL - väide NULL<1 AND NULL>10 - kummagi alamtingimuse täidetust ei saa kontrollida, sest NULL on nagu kinnine karp, mille sisse ei näe - väide, mille täidetus ei saa kontrollida e kontrolli tulemus UNKNOWN - rida pole tulemuses. Selle päringu tulemuses ei ole ühtegi rida. ## Küsimus: Kas saate tuua näite sellest, kuidas ebaotstarbekas SQL ülesande lahendus mõjutab vastuse saamise kiirust? **Vastus:** Olgu meil PostgreSQL andmebaas järgmise kontseptuaalse struktuuriga:[Facility]-1---------------0...*-[Health_care_visit] Facility - 50_000 ridaHealth_care_visit - 1_000_000 rida.Järgnevad katsetused on tehtud PostgreSQL (16) põhjal. Täitmisplaanide ja täitmise kiiruse vaatamiseks kasutasin EXPLAIN ANALYZE lauset. Rõhutan, et nende ülesannete juures pakutud lahendusvariandid on loogiliselt samaväärsed e annavad alati sama tulemuse. Ülesanne - leia iga patsiendi kohta, kui mitmes protsendis erinevates tervishoiuasutustest on ta teinud vähemalt ühe külastuse. Ümarda tulemus ühe kohani peale koma. Kirjutasin kaks lauset, et seda ülesannet lahendada. Lausetest on puudu nulliga jagamise vältimine, aga see ei muuda üldpilti. Lause 1 - Tekitatakse tabelite Health_care_visit ja ja Facility otsekorrutis (leitakse kõikvõimalikud ridade paarid). Kasutatakse Count(DISTINCT ...), et leida tulemuse põhjal erinevate tervishoiuasutuste arv ja erinevate tervishoiuasutuste arv, kus on tehtud vähemalt üks reserveerimine. SELECT hcv.patient_id, Round(Count(DISTINCT hcv.facility_id)::numeric/Count(DISTINCT facility.facility_id)*100,1) AS percentageFROM Health_care_visit AS hcv, FacilityGROUP BY hcv.patient_idORDER BY hcv.patient_id; Lause 2 - Kasutatakse Count(DISTINCT ...), et leida erinevate tervishoiuasutuste arv, kus on tehtud vähemalt üks reserveerimine. Tervishoiuasutuste arv leitakse eraldi alampäringuga. SELECT hcv.patient_id, Round(Count(DISTINCT hcv.facility_id)::numeric/(SELECT Count(*) AS cnt FROM Facility)*100,1) AS percentageFROM Health_care_visit AS hcvGROUP BY hcv.patient_idORDER BY hcv.patient_id; Lause 1 täitmiseks kulus 290 minutit ja lause 2 täitmiseks 370 millisekundit. Lause 1 täitmise plaanist (lisatud pildina siia küsimusele) on näha, et tsüklis moodustatakse tulemus, kus on 50_000_000_000 (50 miljardit) rida ja siis asutakse korduseid eemaldama. Tsükli käigus materialiseeritakse e salvestatakse eraldi koopiana miljon korda tabeli Facility läbikäimise tulemus. **Märksõnad:** otsekorrutis, Cartesiuse ristkorrutis, täitmisplaan, execution plan, protsent, protsendiarvutus ## Küsimus: Kas UPDATE lause võiks kirjutada nii, et WHERE klauslisse kirjutatud tingimuse asemel kirjutatakse SET klauslisse tingimus, mille täidetuse korral uuendatakse vastavat rida? **Vastus:** Süntaksi mõttes on see tehtav ja annaks soovituse tulemus, kuid PostgreSQL (16) näitel oleks see halva jõudlusega lahendus.Vaatame näidet.Andmebaasis on tabel Health_care_visit, kus on üks miljon rida.Ülesanne: Suurenda 2020. aastal alanud visiitide visiiditasu 10%. NB! 2020. aastal ei alanud ühtegi visiiti.Lahendus 1: Otsingu tingimus on WHERE klauslis. UPDATE Health_Care_visit SET visit_fee=visit_fee*1.1 WHERE Extract(YEAR FROM from_date)=2020;   Lahendus 2: Otsingutingimuse WHERE klauslisse kirjapaneku asemel kasutan SET klauslis CASE avaldist, mis leiab iga rea korral uue visiiditasu (võib jääda samaks või olla senisest 10% suurem).UPDATE Health_Care_visit SET visit_fee=CASE WHEN Extract(YEAR FROM from_date)=2020 THEN visit_fee*1.1 ELSE visit_fee END;Käivitan mõlemad laused ning vaatan EXPLAIN ANALYZE lause abil täitmisplaani ja täitmise aega. NB! Kuna EXPAIN ANALYZE korral lause täidetakse, siis panen andmemuudatused transaktsiooni plokki, mille lõpuks tagasi rulline, et andmebaasis andmed püsivalt ei muutuks.Lahendus 1: Süsteem loeb kõiki tabeli plokke ja filtreerib välja read, mis vastavad tingimusele ja mida tuleks uuendada. Lause täitmiseks kulus 254 ms.Lahendus 2: Süsteem loeb kõiki tabeli plokke ja uuendab kõiki tabeli ridu (arvutab iga rea korral välja CASE avaldise tulemuse ning kirjutab selle visit_fee välja). Lause täitmiseks kulus 24252 ms e 95 korda rohkem aega. ## Küsimus: Kas uuema ühendamise süntaksi korral võib WHERE klauslis olevad lisapiirangud kirjutada FROM klauslis ühendamise tingimusse? **Vastus:** Vaatlen näitena andmebaasi, millel on kontseptuaalne struktuur: [Dept]-0..1-----------0..*-[Emp]SIIN on PostgreSQL andmebaasi loomise laused ja järgnevat koodi saab katsetada näiteks DB Fiddle keskkonnas.INNER JOINNeed kaks lauset:SELECT *FROM Dept INNER JOIN Emp ON Dept.deptno=Emp.deptno AND Dept.dname LIKE 'A%';SELECT *FROM Dept INNER JOIN Emp ON Dept.deptno=Emp.deptno WHERE Dept.dname LIKE 'A%';ja need kaks lauset:SELECT *FROM Dept INNER JOIN Emp ON Dept.deptno=Emp.deptno AND Emp.sal>1000;SELECT *FROM Dept INNER JOIN Emp ON Dept.deptno=Emp.deptnoWHERE Emp.sal>1000;annavad samasuguse tulemuse.Lisakommentaarid: Mõni andmebaasisüsteem (nt MS Access) ei toeta lisapiirangute kirjutamist FROM klausli ühendamise tingimusse. PostgreSQL ja Oracle näiteks toetavad. Seega väheneb koodi porditavus. PostgreSQL ja Oracle näitel on lausete täitmisplaanid ja seega ka täitmise kiirus ühesugused. Pannes lisatingimused FROM klauslisse ei saa kasutada tabelite ühendamisel mugavat ja kompaktset USING (<ühised veerud>) süntaksi. Selline lause ei toimi: SELECT * FROM Dept INNER JOIN Emp USING (deptno) AND Emp.sal>1000; Vanema ühendamise süntaksi puhul toodi probleemina välja, et WHERE klausel on tingimustega ülekoormatud. Pannes kõik tingimused FROM klauslisse on tulemus samasugune. Olukorras, kus laused annavad ühesuguse tulemuse, ei ole kõigi tingimuste koondamine FROM klauslisse mõttekas. Veel üks näide - tabelite põhjal, kus on palju rohkem andmeid (tabelis Health_care_visit on 1_000_000 rida). Täitmisplaanid ja täitmise kiirus on ühesugune, kuid loetavuse poolest on minu arvates FROM ja WHERE klausli eristamine parem.SELECT Hcv.*FROM Health_care_visit AS Hcv INNER JOIN Facility AS F ON Hcv.facility_id=F.facility_idAND EXTRACT(year FROM Hcv.from_date) >2010 AND F.facility_name ILIKE 'A%'INNER JOIN Postal_address AS P ON Hcv.postal_address_id=P.postal_address_id AND P.city='Kaduna';SELECT Hcv.*FROM Health_care_visit AS Hcv INNER JOIN Facility AS F USING (facility_id)INNER JOIN Postal_address AS P USING (postal_address_id)WHERE EXTRACT(year FROM Hcv.from_date) >2010 AND F.facility_name ILIKE 'A%'AND P.city='Kaduna';OUTER JOINLaused annavad erineva tulemuse.SELECT *FROM Dept LEFT JOIN Emp ON Dept.deptno=Emp.deptno AND Dept.dname LIKE 'A%';Tulemuses on kõik osakonnad (töötajatega või mitte) - ka sellised, mille nimi ei alga A tähega.SELECT *FROM Dept LEFT JOIN Emp ON Dept.deptno=Emp.deptno WHERE Dept.dname LIKE 'A%';Tulemuses on ainult sellised osakonnad (töötajatega või mitte), mille nimi algab A tähega.SELECT *FROM Dept LEFT JOIN Emp ON Dept.deptno=Emp.deptno AND Emp.sal>1000;Tulemuses on töötajad, kelle palk on üle 1000 EUR + üks rida iga osakonna (Dept) kohta, milles pole ühtegi üle 1000 EUR palgaga töötajat. Seda saab kasutada, et lahendada ülesanne: Leia osakonnad, kus pole ühtegi üle 1000 EUR palgaga töötajat.SELECT Dept.*FROM Dept LEFT JOIN Emp ON Dept.deptno=Emp.deptnoAND Emp.sal>1000WHERE Emp.deptno IS NULL;Järgneva päringu tulemuses on töötajad, kelle palk on üle 1000 EUR.SELECT *FROM Dept LEFT JOIN Emp ON Dept.deptno=Emp.deptnoWHERE Emp.sal>1000; ## Küsimus: Kas ühes ja samas SQL päringus võib segamini kasutada vanemat ja uuemat ühendamise süntaksi? **Vastus:** Jah, see on tehniliselt võimalik. Kuid see ei ole soovitav, sest halvendab koodi loetavust.Halvem.SELECT Tudeng.tudkood, Tudeng.perenimi, Oppimine.oppim_algus, Oppimine.oppim_lopp, Aine.aine_kood, Aine.nimetusFROM Aine, Tudeng INNER JOIN Oppimine ON Tudeng.tudkood = Oppimine.tudengWHERE Aine.aine_kood = Oppimine.aine;Parem.SELECT Tudeng.tudkood, Tudeng.perenimi, Oppimine.oppim_algus, Oppimine.oppim_lopp, Aine.aine_kood, Aine.nimetusFROM (Tudeng INNER JOIN Oppimine ON Tudeng.tudkood = Oppimine.tudeng)INNER JOIN Aine ON Aine.aine_kood = Oppimine.aine;--läbivalt uuem süntaksSELECT Tudeng.tudkood, Tudeng.perenimi, Oppimine.oppim_algus, Oppimine.oppim_lopp, Aine.aine_kood, Aine.nimetusFROM Tudeng, Oppimine, AineWHERE Tudeng.tudkood = Oppimine.tudengAND Aine.aine_kood = Oppimine.aine;--läbivalt vanem süntaks **Märksõnad:** puhas kood, clean code, SQL, join, ühendamine ## Küsimus: Kuidas arvutada SQLis protsenti nii, et ei peaks sama tabelit mitmekordselt lugema? **Vastus:** PostgreSQLis on andmebaas järgmise kontseptuaalse struktuuriga.[Facility_type]-1-------0..*-[Facility]-1---------------0..*-[Health_care_visit]Tabelis Facility_type on 5 rida.Tabelis Facility on 5_000 rida.Tabelis Health_care_visit on 1_000_000 rida.Järgnevalt esitatakse kolm ülesannet ja nende lahendused PostgreSQLis (16). Lahendus 1 korral tehakse kaks päringut samadesse tabelitesse. Need päringud vormistatakse  parema loetavuse huvides ühiste tabeli avaldistena (common table expression) - need on lause alguses WITH klauslis. Lausete täitmisplaanid näitavad, et samu tabeleid ja nende indekseid loetakse mitmekordselt. Lahendus 2 korral tehakse samade tabelite põhjal üks päring. Protsendi arvutamiseks vajalike arvude leidmiseks kasutatakse Count kokkuvõttefunktsiooni koos FILTER predikaadiga.  Lausete täitmisplaanid näitavad, et samu tabeleid ja nende indekseid loetakse ühekordselt. PostgreSQLis peab jagamisoperatsioonide täpsuse huvides vähemalt ühe argumendi teisendama Decimal tüüpi (seda teeb ::decimal). Kõigi lausete puhul kasutatakse nulliga jagamise vältimiseks Nullif funktsiooni, mis tagastab NULL kui argumendid on võrdsed (Väärtus/NULL=> NULL). Kõigi lausete puhul kasutatakse ümardamiseks Round funktsiooni.  Kõigi lausete puhul vaadatakse täitmisplaani ja täitmise kiirust kasutades EXPLAIN ANALYZE lauset. Ülesanne 1: Leia, kui mitu protsenti moodustab tervishoiuasutuste külastuste arv, kus tasu on alla 9000, külastuste arvust, kus tasu on 9000 või rohkem. Väldi nulliga jagamist. Ümarda tulemus ühe kohani peale koma.Lahendus 1 WITH smaller_fee AS (SELECT Count(*) AS cnt FROM Health_care_visit WHERE visit_fee<9000), higher_fee AS (SELECT Count(*) AS cnt FROM Health_care_visit WHERE visit_fee>=9000) SELECT Round(smaller_fee.cnt::decimal*100/nullif(higher_fee.cnt::decimal,0),1) AS percent FROM smaller_fee, higher_fee; Täitmise aeg: 208 ms. Lahendus 2 SELECT Round(Count(*) FILTER (WHERE visit_fee<9000)::decimal/nullif(Count(*) FILTER (WHERE visit_fee>=9000)::decimal,0),1) AS percent FROM Health_care_visit; Täitmise aeg: 136 ms.Ülesanne 2: Leia, kui mitu protsenti moodustab kliinikute külastuste arv haiglate külastuste arvust. Väldi nulliga jagamist. Ümarda tulemus ühe kohani peale koma.Lahendus 1   WITH hospital_visits AS (SELECT Count(*) AS cnt FROM Facility AS F INNER JOIN Health_care_visit AS Hcv USING (facility_id) WHERE facility_type_code='HOS01'), clinic_visits AS (SELECT Count(*) AS cnt FROM Facility AS F INNER JOIN Health_care_visit AS Hcv USING (facility_id) WHERE facility_type_code='CLI06') SELECT Round(clinic_visits.cnt::decimal*100/nullif(hospital_visits.cnt::decimal,0),1) AS percent FROM hospital_visits, clinic_visits; Täitmise aeg: 113 ms.Lahendus 2 SELECT Round(Count(*) FILTER (WHERE facility_type_code='CLI06')::decimal*100/nullif(Count(*) FILTER (WHERE facility_type_code='HOS01')::decimal,0),1) AS hospital_visits_cnt FROM Facility AS F INNER JOIN Health_care_visit AS Hcv USING (facility_id); Täitmise aeg: 98 ms.Ülesanne 3: Leia, kui mitu protsenti moodustab tervishoiuasutuste arv, kus on vähemalt üks külastus, mille eest tasuti üle 9000 ühiku raha, kõigi asutuste arvust, kus on tehtud vähemalt üks külastus. Väldi nulliga jagamist. Ümarda tulemus ühe kohani peale koma.Lahendus 1   WITH total_facilities AS (SELECT Count(*) AS cnt FROM Facility), facilities_with_high_fees AS (SELECT Count(*) AS cnt FROM Facility AS F  WHERE EXISTS (SELECT * FROM Health_care_visit AS Hcv WHERE F.facility_id=Hcv.facility_id AND visit_fee>9000 )) SELECT Round(facilities_with_high_fees.cnt*100/nullif(total_facilities.cnt,0),1) AS percent FROM total_facilities, facilities_with_high_fees;Täitmise aeg: 122 ms. Lahendus 2 SELECT Round(Count(DISTINCT Hcv.facility_id) FILTER (WHERE visit_fee>9000)::decimal*100/nullif(Count(DISTINCT F.facility_id)::decimal,0),1) AS percent FROM Facility AS F INNER JOIN Health_care_visit AS Hcv USING (facility_id);Täitmise aeg: 462 ms.Järeldused. Sama ülesannet saab lahendada mitmel erineval viisil. Protsendi arvutamine nii, et sama tabelit ei pea mitu korda lugema on mõnikord kiirem kui protsendi arvutamine nii, et sama tabelit loetakse mitu korda (ülesanded 1 ja 2) kuid mõnikord ei ole (ülesanne 3). Ülesande 3 lahenduse 2 puhul tundub probleemiks olevat vajadus eemaldada korduseid. **Märksõnad:** protsent, protsendiarvutus, FILTER klausel, nulliga jagamine ## Küsimus: Kuidas jõustada MS Accessi ja PostgreSQL andmebaasis piirangut, et väärtus ei tohi olla tühi string, tühikutest koosnev string, tühimärkidest koosnev string? **Vastus:** Tühi string, tühikutest koosnev string ja tühimärkidest koosnev string on kõik tekstilised väärtused ning selliseid piiranguid võib olla vaja jõustada tekstiliste veergude põhjal.Need ei ole sama mis NULL. NULL on spetsiaalne tähis, mis osutab väärtuse puudumisele, samas kui eelnimetatud on väärtused. Tühimärkide hulk (ingl k whitespace character)  hõlmab tühikuid, tabulatsioone, reavahetusi ja muid mitteprinditavaid tühikuid tekstis.Oletame, et tabelis on veerg nimega nimetus. Mõned märkused: Trim on paljudes andmebaasisüsteemides toetatud funktsioon, mis eemaldab stringi algusest ja lõpust tühikud. Esitatud kitsendused on sellised, kus iga kitsenduse realisatsioon hõlmab endas ka eelmiste kitsenduste jõustamist (seega näiteks kitsenduse "ei tohi olla tühimärkidest koosnev string" realisatsioon välistab ka tühikutest koosnevate stringide ja tühjade stringide registreerimise. MS Access Ei tohi olla tühi string (kaks võimalikku viisi): Veeru nimetus omadus, mida saab määrata graafilises kasutajaliideses: Allow Zero Length = No CHECK(nimetus<>'') Ei tohi olla tühikutest koosnev string (kaks võimalikku viisi): Veeru nimetus valideerimisreegel, mida saab määrata graafilises kasutajaliideses: Trim([nimetus])<>'' CHECK(Trim(nimetus)<>'') Ei tohi olla tühimärkidest koosnev string: Ei saa jõustada PostgreSQL Ei tohi olla tühi string: CHECK(nimetus<>'') Ei tohi olla tühikutest koosnev string: CHECK(Trim(nimetus)<>'') Ei tohi olla tühimärkidest koosnev string: CHECK(nimetus!~'^[[:space:]]*$') Kasutatakse regulaaravaldist !~ - operaator, mis kontrollib, et string ei vastaks mustrile [[:space:]] - tühimärkide klass ^ - stringi algus $ - stringi lõpp * - esineb null või rohkem korda Alternatiivne kirjapilt: CHECK(nimetus!~'^\s*$') **Märksõnad:** regulaaravaldis, regular expression, regex ## Küsimus: Kuidas kasutada õigesti TOP (MS Access) ja FETCH FIRST n ROWS WITH TIES (PostgreSQL) predikaate väärtuste jadas kohal x olevate väärtuste leidmiseks? **Vastus:** TOP n - saab kasutada MS Accessis (samaväärset TOP ... WITH TIES saab kasutada MS SQL Serveris). SQL standard ei kirjelda. LIMIT n - Saab kasutada nt PostgreSQLis (ja ka nt LibreOffice Baseis). SQL standard ei kirjelda. FETCH FIRST n ROWS ONLY - Samaväärne LIMITiga. Saab kasutada nt PostgreSQLis. Seda kirjeldab SQL standard. FETCH FIRST n ROWS WITH TIES - Samaväärne MS Accessi TOPiga. Saab kasutada nt PostgreSQLis. Seda kirjeldab SQL standard. Kõik need predikaadid põhinevad sellel, et read sorteeritakse ja valitakse esimesed read. LIMIT n ja FETCH FIRST n ROWS ONLY tagastavad maksimaalselt n rida. TOP n ja FETCH FIRST n ROWS WITH TIES võivad tagastada rohkem kui n rida. Kui sorteerimise aluseks olevas veerus on reas n mingi väärtus, mis on ka järgnevates ridades, siis on tulemuses ka need read. NB! PostgreSQLis saaks järgneva kahe ülesande lahendamiseks edukalt kasutada ka Dense_rank aknafunktsiooni. See leiab tiheda pingerea. Tihedas pingereas on asetused näiteks 1,1,2, mitte 1,1,3. Lahenduseks on leida suuruste või esinemiste arvu pingerida ja valida sealt kolmandal kohal olevad tulemused.Loon näitena tabeliCREATE TABLE Vaartus (suurus SMALLINT NOT NULL);INSERT INTO Vaartus(suurus) VALUES (10);INSERT INTO Vaartus(suurus) VALUES (10);INSERT INTO Vaartus(suurus) VALUES (10);INSERT INTO Vaartus(suurus) VALUES (9);INSERT INTO Vaartus(suurus) VALUES (9);INSERT INTO Vaartus(suurus) VALUES (9);INSERT INTO Vaartus(suurus) VALUES (8);INSERT INTO Vaartus(suurus) VALUES (8);INSERT INTO Vaartus(suurus) VALUES (7);Ülesanne 1: Leia tabelist Vaartus read, kus on suuruselt kolmas suurus. Antud andmete korral tuleks leida read, kus suurus on 8.Vale lahendus MS Accessis:SELECT suurusFROM VaartusWHERE suurus = (SELECT Min(suurus) AS mFROM (SELECT TOP 3 suurusFROM VaartusORDER BY suurus DESC) AS ap);Vale lahendus PostgreSQLis:SELECT suurusFROM VaartusWHERE suurus = (SELECT Min(suurus) AS mFROM (SELECT suurusFROM VaartusORDER BY suurus DESCFETCH FIRST 3 ROWS WITH TIES) AS ap);Tulemuseks on read, kus suurus on 10.Alampäring, kus on TOP/FETCH, ei leia mitte kolme erinevat suurimat suurust, vaid suuruse järgi kahanevalt sorteeritud tulemusest kolm esimest rida. Juhul kui on veel mõni rida, kus on esimeses kolmes reas olnud suurus, siis on ka see tulemuses. Antud juhul on tulemuses read, kus suurus on 10.Õige lahendus MS Accessis:SELECT suurusFROM VaartusWHERE suurus = (SELECT Min(suurus) AS mFROM (SELECT DISTINCT TOP 3 suurusFROM VaartusORDER BY suurus DESC) AS ap);Õige lahendus PostgreSQLis:SELECT suurusFROM VaartusWHERE suurus = (SELECT Min(suurus) AS mFROM (SELECT DISTINCT suurusFROM VaartusORDER BY suurus DESCFETCH FIRST 3 ROWS WITH TIES) AS ap);Sisemine alampäring leiab kolm erinevat kõige suuremat suurust. Välimine alampäring leiab nende hulgast kõige väiksema. Põhipäring leiab kõik read, kus on leitud suurus. Antud juhul võib alampäringus kasutada ka FETCH FIRST 3 ROWS ONLY või LIMIT, sest see ei muuda tulemust.Ülesanne 2: Leia tabelist Vaartus esinemiste arvult kolmandal kohal olevad suurused. Väljasta suurus ja selle esinemiste arv. Antud andmete korral tuleks leida suurus 7, mida esineb üks kord.Vale lahendus MS Accessis:SELECT suurus, Count(*) AS arvFROM VaartusWHERE suurus=(SELECT Min(suurus) AS mFROM (SELECT TOP 3 suurus, Count(*) AS arvFROM VaartusGROUP BY suurusORDER BY Count(*) DESC) AS ap)GROUP BY suurus;Vale lahendus PostgreSQLis:SELECT suurus, Count(*) AS arvFROM VaartusWHERE suurus=(SELECT Min(suurus) AS mFROM (SELECT suurus, Count(*) AS arvFROM VaartusGROUP BY suurusORDER BY Count(*) DESCFETCH FIRST 3 ROWS WITH TIES) AS ap)GROUP BY suurus;Tulemuseks on suurus 8, mida esineb kaks korda.Alampäring, kus on TOP/FETCH, ei leia mitte kolme erinevat suurimat suuruste esinemiste arvu, vaid arvu järgi kahanevalt sorteeritud tulemusest kolm esimest rida. Juhul kui on veel mõni rida, kus on esimeses kolmes reas olnud arv, siis on ka see tulemuses. Antud juhul on tulemuses kaks rida, kus arv on 3 ja üks rida, kus arv on kaks. Õige lahendus MS Accessis:SELECT suurus, Count(*) AS arvFROM VaartusGROUP BY suurusHAVING Count(*)=(SELECT Min(arv) AS mFROM (SELECT DISTINCT TOP 3 Count(*) AS arvFROM VaartusGROUP BY suurusORDER BY Count(*) DESC) AS ap);Õige lahendus PostgreSQLis:SELECT suurus, Count(*) AS arvFROM VaartusGROUP BY suurusHAVING Count(*)=(SELECT Min(arv) AS mFROM (SELECT DISTINCT Count(*) AS arvFROM VaartusGROUP BY suurusORDER BY Count(*) DESCFETCH FIRST 3 ROWS WITH TIES) AS ap);Sisemine alampäring leiab kolm erinevat kõige suuremat esinemiste arvu. Välimine alampäring leiab nende hulgast kõige väiksema. Põhipäring leiab erinevate suuruste esinemiste arvu ja jätab alles read, kus see arv on võrdne alampäringutega leitud arvuga. Antud juhul võib alampäringus kasutada ka FETCH FIRST 3 ROWS ONLY või LIMIT, sest see ei muuda tulemust. ## Küsimus: Kuidas katsetada SQLis päringuid ilma, et mul oleks tabeleid, mille põhjal seda teha? **Vastus:** Kasutades lauses ühiseid tabeli avaldisi (common table expression) on võimalik päringu kontekstis koostada tabel, mille põhjal päringut täita.Näide: Oletame, et ma tahan teada, kas tingimus pikkus NOT IN (170, 180) on loogiliselt samaväärne kui tingimus  pikkus <>170 OR pikkus<>180 või tingimus pikkus <>170 AND pikkus<>180. Saan seda katsetada ilma, et mul oleks andmebaasis baastabelit, kus on veerg pikkus koos sobivate väärtustega.Näiteks lähen DB-Fiddle keskkonda, valin PostgreSQL ja proovin neid kolme lauset. Kõigis nendes pannakse WITH klauslis VALUES lauset ja konstante kasutades samasuguse struktuuriga ja andmetega tabel, millest põhilausega andmeid otsitakse. WITH klauslis saab ära määrata tabeli avaldisega moodustatud tabeli veergude nimed.   WITH pikkused (pikkus) AS (VALUES (150), (160), (170), (180), (190), (200)) SELECT * FROM pikkused WHERE pikkus NOT IN (170, 180);   WITH pikkused (pikkus) AS (VALUES (150), (160), (170), (180), (190), (200)) SELECT * FROM pikkused WHERE pikkus <>170 OR pikkus<>180;   WITH pikkused (pikkus) AS (VALUES (150), (160), (170), (180), (190), (200)) SELECT * FROM pikkused WHERE pikkus <>170 AND pikkus<>180; **Märksõnad:** cte, ühine tabeli abaldis ## Küsimus: Kuidas konkateneerida MS Accessis, PostgreSQLis ja LibreOffice Baseis tekstilisi väärtuseid, kui üks väärtus puudub (on NULL)? **Vastus:** Oletame, et andmebaasis on tabel, kuhu on lisatud kaks rida andmeid. Ühel isikul perenimi puudub (on NULL).CREATE TABLE Isik(isik_id INTEGER,eesnimi VARCHAR(50) NOT NULL,perenimi VARCHAR(50),CONSTRAINT pk_isik PRIMARY KEY (isik_id));INSERT INTO Isik (isik_id, eesnimi) VALUES (1,'Mati');INSERT INTO Isik (isik_id, eesnimi, perenimi) VALUES (2,'Kati','Karu');Ülesanne: Leia kõik isikud. Väljasta iga isiku kohta isik_id ning ees- ja perenimi ühe stringina. Nime komponentide vahel peab olema tühik.PostgreSQLSELECT isik_id, eesnimi || ' ' || perenimi AS nimiFROM Isik;Isikul, kelle perenimi on NULL, on nime väljas samuti NULL, sest NULL || 'tekst'=>NULLKuidas saada tulemus, kus puuduva perenimega isikul on nime väljas eesnimi?Lahendus 1: Funktsioon Coalesce tagastab vasakult lugedes esimese argumendi, mis pole NULL. Selle abil asendatakse NULL tühja stringiga. Funktsiooni Trim abil eemaldatakse stringi lõpust tühik.SELECT isik_id, Trim(eesnimi || ' ' || Coalesce(perenimi,'')) AS nimiFROM Isik;Lahendus 2: SELECT isik_id, Trim(Concat(eesnimi,' ',perenimi)) AS nimiFROM Isik;Lahendus 3: Trim funktsiooni tühiku eemaldamiseks eesnime järelt ei ole vaja.SELECT isik_id, Concat_ws(' ', eesnimi, perenimi) AS nimiFROM Isik;Lahendus 4:SELECT isik_id, Trim(Format('%1$s %2$s', eesnimi, perenimi)) AS nimiFROM Isik;MS AccessSELECT isik_id, Trim(eesnimi & ' ' & perenimi) AS nimiFROM Isik;MS Accessis on kaks eraldi stringide konkatenatsiooni operaatorit, mille korral on erinevus tulemuses, kui argument on NULL.NULL & 'tekst'=>'tekst'NULL+tekst=>'tekst'LibreOffice Base (kasutab HSQLDB)SELECT ISIK_ID, Trim(BOTH FROM (EESNIMI || ' ' || Coalesce(PERENIMI,''))) AS NIMIFROM ISIK;Sarnaselt PostgreSQLile NULL || 'tekst'=>NULL. Seega kasutatakse Coalesce funktsiooni, et asendada NULL tühja stringiga. ## Küsimus: Kuidas kustutada korraga mitu tabeliga seotud kitsendust? **Vastus:** See on hea näide, kuidas SQLi dialekt e mägimurrak erineb erinevates andmebaasisüsteemides detailide poolest. Järgnev katsetus tehti keskkondades DB Fiddle, SQL Fiddle ja db<>fiddle. CREATE TABLE Riik (riik_kood CHAR(3) NOT NULL, CONSTRAINT pk_riik PRIMARY KEY (riik_kood));   CREATE TABLE Isik(isik_id INTEGER NOT NULL, pikkus SMALLINT NOT NULL, kaal SMALLINT NOT NULL, riik_kood CHAR(3) NOT NULL, CONSTRAINT pk_isik PRIMARY KEY (isik_id), CONSTRAINT chk_isik_pikkus CHECK (pikkus>0), CONSTRAINT chk_isik_kaal CHECK (kaal>0), CONSTRAINT fk_isik_riik FOREIGN KEY (riik_kood) REFERENCES Riik (riik_kood)); Kustuta tabelist Isik ühe lausega CHECK kitsendused ning välisvõtme kitsendus.PostgreSQL (17), MySQL (9),  Firebird (4), MariaDB (10.9): ALTER TABLE Isik DROP CONSTRAINT chk_isik_pikkus, DROP CONSTRAINT chk_isik_kaal, DROP CONSTRAINT fk_isik_riik;--komadegaOracle (23ai), IBM DB2 (11): ALTER TABLE Isik DROP CONSTRAINT chk_isik_pikkus DROP CONSTRAINT chk_isik_kaal DROP CONSTRAINT fk_isik_riik;--komadeta MS SQL Server (2022): ALTER TABLE Isik DROP CONSTRAINT chk_isik_pikkus, chk_isik_kaal, fk_isik_riik;MS Access (365): ALTER TABLE Isik DROP CONSTRAINT chk_isik_pikkus; ALTER TABLE Isik DROP CONSTRAINT chk_isik_kaal; ALTER TABLE Isik DROP CONSTRAINT fk_isik_riik;--eraldi lausedLibreOffice Base (HSQLDB), SQLite (3.39):Kitsendusi saab defineerida, kuid ALTER TABLE lausega kustutada ei saa. ## Küsimus: Kuidas leida andmebaasist andmeid, mida seal justkui ei ole? Näiteks on andmebaasis andmed külaliste ja nende hotellide reserveerimiste kohta ja pean leidma külalised, kes EI OLE, 2014. aastal ühegi reserveerimist alustanud. **Vastus:** Andmebaasi kontseptuaalne struktuur on antud juhul järgmine.[Külaline]-1----------------0..*-[Reserveerimine] Võimalik ülesande lahendus on selline. SELECT Külaline.külalise_nr, Külaline.perenimiFROM KülalineWHERE Külaline.külalise_nr NOT IN(SELECT Reserveerimine.külalise_nr FROM ReserveerimineWHERE Year(Reserveerimine.alguse_aeg) = 2014); SQLis me töötame hulkadega. Oletame näiteks, et teete fotosid ja peate valima, milliseid tahate säilitada. On kaks fotode hulka - need mida säilitada ja need mida mitte. Säilitatavaid fotosid võib hakata ükshaaval välja valima. Kuid mõnikord võib lihtsam olla vaadata kõik fotod üle ja visata ära need, mis ei tulnud kindlasti välja. Kõik allesjäänud fotod kuuluvad säilitamisele. Nii ka siin - alampäringuga leian kõik külalised, kellel on mõni reserveerimine 2014. aastal alanud. Põhipäringuga leian kõik ülejäänud külalised. Nende hulka kuuluvad nii külalised, kellel pole üldse reserveeringuid kui ka need, kelle kõik reserveeringud on alanud muul ajal kui 2014. aastal. Siit tuleb välja üks üldine probleemide lahendamise strateegia (SQLis ja mujal). Kui tahan leida mingitele tingimusele vastavad olemid või seosed, siis otsin kõigepealt kõiki neid, mis minu tingimustele ei vasta ja siis leian kõik ülejäänud seda tüüpi olemid või seosed - need ongi need, mida otsin.   ## Küsimus: Kuidas leida iga rea kohta ühest tabelist selliste ridade arv teisest tabelist, mis rahuldavad mingit tingimust? Kas erinevatel lahendustel on töökiiruse mõttes erinevusi? **Vastus:** Toon näite. Olgu meil PostgreSQL andmebaas, millel on järgmine kontseptuaalne struktuur[Facility]-1-------------0..*-[Health_care_visit]Tabelis Facility on 50_000 rida.Tabelis Health_care_visit on 1_000_000 rida.Järgnevad katsetused on tehtud PostgreSQL (17) põhjal. Täitmisplaanide ja täitmise kiiruse vaatamiseks kasutasin EXPLAIN ANALYZE lauset. Rõhutan, et nende ülesannete juures pakutud lahendusvariandid on loogiliselt samaväärsed e annavad alati sama tulemuse. Kõik need on kokku näide "abstraktsioonide lekkimise" kohta e selle kohta, kuidas andmete füüsilise ("süsteemi kaane all") salvestamise ja töötlemise küsimused "lekivad" andmete kasutaja maailma ja kokkuvõttes peab ta teadma, kuidas oleks konkreetses süsteemis kõige otstarbekam oma küsimusi formuleerida. Ülesanne: Leia iga rea kohta tabelis Facility selliste ridade arv tabelis Health_care_visit, kus külastus algas 2010. aastal.Kõikides lahendustes kasutatakse välisühendamist, et tulemuses oleksid ka sellised read tabelist Facility, millele ei ole tingimusele vastavaid ridu tabelis Health_care_visit.Lahendus 1:SELECT facility_name, Count(hcv.facility_id) AS cnt FROM Facility LEFT JOIN health_care_visit AS hcv ON Facility.facility_id=hcv.facility_id AND Extract(year FROM from_date)=2010 GROUP BY facility_name; Teises tabelis huvipakkuvaid ridu piirav tingimus on kirjutatud ühendamise tingimusse.Lahendus 2: WITH hcv AS (SELECT facility_id FROM health_care_visit  WHERE Extract(year FROM from_date)=2010) SELECT facility_name, Count(hcv.facility_id) AS cnt FROM Facility LEFT JOIN hcv ON Facility.facility_id=hcv.facility_id GROUP BY facility_name;Teises tabelis huvipakkuvad read leitakse alampäringuga, mis on vormistatud ühise tabeli avaldisena. Põhipäringus ühendatakse need andmed esimese tabeliga ning arvutatakse koondandmed.Lahendus 3: SELECT facility_name, Count(hcv.facility_id) FILTER (WHERE Extract(year FROM from_date)=2010) AS cnt FROM Facility LEFT JOIN health_care_visit AS hcv ON Facility.facility_id=hcv.facility_id GROUP BY facility_name; Kasutatakse FILTER funktsionaalsust.Lahenduste 1 ja 2 korral kasutas andmebaasisüsteem tabeli Health_care_visit kõigi ridade läbivaatamiseks kahte paralleelprotsessi. Lause täitmine võttis umbes 150 ms. Lahenduse 3 korral vaatas andmebaasisüsteem samuti läbi kõik tabeli Health_care_visit read, kuid paralleeltööd sealjuures ei kasutanud ning lause täitmine võttis umbes 500 ms. ## Küsimus: Kuidas Mauruse otsing täpsemalt töötab? Millist tuge pakkus selle realiseerimiseks andmebaasisüsteem, mida Maurus kasutab? **Vastus:** Mauruse kasutajad soovisid sageli, et seal oleks otsingu funktsionaalsus. Lisasin Maurusesse selle funktsionaalsuse. Otsing on võimalik kodulehe piires. Leiate võimaluse seda teha iga aine kodulehe paremast ülaservast. Otsing toimub üle aine sisu kirjelduse, materjalide metaandmete, tegevuskava, teadete (v.a isiklikud teated), kasutajatoe küsimuste/vastuste, viidete, tähaegade, ülesannete (kuid mitte nende vastused) ja vastuvõtuaegade. Otsingu tulemused on ühel lehel nende kategooriate kaupa grupeerituna. Materjale, teateid ja kasutajatoe küsimusi/vastuseid on otsingu tulemuses igaühte kuni 10. Viiteid on tulemuses kuni 20. Materjalide puhul ei toimu otsing mitte failide sisu, vaid materjale kirjeldavate andmete (metaandmete) põhjal. Kuna Maurus kasutab PostgreSQL andmebaasisüsteemi, siis tegi PostgreSQLi pakutav täisteksti otsingu funktsionaalsus, mille kohta saab näiteks lugeda SIIT ja SIIT, selle funktsionaalsuse realiseerimise lihtsamaks. Järgnevalt esitan koodinäite. Näiteks oletame, et tahan lisada teadete otsimise võimaluse ning et andmebaasis on tabel Avalik_teade, üle mille veergude pealkiri ja sisu peaks otsing toimuma. CREATE TABLE Avalik_teade(avalik_teade_id SERIAL,pealkiri TEXT NOT NULL,sisu TEXT NOT NULL,CONSTRAINT pk_avalik_teade PRIMARY KEY (avalik_teade_id));INSERT INTO Avalik_teade (pealkiri, sisu) VALUES ('Otsinguvõimalus', 'Kodulehel saab nüüd teha otsingut'); Lisan tabelisse veeru tsv, mis hakkab iga teate korral sisaldama spetsiaalset pealkirja ning sisu kokkuvõtet ja on ühtlasi aluseks nende alusel otsingute tegemisele. See veerg on tüüpi tsvector. See on spetsiifiline PostgreSQLi andmetüüp. Kahjuks ei ole täistektiotsingutel eesti keele tuge, tänu millele oskaks andmebaasisüsteem otsingu tegemisel arvestada keele eripäradega. Seega kasutan inglise keele (english) reegleid. Tabelisse lisatud rea korral oleks veerus tsv väärtus: 'kodulehel':2 'nüüd':4 'otsingut':6 'otsinguvõimalus':1 'saab':3 'teha':5Andmete automaatseks uuendamiseks tekstiotsingu veerus on kaks võimalust.Võimalus 1. Lisan tabelisse kohustusliku arvutatava veeru, mille väärtus on salvestatud kettale (stored).ALTER TABLE Avalik_teadeADD COLUMN tsv tsvectorGENERATED ALWAYS AS (to_tsvector('english', coalesce(pealkiri, '') || ' ' || coalesce(sisu, ''))) STORED NOT NULL;coalesce funktsioon tagastab vasakult lugedes esimese argumendi, mis ei ole NULL. coalesce(pealkiri,'') avaldis tähendab, et kui pealkiri on olemas (pole NULL) tagastab funktsioon pealkirja, vastasel juhul teiseks argumendiks oleva tühja stringi. Tühi string ja NULL on kaks ise asja - tühi string on väärtus, kuid NULL on marker, mis tähistab väärtuse puudumist. coalesce läheb vaja, sest PostgreSQLi stringide ühendamise (konkatenatsiooni) operaator käitub juhul kui üks argument on NULL järgnevalt: 'tekst' || NULL => NULL. Juhuks kui teates pealkiri või sisu puudub tuleb enne nende ühendamist kontrollida kas üks nendest on NULL ja vajadusel asendada see tühja stringiga: 'tekst' || '' => 'tekst'Võimalus 2. Lisan tabelisse uue veeru ning lisan tabelile trigeri, mis tabelisse rea lisamisel või olemasolevas reas pealkirja või sisu uuendamisel, arvutab tsvector väärtuse ja salvestab sellesse veergu. ALTER TABLE Avalik_teade ADD COLUMN tsv tsvector; Loon tabeliga seotud trigeri, mis andmete tabelisse lisamisel või muutmisel värskendab veergudes pealkiri ja sisu olevate andmete põhjal veerus tsv olevaid andmeid. Määran, et ridade uuendamise (UPDATE) korral peaks triger käivituma ainult siis, kui andmeid uuendatakse (UPDATE) mingis kindlas veerus. CREATE TRIGGER teade_tsv_iu BEFORE INSERT OR UPDATE OF pealkiri, sisuON Avalik_teade FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(tsv, 'pg_catalog.english', pealkiri, sisu); Teen andmemuudatuse, mis tänu eelnevale trigerile tingib andmete lisamise veergu tsv. UPDATE Avalik_teade SET pealkiri=pealkiri; Muudan veeru tsv kohustuslikuks. ALTER TABLE Avalik_teade ALTER COLUMN tsv SET NOT NULL;   Loon veerule tsv otsingu kiirendamiseks indeksi, ükskõik kas kasutan võimalust 1 või 2. CREATE INDEX teade_tsv_idx ON Avalik_teade USING gin(tsv); Järgnev päring leiab tabelist Avalik_teade sellised teated, mis sisaldavad sõna "otsingut". Päring väljastab teate identifikaatori, pealkirja, sisu ning pealkirja ja sisu põhjal moodustatud kokkuvõtte, kus on otsisõna esile tõstetud. Päringu tulemus on sorteeritud tulemuse relevantsuse hinnangu alusel kahanevalt. Päringu tulemuses on maksimaalselt 10 rida.. SELECT avalik_teade_id, pealkiri, sisu, ts_headline(coalesce(pealkiri,'') || ' ' || coalesce(sisu,''), q) AS fragment FROM (SELECT avalik_teade_id, pealkiri, sisu, q, ts_rank_cd(tsv,q) AS rank FROM Avalik_teade, to_tsquery('otsingut') AS q WHERE tsv @@ q ORDER BY rank DESC FETCH FIRST 10 ROWS ONLY) AS foo; **Märksõnad:** tekstiotsing ## Küsimus: Kuidas oleks PostgreSQLis töökiiruse mõttes kõige efektiivsem leida andmed ühest tabelist ja väljastada tulemuses ka tõeväärtus, mis leitakse teises tabelis olevate andmete põhjal? **Vastus:** Järgnev katsetus on tehtud PostgreSQL (16) põhjal.Andmebaasis on tabelid järgmise kontseptuaalse struktuuriga:[Person]-1----------0..*-[Health_care_visit]Tabelis Person on 70_000 rida.Tabelis Health_care_visit on 1_000_000 rida.Tabelis Health_care_visit on liitindeks, mille esimene veerg on person_id, ja millesse kuulub ka veerg from_date.Ülesandeks on leida iga isiku kohta tema isiku id, eesnimi, perenimi, sünniaeg ja tõeväärtus, mis näitab, kas isikul on alanud viimase viie aasta jooksul vähemalt üks visiit (TRUE) või mitte (FALSE).Kolm võimalikku lahendust.Lahendus 1: SELECT klauslis on korreleeruv EXISTS alampäring SELECT party_id, first_name, last_name, birth_date, EXISTS (SELECT * FROM Health_care_visit AS hcv  WHERE hcv.patient_id=person.party_id AND EXTRACT (YEAR FROM from_date) BETWEEN EXTRACT(YEAR FROM CURRENT_DATE)-5 AND EXTRACT(YEAR FROM CURRENT_DATE)) AS has_recent_visits FROM Person; Lahendus 2: SELECT klauslis on korreleeruv alampäring, millega loendatakse isikuga seotud sobivate visiitide arv ja väljastatakse tõeväärtus TRUE, kui see arv on suurem kui 0. SELECT party_id, first_name, last_name, birth_date, (SELECT Count(*)>0 AS reslt FROM Health_care_visit AS hcv  WHERE hcv.patient_id=person.party_id AND EXTRACT (YEAR FROM from_date) BETWEEN EXTRACT(YEAR FROM CURRENT_DATE)-5 AND EXTRACT(YEAR FROM CURRENT_DATE)) AS has_recent_visits FROM Person;   Lahendus 3: Kasutatakse kokkuvõttefunktsiooni Bool_or, mis tagastab ridade rühma kohta tõeväärtuse TRUE, kui vähemalt ühe rühma kuuluva rea puhul arvutatud tõeväärtus on TRUE.SELECT party_id, first_name, last_name, birth_date, Bool_or(EXTRACT (YEAR FROM from_date) BETWEEN EXTRACT(YEAR FROM CURRENT_DATE)-5 AND EXTRACT(YEAR FROM CURRENT_DATE)) AS has_recent_visits FROM Person INNER JOIN Health_care_visit AS hcv  ON hcv.patient_id=person.party_idGROUP BY party_id, first_name, last_name, birth_date;Lahendus 4: Ühises tabeli avaldises (common table expression) leitakse hiljuti külastusi teinud patsientide identifikaatorid. Põhipäringus ühendatakse need andmed välisühendamist kasutades tabeliga Person - välisühendamist kasutatakse, et tulemuses oleks ka need isikud, kellel hiljutisi külastusi ei ole.  WITH recent_visitors AS (SELECT DISTINCT patient_id FROM Health_care_visit WHERE EXTRACT (YEAR FROM from_date) BETWEEN EXTRACT(YEAR FROM CURRENT_DATE)-5 AND EXTRACT(YEAR FROM CURRENT_DATE)) SELECT party_id, first_name, last_name, birth_date, CASE WHEN rv.patient_id IS NOT NULL THEN TRUE ELSE FALSE END AS  has_recent_visits FROM Person LEFT JOIN recent_visitors AS rv  ON rv.patient_id=person.party_id; Kasutasin lausete käivitamiseks EXPLAIN ANALYZE lauset. Sellisel juhul lause täidetakse, kasutajale tulemust ei näidata, kuid kasutaja näeb lause täitmisplaani (protseduuri, mille alusel andmebaasisüsteem lause täidab) ja täitmise aega.Kõigil kolmel lausel oli täitmisplaan erinev. Kõige kiiremini täideti lahendus 1 - 227 ms. Täitmiseks ei kasutatud indeksit. Andmebaasisüsteem vaatas järjest läbi kõik tabeli Person read ja iga rea korral vaatas ridu tabelist Health_care_visit, kuni leidis vaste.Täitmiskiiruselt järgmine oli lahendus 4 - 267 ms. Täitmiseks ei kasutatud indeksit. Alampäringu täitmiseks loeti paralleelprotsesside poolt tabeli Health_care visit ridu ja kordused eemaldati sorteerimist kasutades. Saadud tabel ühendati tabeliga Person kasutades räsiväärtuste arvutamisel põhinevat algoritmi (hash join).Täitmiskiiruselt järgmine oli lahendus 3 - 588 ms. Täitmiseks ei kasutatud indeksit. Andmebaasisüsteem ühendas tabelid Person ja Health_care visit kasutades räsiväärtuste arvutamisel põhinevat algoritmi (hash join).Kõige aeglasem oli lahendus 2 - 688 ms. Täitmiseks kasutati indeksit. Andmebaasisüsteem vaatas järjest läbi kõik tabeli Person read ja iga rea korral loendas indeksi alusel kokku tabelis Health_care_visit olevate seotud ridade arvu.Mõned üldised järeldused: SQL ülesandele on tüüpiliselt mitu erinevat vastust. Erinevate lahenduste täitmiskiirused võivad olla erinevad. Andmebaasisüsteem otsustab ise, millal andmebaasis loodud indekseid päringute täitmiseks kasutada ja indeksi kasutamine ei pruugi alati olla kõige kiirem viis andmete ülesleidmiseks. ## Küsimus: Kuidas teistes andmebaasisüsteemides realiseerida PostgreSQLi FILTER predikaati, mida saab kasutada koos kokkuvõttefunktsiooniga? **Vastus:** PostgreSQLis saab kokkuvõttefunktsioonidega (nt Count, Min, Max, Sum, Avg) koos kasutada FILTER klauslit, et piirata ridu, mis lähevad kokkuvõttefunktsiooni tulemuse arvutamisel sisendiks. See võimaldab ühe ja sama lausega küsida samast tabelist koondtulemusi erinevatele tingimustele vastavate ridade põhjal.Oletame, et SQL-andmebaasis on tabel Hotell:Hotell(hotelli_nr, nimi, linn)Primaarvõti(hotelli_nr)Ülesandeks oleks leida sama lausega Tallinnas olevate hotellide arv ja Tartus olevate hotellide arv.PostgreSQLSELECT Count(*) FILTER (WHERE linn='Tallinn') AS tallinna_hotellide_arv,Count(*) FILTER (WHERE linn='Tartu') AS tartu_hotellide_arvFROM Hotell;Alternatiivsed lahendused põhinevad Count funktsiooni omadusel, et Count(<avaldis>) loendab vaid ridu, kus avaldise arvutamise tulemus ei ole NULL.MS Access SELECT Count(iif(linn='Tallinn',linn,NULL)) AS tallinna_hotellide_arv, Count(iif(linn='Tartu',linn,NULL)) AS tartu_hotellide_arv FROM Hotell;iif funktsioonil on kolm parameetrit - esimese oodatav väärtus on kontrollitav tingimus, teise oodatav väärtus on funktsiooni tulemus, kui tingimuse kontrolli tulemus on TRUE, kolmanda oodatav väärtus on funktsiooni tulemus, kui tingimuse kontrolli tulemus on FALSE. PostgreSQL (ilma FILTER kasutuseta) SELECT Count(CASE WHEN linn='Tallinn' THEN linn ELSE NULL END) AS tallinna_hotellide_arv, Count(CASE WHEN linn='Tartu' THEN linn ELSE NULL END) AS tartu_hotellide_arv FROM Hotell;Kasutatakse CASE avaldist. ## Küsimus: Kuidas tuleb erinevates andmebaasisüsteemides esitada tekstilisi väärtuseid? **Vastus:** SQL standard näeb ette, et väärtus peab olema ühekordsete ülakomade e apostroofide vahel ('tekst'). Jutumärkidesse võib panna andmebaasiobjektide nimesid e identifikaatoreid ("tekst").Kuidas käituvad erinevad andmebaasisüsteemid? Oracle Database 23ai Free - apostroofid ('tekst')Microsoft SQL Server 2022 - apostroofid või jutumärgid ('tekst', "tekst")MySQL 8 (vaikimisi) - apostroofid või jutumärgid ('tekst', "tekst")MySQL 8 (režiimis ansi) - apostroofid ('tekst')  PostgreSQL 16 - apostroofid ('tekst') SQL Lite 3.27.2 - apostroofid või jutumärgid ('tekst', "tekst")MariaDB 10.7.8 - apostroofid või jutumärgid ('tekst', "tekst")MS Access 2019 - apostroofid või jutumärgid ('tekst', "tekst")MySQLis saab sessiooni piires SQL lausete täitmisse režiimi muuta lausega: SET SESSION sql_mode = 'ansi'; ## Küsimus: Kuidas töötavad SQLis tingimused IN ja NOT IN? **Vastus:** Oletame, et meil on sellise kontseptuaalse struktuuriga andmebaas:[Hotell]-1------------0..*-[Reserveerimine]Ülesanne: Leia reserveerimised, mis on tehtud Tallinna linnas olevas hotellis. SELECT *FROM ReserveerimineWHERE hotelli_nr IN (SELECT hotelli_nrFROM HotellWHERE linn = 'Tallinn' ); Sulgudes oleva alampäringuga leitakse hotellide numbrid, mille korral on täidetud tingimus linn = 'Tallinn'. Tulemuseks on hulk (1,2,8). Iga rea korral tabelist Reserveerimine leitakse sellest reast hotelli number ja kontrollitakse, kas see number sisaldub alampäringuga leitud hulgas. Näiteks reserveerimisel hotellis 3 kontrollitakse: Kas on tõsi, et väärtus 3 sisaldub hulgas (1,2,8). Vastus - ei ole tõsi. Järelikult sellise hotelli numbriga reserveerimine ei ole tulemuses. Näiteks reserveerimisel hotellis 2 kontrollitakse:Kas on tõsi, et väärtus 2 sisaldub hulgas (1,2,8). Vastus - jah, on tõsi. Järelikult sellise hotelli numbriga reserveerimine on tulemuses.Ülesanne: Leia reserveerimised, mis ei ole tehtud Tallinna linnas olevas hotellis. SELECT *FROM ReserveerimineWHERE hotelli_nr NOT IN (SELECT hotelli_nrFROM HotellWHERE linn = 'Tallinn'); Sulgudes oleva alampäringuga leitakse hotellide numbrid, mille korral on täidetud tingimus linn = 'Tallinn' . Tulemuseks on hulk (1,2,8). Iga rea korral tabelist Reserveerimine leitakse sellest reast hotelli number ja kontrollitakse, kas see number ei sisaldu alampäringuga leitud hulgas. Näiteks reserveerimisel hotellis 3 kontrollitakse:Kas on tõsi, et väärtus 3 ei sisaldu hulgas (1,2,8). Vastus - jah, on tõsi. Järelikult sellise hotelli numbriga reserveerimine on tulemuses. Näiteks reserveerimisel hotellis 2 kontrollitakse: Kas on tõsi, et väärtus 2 ei sisaldu hulgas (1,2,8). Vastus - ei ole tõsi. Järelikult sellise hotelli numbriga reserveerimine ei ole tulemuses.Juhul, kui alampäring võib tagastada NULLi, siis tuleks kirjutada: SELECT *FROM ReserveerimineWHERE hotelli_nr NOT IN (SELECT hotelli_nrFROM HotellWHERE linn = 'Tallinn' AND hotelli_nr IS NOT NULL);Ilma selleta juhtuks nii, et kui alampäring tagastaks NULLi, siis poleks põhipäringu tulemuses ühtegi rida. Miks see nii juhtub? Vaatame järgmist näidet. Sulgudes oleva alampäringuga leitakse hotellide numbrid, mille korral on täidetud tingimus linn = 'Tallinn' . Tulemuseks on hulk (1,2,8, NULL). Iga rea korral tabelist Reserveerimine leitakse sellest reast hotelli number ja kontrollitakse kas see number ei sisaldu alampäringuga leitud hulgas. Näiteks reserveerimisel hotellis 3 kontrollitakse: Kas on tõsi, et väärtus 3 ei sisaldu hulgas (1,2,8, NULL). Vastus - ei tea. NULL on nagu suletud karp, mille sisse ei näe. Võibolla on seal karbis 3 võibolla mitte. Järelikult sellise hotelli numbriga reserveerimine ei ole tulemuses. Näiteks reserveerimisel hotellis 2 kontrollitakse: Kas on tõsi, et väärtus 2 ei ole hulgas (1,2,8, NULL). Vastus - ei ole tõsi. Järelikult sellise hotelli numbriga reserveerimine ei ole tulemuses. Antud juhul polnud seda tingimust (hotelli_nr IS NOT NULL) tingimata vaja kirja panna (ehki kirjapanek poleks ka viga), sest hotelli_nr tabelis Hotell on primaarvõti ja seega ka kohustuslik veerg. ## Küsimus: Mida tähendab, et kirjutage INSERT lause nii, et see poleks tundlik veergude järjekorra muutmise suhtes? **Vastus:** Halb: INSERT INTO Isik VALUES ('39107070123', 'Mets'); Kui tabelis Isik muutub veergude järjekord, siis tuleb seda lauset muuta. Vastasel juhul võib lisamine ebaõnnestuda, või mis veel hullem, lisamine õnnestub, kuid väärtused lähevad valedesse väljadesse. Lause ei kirjelda esitatud väärtuste tähendust. Palju parem: INSERT INTO Isik (isikukood, perenimi) VALUES ('39107070123', 'Mets'); Kui tabelis Isik muutub veergude järjekord, siis ei tule seda lauset muuta. Halb: INSERT INTO Magamine_koopia SELECT * FROM Magamine; Lisaks eelnimetatud probleemidele ei näe koodi lugeja, millised veerud ja millises järjekorras alampäringu poolt tagastatakse. Palju parem: INSERT INTO Magamine_koopia (ase_id, algus, magaja_id, kestus, kommentaar)SELECT ase_id, algus, magaja_id, kestus, kommentaar FROM Magamine; ## Küsimus: Mida tähendab ülesandes lause "tabelite ühendamisel realiseerige joini tingimused WHERE klausli abil" või "tabelite ühendamise (joini) tingimused kirjutada WHERE klauslisse"? **Vastus:** Teatavasti saab tabelite ühendamiseks kasutada nii vanemat süntaksi: SELECT Oppimine.*, Aine.nimetus AS aine_nimetus FROM Oppimine, Aine WHERE Oppimine.aine=Aine.aine_kood; kui "uuemat" süntaksi: SELECT Oppimine.*, Aine.nimetus AS aine_nimetus FROM Oppimine INNER JOIN Aine ON Oppimine.aine=Aine.aine_kood; "Uuem" on jutumärkides, sest SQL standard näeb seda ette juba 1992. aasta redaktsioonist/versioonist. Mõlemaid kirjaviise peaks oskama. Näiteks võivad SQL lausete generaatorid genereerida just vanema süntaksiga lauseid. Siis peaks sellest aru saama. Kui ülesandes on öeldud, et "tabelite ühendamisel realiseerige joini tingimused WHERE klausli abil", siis see tähendab, et juhul kui kasutate ühendamisoperatsiooni, siis tuleb kasutada vanemat süntaksi. Kui lahendate ülesande ilma ühendamisoperatsioonideta (nt kasutades alampäringuid), siis ignoreerige seda juhist. ## Küsimus: Miks mõnikord peab koos kokkuvõttefunktsiooni kasutamisega kasutama GROUP BY klauslit ja mõnikord ei pea? **Vastus:** Järgnevad koodinäited põhinevad enamasti MS Accessil, kuid kirjeldatud põhimõtted kehtivad SQLis üldiselt.Oletame, et ülesandeks on leida iga aasta kohta, millal on alanud mõni reserveerimine, sellel aastal alanud reserveerimiste arv. SELECT Year(alguse_aeg) AS aasta, Count(*) AS arv FROM Reserveerimine;   See lause on vale, sest puudub eeskiri (GROUP BY klauslis), kuidas moodustada ridade rühmad, milles olevad read tuleb kokku loendada. Kuna SELECT klauslis on veerg, millele kokkuvõttefunktsiooni ei rakendata (aasta), siis ei saa eeldada, et kõik tabeli read on selleks paigutatud ühte rühma. Teiste sõnadega, kui SELECT klauslis on kokkuvõttefunktsioonide väljakutseid + üks või mitu veergu, millele ei rakendu kokkuvõttefunktsioon, siis peavad kõik need veerud olema ka nimetatud GROUP BY klauslis.Õige oleks SELECT Year(alguse_aeg) AS aasta, Count(*) AS arv FROM Reserveerimine GROUP BY Year(alguse_aeg); PostgreSQLis saab GROUP BY klasuslis kasutada ka veerule SELECT klauslis määratud aliast. SELECT Extract(year from alguse_aeg) AS aasta, Count(*) AS arv  FROM Reserveerimine  GROUP BY aasta;  Kurioosumina võib välja tuua, et populaarset andmebaasisüsteemi MySQL saab panna tööle erinevates režiimides, sh sellises, mis lubab käivitada algselt välja toodud lauset. Vaikimisi seda lauset MySQL 8-s ei täideta. SET SESSION sql_mode = 'traditional';   SELECT Year(alguse_aeg) AS aasta, Count(*) AS arv FROM Reserveerimine;Lause täidetakse. Tulemuseks on tabel, kus on üks rida ja kaks veergu. Väljas aasta on üks (esimene?) aasta , väljas arv on kõikide reserveerimiste koguarv.   SET SESSION sql_mode = 'ansi';   SELECT Year(alguse_aeg) AS aasta, Count(*) AS arv FROM Reserveerimine; Lauset ei täideta.Järgnevas lauses aga pole GROUP BY klauslit vaja, sest KÕIKIDESSE tulemusse kuuluvatesse veergudesse leitakse andmed kokkuvõttefunktsiooniga. Kuna SELECT klauslis pole ühtegi kokkuvõttefunktsiooniga katmata veergu, siis saab eeldada, et ridade rühma, mille järgi koondväärtused leitakse, moodustavad kõik tabeli read. SELECT Round(Avg(lopu_aeg - alguse_aeg),2) AS avg_pikkus, Min(lopu_aeg - alguse_aeg) AS min_pikkus, Max(lopu_aeg - alguse_aeg) AS max_pikkus FROM Reserveerimine AS R, Hotell AS H WHERE R.hotelli_nr = H.hotelli_nr AND linn = 'Tallinn' AND lopu_aeg - alguse_aeg > 2   Eelnev näide on samaväärne selle lausega - rühmitamine e grupeerimine tühjal veergude hulgal e kõik tabeli read kuuluvad ühte rühma. Sellist süntaksi SQL standard lubab, aga MS Access ei toeta.   SELECT Round(Avg(lopu_aeg - alguse_aeg),2) AS avg_pikkus, Min(lopu_aeg - alguse_aeg) AS min_pikkus, Max(lopu_aeg - alguse_aeg) AS max_pikkus FROM Reserveerimine AS R, Hotell AS H WHERE R.hotelli_nr = H.hotelli_nr AND linn = 'Tallinn' AND lopu_aeg - alguse_aeg > 2 GROUP BY (); ## Küsimus: Miks õppida SQLi? **Vastus:** SQLis kui keeles võiks kahtlemata olla palju asju teistmoodi ja paremini (vt "Andmebaasid I" teema 6 materjale). Arendajad kiristavad mõnikord SQLi peale hambaid ja kiruvad, kuid ikkagi kasutavad seda. Miks nad seda teevad? 2024. aasta märtsi seisuga on kümne kõige populaarsema andmebaasisüsteemi hulgas seitsmes kasutusel SQL. IEEE Spectrumi 2024. aasta programmeerimiskeelte populaarsuse indeksis oli SQL populaarsuselt kuuendal kohal ja tööandja poolt oodatud keelte hulgas esikohal!IEEE Spectrumi 2023. aasta programmeerimiskeelte populaarsuse indeksis oli SQL populaarsuselt seitsmendal kohal ja tööandja poolt oodatud keelte hulgas esikohal! IEEE Spectrumi 2022. aasta programmeerimiskeelte populaarsuse indeksis oli SQL populaarsuselt kuuendal kohal ja tööandja poolt oodatud keelte hulgas esikohal! SQL on oma positsiooni selles pingereas tublisti parandanud, sest 2021. aasta uuringu kohaselt oli SQL populaarsuselt 15-s ja tööandja oodatult keelte hulgas 6-s. Tööandjad tahavad töötajatelt lisaks muude keelte oskustele kindlasti ka SQLi oskust, sest programmid töötavad andmetega ja väga-väga sageli on andmed SQL-andmebaasides. Seega puutub mistahes valdkonnas ja keeles programmeerija kindlasti kokku ka SQLiga. SQLi leiab kasutust suurandmetega töötamisel, andmeteaduses, masinõppes. SQL on pika ajalooga, küps keel, mille kasutamiseks mõeldud programmide hulk on tohutu ning mis on suutnud uute IT-trendidega alati väga hästi kohanduda. SIIN on artikkel, mis kirjutab SQL populaarsuse tõusust. Artikkel lõpeb tõdemusega: "Igal dekaadil tekib mõni uus ülehaibitud andmebaasi tehnoloogia, mille pooldajad väidavad, et SQL on kohutav, aeglane või ebapraktiline. Aja jooksul võidab terve mõistus ja saadakse aru, et SQL on hea idee ning kõik jätkavad selle kasutamist."Sellest tulenevalt on lisaks arendajatele SQL hädavajalik keel andmeteadlastele. Nad peavad kuidagi enda uurimismaterjalile e andmetele ligi pääsema ja sageli on selleks vaja kasutada SQLi. Näiteks üleeuroopalisel suurandmete töötlemise maratonil 2017. aastal kolmanda koha saanud võistkonna liige kommenteeris, et sisendandmed olid SQL-andmebaasis, hierarhiatena, Adjacency List (külgnevusnimistu) mudeli alusel. Ta ütles SQLi kasutamise kohta: "asi kisub vist hoopis sql hackathoniks. /.../ eeltöötlus ja andmebaasides ringirändamine ja avastamine on 80-90% ajast." Osalejatele anti vahendite valik vabaks. Eesti võistkond otsustas esmajoones kasutada PostgreSQLi (populaarne ja väga võimalusterohke avatud lähtekoodiga serveri andmebaasisüsteem, kus saab kasutada SQLi). See tähendab, et andmed laaditi PostgreSQLi tabelitesse ja otsiti vastuseid küsimustele kasutades SQL päringuid. Ainult siis, kui PostgreSQL jäi töökiiruse mõttes hätta ("5+ JOINiga päringutel kulus tulemusteni üle 15 minuti (võtmeveergude indekseerimised jm. "hügieenilised" tegevused olid eelnevalt tehtud)"), laaditi andmed päringu tegemiseks Hadoop klastrisse. Ka seal läks vaja SQLi oskust, sest läbi Hive pakutava liidese saab klastris olevate andmete poole pöörduda kasutades SQL-laadset keelt HiveQL. PostgreSQL päringuid polnud vaja palju muuta, kuid töökiiru paranes kuni kümme korda. Samas kommenteeris üks võistkonna liikmetest, et "Kui Hackathlonil poleks ajapiirangut olnud, siis selle andmestiku puhul oleks saanud ka ilma Hiveta." Samuti kasutati hajusarvutuste platvormi Spark, kuid ka selle kasutamiseks on kasulik SQLi tunda. Arvatavasti olete kuulnud NoSQL (kes interpreteerib seda kui "No to SQL", kes aga "Not only SQL") süsteemidest. Need süsteemid sõitsid 2010ndatel suure hurraaga turule, kui järjekordsed printsid valgel hobusel, mis pidid andmebaaside maailma kõigist hädadest päästma. Eriti alguses vastandusid need (nagu nimigi viitab) täielikult SQLile. Nüüdseks aga on üha rohkemates sellistes süsteemides kasutusele võetud kõrgtaseme (deklaratiivne) päringukeel, mis kangesti meenutab SQLi. Irvhambad on hakanud NoSQLi kutsuma tänu sellele kui "Not yet SQL". Nii et kui "päris" SQLi oskate, siis pole keeruline ka neid uusi keeli suhu saada. Näited: CQL (Cassandra Query Language, andmebaasikeel veergude perekondade põhises andmebaasisüsteemis Cassandra). N1QL (päringukeel dokumendipõhises andmebaasisüsteemis Couchbase). SPARQL (standardiseeritud päringukeel andmebaasisüsteemidele, mis põhinevad RDF (Resource Description Framework, ressursside kirjeldamise karkass) andmemudelil). PGQL (katse pakkuda graafipõhistele süsteemidele välja ühtlustatud SQLi-laadset päringukeelt). Rahvusvaheline standardimisorganisatsioon ISO (International Organization for Standardization) alustas graafipõhise andmebaasikeele standardi väljatöötamisega. Uus keel hakkab põhinema SQLil ja selle edul ning andmete otsimise lause peaks meenutama SQL SELECT lauset. Cypher (päringukeel graafipõhises andmebaasisüsteemis Neo4J). Carnegie Melloni ülikooli andmebaaside professor Andy Pavlo ütles 2021. aastal, et SQLi puudus hoiab Redise (ühe tuntud NoSQL süsteemi) kasutajaid tagasi, sest iga suurem ja kasutatavam NoSQL süsteem, v.a MongoDB ja FaunaDB, toetab mingit SQLi varianti. "SQL oli maailmas enne teie sündi ja on siin ka siis, kui te surete". (artikkel) (video) ## Küsimus: Millal kasutada SQLis tabelite ühendamist ja millal alampäringut? **Vastus:** SQL on keeleliselt liiane, mis tähendab, et aastate jooksul on SQL keelt täiendatud aina uute keelekonstruktsioonidega ja ühte ning sama ülesannet saab seetõttu lahendada paljudel erinevatel viisidel. Mingis mõttes on see nagu inimkeeles, kus on ka palju sünonüüme ning ühte ja sama mõtet saab avaldada erinevatel viisidel. Mõni väljendusviis võib olla sobivam ühes kontekstis ja mõni teises.Oletame, et meil on sellise kontseptuaalse struktuuriga andmebaas:[Hotell]-1------------0..*-[Reserveerimine]Ülesanne: Leia reserveerimised, mis on tehtud Tallinna hotellides.Lahendus 1: SELECT *FROM ReserveerimineWHERE hotelli_nr IN (SELECT hotelli_nrFROM HotellWHERE linn='Tallinn');Lahendus 2;SELECT Reserveerimine.*FROM Reserveerimine INNER JOIN Hotell ON Reserveerimine.hotelli_nr=Hotell.hotelli_nrWHERE Hotell.linn='Tallinn';Millal kindlasti kasutada lahendust 2? Päringu tulemuses on vaja väljastada andmeid tabelist Hotell. Väljastatavad andmed määratakse ära lause SELECT klauslis. Päringu tulemuses on vaja väljastada andmeid mõnest muust tabelist kui Hotell, kuid selle tabelini jõudmiseks tuleb see ühendada tabeliga Hotell. Päringu tulemust on vaja sorteerida andmete järgi, mis on tabelis Hotell või mõnes sellises tabelis milleni pääseb tabelit Hotell ühendades. Sorteerimiseeskiri oleks lause ORDER BY klauslis. Päringu tulemusse on vaja arvutada koondandmeid andmete põhjal, mis on tabelis Hotell või mõnes sellises tabelis milleni pääseb tabelit Hotell ühendades. Koondandmete arvutamiseks vajaliku grupeerimise eeskiri oleks lause GROUP BY klauslis. Ülesanne: Kustuta selliste reserveerimiste kommentaarid, mis on tehtud Tallinna hotellidesLahendus 1:UPDATEReserveerimine SET kommentaar=NULLWHERE hotelli_nr IN (SELECT hotelli_nrFROM HotellWHERE linn='Tallinn');Miks mitte kasutada ühendamist?Tõepoolest, see oleks võimalik, kuid erinevate andmebaasisüsteemide SQL dialektides e mägimurrakutes oleks see lause erinev. Seega kood on vähem porditav e erinevate süsteemide vahel ülekantav.Lahendus 2 MS Accessis: UPDATE Reserveerimine INNER JOIN Hotell ON Reserveerimine.hotelli_nr = Hotell.hotelli_nr SET Reserveerimine.kommentaar = Null WHERE Hotell.linn='Tallinn'; Lahendus 2 PostgreSQLis UPDATE Reserveerimine SET kommentaar=NULL FROM Hotell WHERE Reserveerimine.hotelli_nr=Hotell.hotelli_nr AND Hotell.linn='Tallinn';NB! Veel üks võimalik lahendus (nii PostgreSQLis kui MS Accessis): UPDATE Reserveerimine AS R SET kommentaar = NULL WHERE EXISTS (SELECT * FROM Hotell, Reserveerimine AS R2 WHERE Hotell.hotelli_nr=R2.hotelli_nr AND linn='Tallinn' AND R.hotelli_nr=R2.hotelli_nr AND R.ruumi_nr=R2.ruumi_nr AND R.kylalise_nr=R2.kylalise_nr AND R.alguse_aeg=R2.alguse_aeg );UPDATE  lause WHERE klauslis on tingimus (EXISTS (korreleeruv alampäring)), mille täidetust saab kontrollida. Alampäringu viimased neli tingimust seovad alampäringu ja põhilause ning arvestavad sellega, et reserveerimise unikaalne identifikaator on hotelli_nr, ruumi_nr, külalise_nr ja alguse_aeg kombinatsioon. Kuna nii põhilauses kui alampäringus viidatakse samale tabelile (Reserveerimine), siis selleks, et käsitleda neid lause kontekstis justkui kahte erinevat tabelit kasutatakse aliasi (R ja R2). Ülesanne: Kustuta reserveerimised, mis on tehtud Tallinna hotellidesLahendus 1:DELETE FROM ReserveerimineWHERE hotelli_nr IN (SELECT hotelli_nrFROM HotellWHERE linn='Tallinn');Miks mitte kasutada ühendamist?Tõepoolest, see oleks võimalik, kuid erinevate andmebaasisüsteemide SQL dialektides e mägimurrakutes oleks see lause erinev. Seega kood on vähem porditav e erinevate süsteemide vahel ülekantav.Lahendus 2 MS Accessis: DELETE Reserveerimine.* FROM Reserveerimine INNER JOIN Hotell ON Reserveerimine.hotelli_nr = Hotell.hotelli_nr WHERE Hotell.linn='Tallinn'; Lahendus 2 PostgreSQLis DELETE FROM Reserveerimine USING Hotell WHERE Reserveerimine.hotelli_nr=Hotell.hotelli_nr AND Hotell.linn='Tallinn';   NB! Veel üks võimalik lahendus (nii PostgreSQLis kui MS Accessis): DELETE FROM Reserveerimine AS R WHERE EXISTS (SELECT * FROM Hotell, Reserveerimine AS R2 WHERE Hotell.hotelli_nr=R2.hotelli_nr AND linn='Tallinn' AND R.hotelli_nr=R2.hotelli_nr AND R.ruumi_nr=R2.ruumi_nr AND R.kylalise_nr=R2.kylalise_nr AND R.alguse_aeg=R2.alguse_aeg );DELETE lause WHERE klauslis on tingimus (EXISTS (korreleeruv alampäring)), mille täidetust saab kontrollida. Alampäringu viimased neli tingimust seovad alampäringu ja põhilause ning arvestavad sellega, et reserveerimise unikaalne identifikaator on hotelli_nr, ruumi_nr, külalise_nr ja alguse_aeg kombinatsioon. Kuna nii põhilauses kui alampäringus viidatakse samale tabelile (Reserveerimine), siis selleks, et käsitleda neid lause kontekstis justkui kahte erinevat tabelit kasutatakse aliasi (R ja R2). ## Küsimus: Milline on tüüpiline viga LIMIT klausli kasutamisel? **Vastus:** LIMIT klauslit ei saa kasutada MS Accessis, kuid saab kasutada mitmes teises SQL andmebaasisüsteemis. LIMIT n võimaldab päringu tulemusest väljastada esimesed n rida. SQL standard ei näe samuti ette LIMIT klauslit. Samas saab SQL standardi kohaselt kasutada FETCH FIRST n ROWS ONLY klauslit, mis teeb sama välja kui LIMIT.Üks ülesannete klass, kus LIMIT'it ebaõigelt kasutatakse, on kõigi nende ühte tüüpi olemite leidmine, millel mingi tunnuse väärtus on kõige suurem või kõige väiksem. Leia ametid, millel on kõige suurem min_palk väärtus.   Vale. Sorteerin read minimaalse palga jälgi kahanevalt ja siis valin ridade hulgast kõige esimese.   SELECT amet_kood, min_palk FROM Amet ORDER BY min_palk DESC LIMIT 1; SELECT *FROM AmetORDER BY palk DESCFETCH FIRST 1 ROWS ONLY; Õige. Leian ametid, mille minimaalne palk on kõigi minimaalsete palkade hulgast kõige suurem.   SELECT amet_kood, min_palk FROM Amet WHERE min_palk=(SELECT Max(min_palk) AS m FROM Amet); Esimene lahendus on vale, sest võib olla mitu ametit, millel on ühtemoodi kõige suurem palk. Esimene lahendus leiab ainult ühe sellise ameti (millise, on ennustamatu). Teine leiab kõik sellised ametid.MS Accessis oleks õige lahendus ka selline. TOP predikaat leiab minimaalse palga järgi kahanevalt sorteeritud ametite hulgast kõige esimese (e kõige suurema) minimaalse palgaga ametid. SELECT TOP 1 amet_kood, min_palk FROM Amet ORDER BY min_palk DESC;MS SQL Serveris tuleks sama tulemuse saavutamiseks kasutada TOP ... WITH TIES. SELECT TOP 1 WITH TIES amet_kood, min_palk FROM Amet ORDER BY min_palk DESC;Samuti annab õige tulemuse see päring, mis töötab näiteks PostgreSQLis. WITH TIES tagab, et vajadusel on päringu tulemuses rohkem kui üks rida.SELECT *FROM AmetORDER BY palk DESCFETCH FIRST 1 ROWS WITH TIES;Oluline on üle rõhutada, et TOP ja FETCH FIRST 1 ROWS WITH TIES lahendused eeldavad ridade sorteerimist - muidu on tulemus juhuslik rida. ## Küsimus: Milline võiks olla üldine SQL SELECT lausete koostamise strateegia? **Vastus:** Olen kunagi midagi kirjutanud SQL SELECT lausete koostamise üldise strateegia/metoodika kohta. See põhineb paljuski matemaatik Georg Pólya üldist probleemilahenduse strateegiat kirjeldaval raamatul Kuidas seda lahendada. Huvilised leiavad kirjutise lisamaterjalide lehelt (kasutajanimi: SIS2 parool: SIS2) SIIT. ## Küsimus: Milliseid materjale soovitate SQLi õppimisega alles alustanule, kes peab lähiajal töö- või praktikakoha saamise intervjuul vastama SQLi puudutavatele küsimustele? **Vastus:** 46 tööintervjuu küsimust SQLi kohta andmeteadlasele. Sealt leiate ka viite tegelikele küsimustele ja õigetele vastustele. https://www.datasciencecentral.com/46-questions-on-sql-to-test-a-data-science-professional-skilltest/   SQLi tööintervjuu küsimusi, millest osad on ka avalikud: https://www.testdome.com/tests/sql-online-test/12   Võibolla tasub sirvida eelmise aasta "Andmebaasid I" slaide SQLi kohta (kasutajanimi: SIS2 ja parool: SIS2). Kui kõiki ei jõua, siis vaadake slaide: tüüpiliste vigade kohta SQL lausetes, ebaotstarbekate SQL lausete kohta. Teadusartikkel tüüpiliste vigade kohta SQL lausetes: Brass, S., Goldberg, C., 2006. Semantic errors in SQL queries: A quite complete list. Journal of Systems and Software, 79(5), 630-644. [WWW] http://dbs.informatik.uni-halle.de/sqllint/jss06.pdf Äkki on abi ka järgnevast. Üldine strateegia andmete otsimise ülesannete lahendamiseks. Kui olete SQLiga rohkem tuttav, siis "trikke" selle kohta, kuidas otsida andmeid, mida andmebaasis ei ole. Muide, IEEE Spectrum 2022. aasta programmeerimiskeelte populaarsuse pingereas oli SQL 6. kohal, 2023. aastal populaarsuse pingereas oli SQL 7. kohal ning 2024. aasta populaarsuse pingereas oli SQL jälle 6. kohal. Kõigil nendel aastatel oli see keel tööandjate ootuse osas esikohal. Tööandjate ootus on, et lisaks muudele keeltele osataks kindlasti ka SQLi. ## Küsimus: Milliseid soovitusi annavad teadusuuringut selles osas, kuidas suurte keelemudelite abil SQL koodi genereerida? **Vastus:** Chang ja Lussier (2023) katsetavad erinevaid võimalusi ja annavad soovitusi suurte keelemudelite promptimiseks e viipade koostamiseks, et saada nendelt SQL koodi. Keelemudelile võiks SQL koodi genereerimiseks anda ette: Näiteülesanded sõnalise küsimuse ning lahenduseks oleva SQL koodi paaridena. Päringuid, kus näiteülesandeid ette ei anta nimetatakse zero-shot text-to-SQL. Päringuid, kus antakse ette mõned näiteülesanded nimetatakse few-shot text-to-SQL. Andmebaasi struktuuri kirjeldus kas tabelite loomise lausetena (CREATE TABLE) või struktuuri kirjeldusena kus on esitatud tabeli nimi, veergude nimed, võtmed ja seosed. Iga tabeli kohta kolm rida näiteandmetena, mille võib esitada näiteks komadega eraldatud nimekirjana, mille ees on nende andmete leidmiseks kasutatud päring (kujul: SELECT * FROM Tabel LIMIT 3) või siis esitada näiteandmed INSERT lausetena. Chang ja Lussier (2023) soovitavad esitada iga veeru kohta kolm erinevat näiteväärtust ja selle ees päringu nende andmete leidmiseks (kujul: SELECT DISTINCT veerg FROM Tabel LIMIT 3). Inimkeelne küsimus. Uuring näitas, et vastuse täpsuse jaoks oleks abi järgnevast. Etteantud teksti normaliseerimine (v.a andmeväärtuste näited). Normaliseerimine tähendab antud teksti esitamist väiketähtedena ja SQL lausetes treppimisest loobumist. See vähendab keelemudelile sisendiks mineva teksti hulka (võib olla piirang prompti pikkusele). Andmebaasi kirjelduses tabelite võtmete (PRIMARY KEY ja UNIQUE kitsendused) ja tabelite vaheliste seoste esitamisest (FOREIGN KEY kitsendused). Mõõdukast hulgast (nt kuni 15) näiteülesannete ja vastuste (SQL lausete) paaridest. Siin võib piirangu seada keelemudelist sõltuv küsimuse lubatud maksimumpikkus. Näiteandmete esitamisest kujul päring + tulemuseks olevad read. Rohkem pole alati parem – Rajkumar et al. (2022) toob välja, et kolm rida näiteandmeid oleks optimaalne – ridade arvu suurenemisel hakkab täpsus vähenema. Näiteülesanded võiksid olla sama andmebaasi põhjal, mille põhjal soovitakse enda ülesande lahendust. Andes näitena ette erinevaid andmebaase ning nendel põhinevaid näiteülesandeid hakkas mingist hetkest vastuste täpsus vähenema. Võimalik, et põhjuseks oli prompti liigne pikkus, sest uuritud mudelite korral saadi parimad tulemused umbes 5500 märgi pikkuse promptiga. Chang ja Lussier (2023) väidavad ChatGPT ja Codex näitel, et täpsus hakkab vähenema kui keelemudelile antud sisendi pikkus ületab 70% maksimaalselt lubatust. Rajkumar et al. (2022) järeldasid juba 2022. aastal, et suured keelemudelid (katsetati prorgammeerijatele mõeldud keelemudeli Codex põhjal) on inimkeelest SQLi genereerimisel tugevad tegijad. Loomulikult on oluline küsimuse (prompti) sõnastamine. Prompti kaudu näidete esitamine on tulemuste täpsuselt võrreldav väiksemate keelemudelite peenhäälestamise järel saadud tulemustega. Kui esitada ainult küsimus (ilma täiendava infota) on täpsus 8.3%. Kui lisaks esitati skeemi kirjeldus tõusis täpsus 59.9%. Kui tulemuses esitati tabelite kohta ka SELECT lause + kolm rida näiteandmeid kasvas tulemuse täpsus 67%-ni.Veel soovitusi: Kasutage prompti e viiba alguses sõna "Please" (Palun). Keelemudel ennustab, mis tekst peaks sisestatud tekstile jälgima. Viisakale tekstile peaks järgnema viisakam järg ning see on tavaliselt täpsem. Öelge küsimuses, kelle rollis Te küsimust esitate (nt andmebaasi programmeerija). Öelge, mis rollis peaks programm Teile vastama (nt andmebaaside spetsialistina). Ingliskeelne küsimus võib anda veidi täpsema vastuse, kuid üldiselt saavad keelemudelid ka eesti keelega hästi hakkama. Vastuse esitamisel failina (nt testandmete genereerimisel) võib tehisintellekt teha vea andmete faili tõstmisel. Lahenduseks võib olla paluda esitada vastus kopeeritaval kujul, st mitte failina. Testandmete genereerimiseks võib paluda tehisintellektil genereerida kood, mis neid andmeid genereerib (sobivas programmeerimiskeeles, mis tuleb viibas ette öelda), selle asemel, et paluda andmeid genereerida ja väljastada. **Märksõnad:** OpenAI, ChatGPT, LLM, suur keelemudel, tehisintellekt, AI, TI, prompt, viip ## Küsimus: Millistes SQL-andmebaasisüsteemides saab kasutada SELECT lauset, kus puudub FROM klausel ning millistes ei saa? **Vastus:** Kasutasin katsetamiseks keskkondi DB Fiddle, SQL Fiddle ja db<>fiddle.Katsetan lauset:SELECT 'Tere maailm' AS vastus;Andmebaasisüsteemid jagunesid kaheks: SELECT lauses peab olema FROM klausel. Andmebaasisüsteemi juures on ka viide kasutatud lausele. IBM DB2 Developer-C 11.1 SELECT 'Tere maailm' AS vastus FROM SYSIBM.SYSDUMMY1; Saab ka võimaldada Dual tabeli kasutamist Firebird 4 SELECT 'Tere maailm' AS vastus FROM RDB$DATABASE; HSQLDB 1.8 (LibreOffice Base) Tabel tuleb ise luua SELECT lauses ei pea olema FROM klauslit. PostgreSQL 17 MySQL 9 SQLite 3.46 MariaDB 10.7 MS SQL Server 2022 Oracle 23ai Enne Oracle 23ai tuli kirjutada: SELECT 'Tere maailm' AS vastus FROM Dual; MS Access 2019 ## Küsimus: Millistes SQL-andmebaasisüsteemides saab kasutada SQL standardis ettenähtud skeemi INFORMATION_SCHEMA, milles on süsteemikataloogi tabelite põhjal loodud vaated ja millistes ei saa? **Vastus:** INFORMATION_SCHEMA on SQL standardis kirjeldatud skeem, mis sisaldab süsteemikataloogi tabelite põhjal loodud vaateid. Süsteemikataloogi tabelites on andmed andmebaasi kohta. Mõte on selles, et erinevate andmebaasisüsteemide andmebaasides on süsteemikataloogi tabelite struktuur erinev, kuid kasutada võiks saada ühesuguse struktuuriga vaateid, mis on nende tabelite põhjal loodud. Süsteemikataloogi tabelite ja vaadete põhjal saab täita SELECT lauseid nagu ka kõigi ülejäänud andmebaasi tabelite ja vaadete põhjal. Kasutasin katsetamiseks keskkondi DB Fiddle, SQL Fiddle ja db<>fiddle.Katsetan lauset:SELECT Count(*) AS arv FROM INFORMATION_SCHEMA.tables;Andmebaasisüsteemid jagunesid kaheks: INFORMATION_SCHEMA ei ole toetatud. Oracle 23ai IBM DB2 Developer-C 11.1 SQLite 3.46 Firebird 4 MS Access 2019 HSQLDB 1.8 (LibreOffice Base) INFORMATION_SCHEMA on toetatud. PostgreSQL 17 MySQL 9 MariaDB 10.7 MS SQL Server 2022 ## Küsimus: Mis probleem on (PostgreSQL näitel) veeru deklaratsiooniga: registr_aeg TIMESTAMP NOT NULL DEFAULT LOCALTIMESTAMP(0) **Vastus:** SELECT LOCALTIMESTAMP;   Tagastab hetke kuupäeva, kellaaja ja sekundi murdosad kuue koha täpsusega.   Funktsiooni väljakutses saab määrata, kui täpselt või kas üldse sekundi murdosasid soovitakse.   SELECT LOCALTIMESTAMP(0);   sekundi murdosasid ei tagasta.   Tüübi deklaratstioon TIMESTAMP - saab salvestada sekundi murdosad kuue koha täpsusega. Tüübi deklaratstioon TIMESTAMP(0) - sekundi murdosasid ei salvestata. Kaks probleemi: Ebaselge, mida andmebaasi tegija tegelikult soovis. Kaks võimalust: sekundi murdosasid ei soovita salvestada; see, et TIMESTAMP(0) asemel on TIMESTAMP, on tähelepanematus e "iluviga"; tegelikult soovitakse salvestada ka sekundi murdosasid, kuid tähelepanematusest on kirjutatud LOCALTIMESTAMP(0), mitte LOCALTIMESTAMP. Andmekvaliteet. on võimalik, et osad registreerimise ajad on vaikimisi väärtuse tõttu sekundi murdosadeta, kuid osad registreerimise ajad on kasutaja enese poolt sisestatud ja sekundi murdosadega. ## Küsimus: Mis vahe on MS Accessi SQL mägimurrakus DISTINCT ja DISTINCTROW määrangutel? **Vastus:** SQL standard kirjeldab DISTINCT, kuid mitte DISTINCTROW (st viimane on andmebaasisüsteemi-spetsiifiline leiutis). Leidke külaliste perenimed nii, et kordused on eemaldatud. Esitage perenimed suurtähtedega. Sorteerige päringu tulemuses perenimed tähestikulisele järjekorrale vastupidises järjekorras. Õige: SELECT DISTINCT Ucase(perenimi) AS perenimi FROM Külaline ORDER BY Ucase(perenimi) DESC; SELECT Ucase(perenimi) AS perenimi FROM Külaline GROUP BY perenimi ORDER BY Ucase(perenimi) DESC; Õpetlik on, et ORDER BY klauslisse tuleb kirjutada ORDER BY Ucase(perenimi) DESC, mitte ORDER BY perenimi DESC; Kuigi MS Access lubaks ORDER BY lauses kirjutada ka ORDER BY perenimi DESC, siis PostgreSQL ja Oracle tahavad ka seal funktsiooni poole pöördumist (NB! PostgreSQL ja Oracle andmebaasisüsteemides on see funktsioon nimega Upper, mitte Ucase). Pealegi on see ülesande mõttes loogilisem – sorteerida tuleks nende andmete alusel, mis kasutajale esitatakse. Kui ma ei taha ORDER BY klauslisse funktsiooni poole pöördumist kirjutada, siis võin vormistada lahenduse mitmeosaliselt, kus kõigepealt leitakse suurtähtedega erinevad perenimed ja siis sorteeritakse tulemust. SELECT perenimi FROM (SELECT DISTINCT Ucase(perenimi) AS perenimi FROM Külaline) AS erinevad_perenimed ORDER BY perenimi DESC; Vale: SELECT DISTINCTROW Ucase(perenimi) AS perenimi FROM Külaline ORDER BY perenimi DESC; DISTINCTROW ignoreeritakse, kui andmeid küsitakse vaid ühest tabelist või on vaja väljastada andmed kõikidest FROM klauslis nimetatud tabelite veergudest. Viide. Veel üks näide. Leidke vähemalt ühe reserveerimise teinud külaliste erinevad perenimed. Päringu tulemuses on iga perenimi üks kord. SELECT DISTINCT perenimi FROM Külaline INNER JOIN Reserveerimine ON Külaline.külalise_nr = Reserveerimine.külalise_nr; Leidke vähemalt ühe reserveerimise teinud külalised. Väljastage igaühe kohta tema perenimi. Kui leidub rohkem kui üks sama perenimega külaline, kes on teinud vähemalt ühe reserveerimise, siis on see perenimi päringu tulemuses mitmekordselt. SELECT DISTINCTROW perenimi FROM Külaline INNER JOIN Reserveerimine ON Külaline.külalise_nr = Reserveerimine.külalise_nr; DISTINCTROW vaatleb korduste eemaldamiseks tervet tabeli rida, mitte ainult päringu tulemuses väljastatavaid andmeid. DISTINCTROW pole SQL standardis ja on MS Accessi-spetsiifiline kontsruktsioon (seda ei toeta isegi MS Accessi vanem vend – MS SQL Server). Alternatiiv selle kasutamisele: SELECT perenimi FROM Külaline WHERE EXISTS (SELECT * FROM Reserveerimine WHERE Külaline.külalise_nr = Reserveerimine.külalise_nr); ## Küsimus: Mis vahe on tabelite ühendamisel (join) ja ühendi leidmisel (union)? **Vastus:** Ühendamine (join) on selleks, et saada tabelist loetud ritta juurde uusi andmeid (enamasti mõnest teisest tabelist, ehki ka tabeli ühendamine iseendaga - self-join - on võimalik). Näiteks oletame, et andmebaasis on järgmise struktuuriga tabelid.[Tudeng]-1----------0..*-[Oppimine]Iga õppimine on seotud täpselt ühe tudengiga. Loen ridu tabelist Oppimine ja tahan, et igas saadud reas oleks ka selle õppimisega seotud tudengi perenimi. Selleks pean ühendada õppimise tabeli read tudengi tabeli ridadega. Pean seda tegema nii, et iga õppimise tabeli rida ühendatakse just ja ainult selle tudengi tabeli reaga, kus vastav tudeng on seotud vastava õppimisega.Vanem süntaks:SELECT Oppimine.*, Tudeng.perenimi AS tudengi_perenimiFROM Oppimine, TudengWHERE Oppimine.tudeng=Tudeng.tudkood;Uuem süntaks:SELECT Oppimine.*, Tudeng.perenimi AS tudengi_perenimiFROM Oppimine INNER JOIN Tudeng ON Oppimine.tudeng=Tudeng.tudkood;Ühendi (union) leidmine on selleks, et leida hulkade ühend. SELECT eesnimi, perenimiFROM TudengUNION SELECT eesnimi, perenimiFROM Oppejoud;Eelnev päring moodustab tabeli, kus on nii õppejõudude kui tudengite ees- ja perenimed. Vaikimisi eemaldatakse kordused.UNION operatsioonis osaleb kaks hulka (antud juhul ridade hulka). Nende hulga elementidel peab olema ühesugune struktuur.SELECT eesnimi, perenimiFROM Tudengleiab read, kus on kaks tekstitüüpi välja.SELECT eesnimi, perenimiFROM Oppejoud;leiab read, kus on kaks tekstitüüpi välja.Seega kahes ridade hulgas, mida UNION'iga kokku panen, peavad olema samasuguse struktuuriga read.Hästi piltlikult rääkides. Ühendamine (join) on nagu rongile vagunite lisamine, kusjuures rongile tuleb lisada õiged vagunid, mis peavad jõudma rongi sihtkohta. Ühendi (union) leidmine on nagu ühesuguse kujuga kastide üksteise otsa virna laadimine. ## Küsimus: Ühes õppematerjalis on öeldud "Objekt-relatsiooniliste andmebaasisüsteemide loomine tuleneb lõppkokkuvõttes sellest, et tänapäeva SQL-andmebaasisüsteemid ei realiseeri täies ulatuses relatsioonilist mudelit ja see tekitab probleeme." Millist osa relatsioonilisest mudelist SQL andmebaasisüsteemid ei realiseeri? Miks nõnda? **Vastus:** Põhinemine hulkade asemel multihulkadel (korduvad read ja veerud on lubatud),tühjade võtmete ja ilma veergudeta tabelite mitte lubamine (kuigi ka tühi hulk on hulk),NULLide kasutamine puuduvate andmete esitamiseks, liigsete piirangutega ja samas liiga keeruline uute tüüpide loomise võimalus, SQL-andmebaasisüsteemides praktikas esinevad piirangud deklaratiivsete kitsenduste loomisele (nt ei saa luua üldiseid kitsendusi e ASSERTIONeid),üleüldine järjekindlusetus asjade tegemises või lubamises,need on vaid mõned asjad, mis muudavad SQLi kasutamise keerukamaks kui peaks.Nii mõnedki erinevused SQLi ja relatsioonilise mudeli lähenemiste vahel on toodud välja teema nr 2 (relatsiooniline andmemudel) slaididel (märkused punastes kastides). Põhjalikumalt on teemat eesti keeles lahatud SELLES ettekandes ja SELLE materjali peatükis 6.Kes ei taha pelgalt piirduda vahendatud infoga, see võib uurida Kolmanda Manifesti kohta ilmunud värskeimat raamatut, kus relatsioonilise mudeli ideid väga põhjalikult ja paljude näidetega selgitatakse.SIIN on aga andmebaasisüsteem (Rel), mis realiseerib relatsioonilist mudelit nii nagu sellest aine teemas nr 2 juttu oli. --- # Teema: Süsteemianalüüs ## Küsimus: Andmebaaside aine pöörab palju tähelepanu süsteemianalüüsile. Miks see on oluline? **Vastus:** Oma iseseisva töö projekti tegemise käigus tuleb Teil ennast panna süsteemianalüütiku rolli. Siin on 15.02.2017 Postimehes ilmunud artikkel analüüsi olulisusest süsteemide loomisel ning sellega seotud valikutest haridusmaastikul. Tööelus võite puutuda infosüsteemide arendamisega kokku tellijana, täitjana või näiteks tellija esindajana, kes täitjat igapäevaselt konsulteerib. Hästi toimiva infosüsteemi loomine algab õige ülesandepüstituse koostamisest. Elu näitab, et "IT-probleemide püstitamine ja kirjeldamine viisil, mis tagaks efektiivse tööprotsessi ja tõhusad lahendused", ei tule sageli nii hästi välja kui võiks. Seega ei jookse mööda külge maha oskus ülesandepüstitust (nõudeid) kirja panna. Arendaja rollis on jällegi vajalik oskus kirjapandud nõuetest aru saada.Hiljutiseks näiteks on kriitika riigi otsuse suhtes hakata arendama uut keskset dokumendihalduse süsteemi (maksab vähemalt 2.3 miljonit), selle asemel, et uuendada olemasolevat tarkvara (A-Dok; maksaks hinnanguliselt vähemalt 400 000). Kriitikud heidavad ette, et riigil puudub dokumendi- ja teabehalduse osas sisuline arusaam, ei arvestata sellega, et erinevatel asutustel on erinevad vajadused ning otsuseid langetavad riigi esindajad ei saa aru probleemidest, mis tegelikult vajavad lahendamist. Üheks suure infosüsteemi ebaõnnestunud arendamise näiteks on Ruumilise planeeringu infosüsteem (RPIS). See loodi detailplaneeringutete avaliku väljapaneku kättesaadavuse parandamiseks ning planeeringute kooskõlastamise kiiremaks, jälgitavamaks ja mugavamaks muutmiseks. Süsteemi arendatakse alates 2009. aastast, sellele on kulutatud peaaegu miljon eurot, kuid kasutajaid peaaegu ei ole. Kohalikud omavalitsused eelistavad teisi turul saadaolevaid süsteeme. Selle asemel, et hakata suure hooga nullist uut süsteemi tegema oleks tulnud kõigepealt aru saada, kas ning mida on vaja - võibolla oleks piisanud mõne turul oleva süsteemi kohandamisest. Sellistele küsimustele annab vastuse süsteemianalüüs. Võibolla oleks olnud ka abi tööprotsesside lihtsustamisest - sellega tegeleb ärianalüüs (business analysis), millega käesolev kursus ei tegele. Jaakkola et al. (2016) kohaselt kasvavad nõuete kogumise (analüüsi) faasis tehtud vigade parandamiseks kuluv pingutus iga järgmise süsteemiarenduse faasiga kolm korda. Disaini faasis on neid 3, realiseerimise faasis 9 ja testimise faasis 27 korda kulukam parandada kui nõuete kogumise faasis. Jaakkola, H., Henno, J., Welzer-Druzovec, T., Thalheim, B., Mäkelä, J., 2016. Why Information Systems Modelling Is Difficult. In SQAMIA. pp. 29– 39. Ehk olete kuulnud sotsiaalkaitse infosüsteemi uue versiooni (SKAIS2) arendamise saagast. Praeguseks on kulud kasvanud kaugelt üle algselt planeeritu ja projekti lõppu ei paista. 2019. aasta jaanuaris kuulutati välja järjekordne riigihange süsteemi uute osade tegemiseks ning olemasolevate parandamiseks. Hanke dokumendid on avalikkusele kättesaadavad riigihangete registris ja neid tasub huvi korral sirvida selle pilguga, et: kui mahukas on keerulise infosüsteemi kirjeldus, milliseid dokumente peavad pakkumise koostajad, sh majandusinimesed oskama kirjutada, milliseid dokumente peavad pakkumisele reageerijad ja ka hiljem analüütikud ning arendajad oskama lugeda. Huvi korral vaadake näiteks "Lisa 3. Nõuded infosüsteemi dokumentatsioonile", "Lisa 2. Mittefunktsionaalsed nõuded", "Lisa 1. Arhitektuuri ülevaade". Mitmed soovitud dokumentidest (sh mittefunktsionaalsed nõuded, kuid mitte arhitektuuri kirjeldus) on ka iseseisva töö projektis. "Lisa 5. Tehniline kirjeldus" esitatud tekstilist jutu süsteemilt oodatavatest funktsionaalsustest peab süsteemianalüütik oskama tõlkida täpsemate mudelite keelde (kasutusjuhtude mudelid, protsessimudelid, seisundidiagrammid, andmemudel jne). "Lisa 11.1. Ärianalüüs" dokumendis on väljatoodud põhimõisted ja nende definitsioonid. Selleks, et midagi koos arendada on oluline, et kõik arendusest huvitatud osapooled mõistetest võimalikult täpselt ja ühtemoodi aru saavad. Teie projektis on selliseks mõistete kataloogiks kontseptuaalse andmemudeli osaks olev olemitüüpide ja atribuutide definitsioon.Veel üks sarnane näide on 2024. aasta veebruaris Põhja-Eesti Regionaalhaigla uue elektroonilise haigla infosüsteemi riigihange, mille hankedokumente saab samuti vaadata riigihangete registrist. "Tehniline kirjeldus lisa 1 - Funktsionaalsed nõuded" loetleb nimekirjana nii funktsionaalseid kui mittefunktsionaalseid nõudeid. "Tehniline kirjeldus lisa 2 - Protsessianalüüs" toob näitena välja mõned keerukad protsessid, mille läbiviimist uus infosüsteem toetama peab. Protsessimudelid on ülesjoonistatud BPMN (Business Process Modelling Notation) modelleerimiskeeles.SIIN on aga viide Eesti riigi infosüsteemidele kehtestatud üldistele mittefunktsionaalsetele nõuetele, mida kõikide selliste süsteemide loomisel peab järgima.Informaatika (ilmselt ka äriinfotehnoloogia) lõputööde kaitsmiskomisjonid peavad oluliseks seda, et arenduse teemaline lõputöö ei oleks etteantud tööülesannete (nõuete) täitmise aruanne, vaid et töö käigus tegeletakse ka nõuete kogumise ja väljendamisega. Kui arendaja peab kellegi teise etteantud nõuete järgi kirjutama koodi, siis see ei sobi lõputööks või vähemasti tõmbab see hindajate silmis töö väärtust väga palju alla. Õppekavades, kus on "Andmebaasid I", on see praktiliselt ainus aine, mis puudutab süsteemianalüüsi. Seega kus siis veel kui mitte siin.Siin, siin, siin ja siin on näide äriinfotehnoloogia lõputöödest, mille sisuks oli mahukas süsteemianalüüs. Kuid ka informaatika arenduse teemalistes lõputöödes ei tohi süsteemianalüüs puududa. Siin ja siin on näited informaatika lõputöödest, kus süsteemianalüüs on hästi olemas. Lõpetuseks veel üks pildirida, mis illustreerib seda, mis võib süsteemi arendamise, sh analüüsi käigus valesti minna. **Märksõnad:** süsteemianalüüs, analüütik, detailanalüüs, strateegiline analüüs, ärianalüüs, nõuded ## Küsimus: Kas töövihiku järgi projekti tehes (X=teenus) peaks lisama kasutusjuhtude mudelisse kasutusjuhud teenuste broneerimise kohta? **Vastus:** EI! See on õige, et kliendid võiksid saada teenuse tarbimiseks aja kinni panna (teenuse broneerida). Infosüsteemi kui terviku seisukohalt on see vajalik funktsionaalsus. Mõelge sellele, millised oleksid võimalikud broneerimisega seotud kasutusjuhud. Broneeri teenus (Klient) Vaata oma broneeringuid (Klient) Tühista oma broneering (Klient) Broneeri teenus (Broneeringute haldur) (võib registreerida mistahes kliendi broneeringu) Vaata kõiki broneeringuid (Broneeringute haldur) (võib vaadata mistahes kliendi broneeringut) Tühista broneering (Broneeringute haldur) (võib tühistada mistahes kliendi broneeringu) Teavita broneeringuga kliente (Broneeringute haldur) (erakorralise teate saatmine ühele või mitmele kliendile) Vaata broneeringute kokkuvõtet (Juhataja) ... Nagu näete, siis kasutusjuhte on palju. Küsimus on, millise funktsionaalse allsüsteemi alla need koondada. Kui "Teenuste funktsionaalse allsüsteemi" alla, siis selle kasutusjuhtude arv vähemalt kahekordistuks ja see allsüsteem kasvaks liiga suureks. Miks see on halb? Samal põhjusel miks liiga suure meetodite arvuga klassi tegemine (tuntakse nime all "plekk" või "jumal-klass"). Sellisest allsüsteemist oleks raskem aru saada, seda oleks raskem arendada ja arenduse tulemusi taaskasutada. Seetõttu oleks õige paigutada eelnimetatud kasutusjuhud "Broneeringute funktsionaalse allsüsteemi" alla (vastab põhiobjektile Broneering). Seda allsüsteemi Te projektis detailselt ei käsitle. Seega pole ka vaja vastavaid kasutusjuhte kirja panna. ## Küsimus: Kas välisteks tegutsejateks võivad olla teised infosüsteemid? **Vastus:** Süsteemi välisteks tegutsejateks võivad olla teised infosüsteemid. Selle näiteks majutusasutuste valdkonnas on siseministri poolt 2017. aasta veebruaris esitatud plaan luua majutusasutuste külastajate register. Sellesse registrisse jõuaks automaatselt info kõigi Eesti majutusasutuste külastajate kohta. Registris toimuksid automaatsed päringud, mis otsivad riigile huvipakkuvaid isikuid (nt tagaotsitavaid). Kui vasteid ei saada, kustutakse inimese info omakorda ööpäeva jooksul. Plaani elluviimisega jätkati 2019. aasta sügisel, kui esitati turismiseaduse muutmise eelnõu, mis sellist registreerimist ette näeb. Eelnõu seletuskiri ütleb, et "Eelnõuga ei laiendata registreerimisel esitatavate majutusteenuse kasutajate andmete koosseisu. Isikuandmete kaitse nõuete paremaks täitmiseks luuakse majutusteenuse kasutajate andmekogu." "Tänavu (2019) üheksa kuuga ööbis Eesti majutusettevõtetes pea 3 miljonit külastajat, nende passiandmed kirjutati üles ja tõsteti hotellis kuhugi seifi. Kehtinuks uue seaduseelnõuga plaanitavad muudatused, oleks politsei- ja piirivalveametil juba 3 miljonit sissekannet andmebaasis, mida saaks automaatselt võrrelda 12 andmekogu sisuga, alates töölubade ja Interpoli registrist ja lõpetades kehtivate isikutunnistuste omaga." (artikkel) Võimalik lahendus on, et iga majutusasutuse infosüsteem realiseerib klientide andmeid pakkuva veebiteenuse. Majutusasutuste külastajate registri tarkvara pöördub regulaarselt selle veebiteenuse poole ja "tõmbab" majutusasutuste andmebaasidest külastajate andmeid kesksesse registrisse (näiteks JSON või XML dokumendina). Sellisel juhul on majutusasutuste külastajate register majutusasutuse infosüsteemi üks väline tegutseja. Eesti riigi infosüsteemi moodustavad infosüsteemid vahetavad omavahel infot X-tee andmevahetuskihi kaudu. X-tee mustrikataloogis kirjeldatakse sellist andmete "tõmbamisel" põhinevat lähenemist mustris PM1: andmete päringu teenus. Andmeid omav infosüsteem on teenuse osutaja. Andmeid omaval infosüsteemil on päringutele vastamise teenus, mida andmeid vajav infosüsteem välja kutsub. Võimalik on ka see, et majutusasutuse infosüsteemi tarkvara võtab ise regulaarselt külastajate registri tarkvaraga ühendust ja "lükkab" sinna külastajate andmeid. Sellisel juhul ei ole majutusasutuste külastajate register majutusasutuse infosüsteemi üks väline tegutseja. Eesti riigi infosüsteemi moodustavad infosüsteemid vahetavad omavahel infot X-tee andmevahetuskihi kaudu. X-tee mustrikataloogis kirjeldatakse sellist andmete "lükkamisel" põhinevat lähenemist mustris PM2: andmete saatmise teenus. Andmeid omav infosüsteem on teenuse tarbija. Andmeid vajaval infosüsteemil on andmete vastuvõtu teenus, mida andmeid omav infosüsteem välja kutsub. Pange selle uudise puhul tähele ka seda, et seadustega võivad olla ette nähtud reeglid, milliseid andmeid võib/peab kui kaua säilitama. Kui hakkate mistahes infosüsteemis mõtlema funktsionaalsusele "Kustuta X", siis tuleb selliste nõuetega arvestada. "Kuigi automaatsest registrist kustuvad inimese andmed üldjuhul ööpäevaga, siis majutusasutused ise peavad plaani kohaselt inimeste infot hoidma alles kaks aastat, et ametkonnad saaks vajadusel seda hiljem kontrollida." Rääkides keskse külastajate registri tehnilisest realisatsioonist, siis järgnev pakub välja ühe võimaliku lahenduse. Andmebaasisüsteem PostgreSQL toetab JSON ja JSONB andmetüüpe (tabelites võivad olla seda tüüpi veerud ja nendes veergudes võivad olla JSON dokumendid). Külastajate andmed laetakse veebiteenuse poolt alla ja salvestatakse dokumentidena PostgreSQL andmebaasi. Nende andmete põhjal tehakse päringuid. Kui leitakse huvipakkuv isik, siis tema andmed kirjutatakse eraldi tabelisse, kus võibolla ei ole enam JSON/JSONB tüüpi veergu, vaid selle asemel, on isiku atribuutidele vastavad andmed (eesnimi, perenimi, isikukood, ...) eraldi veergudes. Huvipakkuvate isikute otsimiseks, nende andmete eraldi tabelisse tõstmiseks ja ülevaadatud külastajate andmete kustutamiseks luuakse andmebaasis funktsioonid. Neid funktsioone on vaja regulaarselt käivitada. Kui soovite teha regulaarselt mingit tööd PostgreSQL andmebaasis (näiteks käivitada regulaarselt funktsiooni), siis tuleb selleks kasutada operatsioonisüsteemi vahendeid. Näiteks UNIXI-laadsetes operatsioonisüsteemides saab kasutada deemonit Cron, mis vastutab automaatsete operatsioonide eest. "Deemon on tagaplaanil jooksev programm, mis teostab teatud ettemääratud operatsioone kindlate ajavahemike tagant või vastuseks mingitele sündmustele." (Vallaste, http://www.vallaste.ee/) Majutusasutuse infosüsteemi klientide funktsionaalses allsüsteemi kirjelduses oleks kasutusjuht "Lae alla külastajate andmed", mis on seotud tegutsejaga Majutusasutuste külastajate register. ## Küsimus: Kuidas eristada sisulisi ja administratiivseid allsüsteeme? **Vastus:** Funktsionaalsed allsüsteemid ning registrid liigituvad sisulisteks ja administratiivseteks. Fowler (2010) liigitab tarkvara tarbetarkvaraks (utility software) ja strateegilist eelist andvaks tarkvaraks (strategic software). Fowler hindab, et 95% tarkvarast on tarbetarkvara ja 5% strateegilist eelist andev tarkvara. Fowler võrdleb tarbetarkvara torustikuga - see peab olema olemas ja veatult töötama. Kuni probleeme ei ole, siis kasutajat ei huvita kus see on ja kuidas see seda teeb. Strateegiline tarkvara aitab ettevõttel edendada oma äri ja jõuda uutele turgudele. Selline tarkvara ja selle toetatav äri peaks andma organisatsioonile võistlejate ees eelise, tehes näiteks midagi paremini kui teised sama valdkonna ettevõtted teevad. Selle tarkvaraga seoses peaks toimuma innovatsioon. Leian, et administratiivsed allsüsteemid vastavad tarbetarkvarale ning sisulised allsüsteemid strateegilisele tarkvarale. ## Küsimus: Ma olen informaatika üliõpilane. Ma arvan, et kursuse töö töövihik on suur dokument mida keegi ei kasuta päris elus. Aine projekti tegemine on täielik ajaraisk, sest kogu info mida õppejõud näha tahab tuleb temalt ning kui ise sellest väga õppida ei saa. Milliseid kasulikke teadmisi, lisaks andmebaasidele, see projekt annab? **Vastus:** SIIN on üks pildirida süsteemiarenduse ideaalist vs. tegelikkusest. Nagu näete laiutab soovide ja tegelikkuse vahel suur auk ning dokumentatsiooni asemel on lihtsalt tühjus. Tegelikult ikkagi on vaja asju ette läbi mõelda ja tehtut dokumenteerida, meeldib see Teile või mitte.Kõik järgnev kehtib endisel, aga selle mõtte lisasin juurde 2024. aasta lõpus. Nüüdseks olete Te kõik tuttavad suurte keelemudelitega ning kuulnud lugusid ja ilmselt ka ise kogenud, kuidas need saavad koodi genereerimisega hästi hakkama KUI neile anda ette hästi sõnastatud küsimus. Programmeerimine on aina rohkem muutumas prompt engineeringuks e viipade koostamiseks.  Minu väide on, et kasutajate nõuetest arusaamine ja nende kirjapanemine on loomulik osa sellest protsessist.  Võibolla üldsegi mitte kauges tulevikus kirjutab koodi programm ja inimese ülesanne on programmile sobiv sisend ette anda (video 1 -  Eric Schmidt - Google boss; video 2). Väga oluliseks muutub valdkonna tundmine, mille jaoks programmi luuakse, sest nii osatakse anda keelemudelile piisavalt põhjalik sisend. Kasutusjuhtude tekstikirjeldused või nende protsesse kirjeldavad tegevusdiagrammid  ja mittefunktsionaalsed nõuded oleks aluseks rakenduse genereerimiseks vajalike viipade koostamiseks. Andmebaasioperatsioonide lepingud oleks aluseks neid realiseerivate rutiinide (kas andmebaasis või väljapool seda) genereerimiseks vajalike viipade koostamiseks. Olemi-suhte diagrammid + atribuutide definitsioonid oleksid aluseks andmebaasi andmestruktuuride genereerimiseks vajalike viipade kooostamiseks. Milliseid kasulikke teadmisi, lisaks andmebaasidele, see projekt annab? Üks võimalik viis, kuidas tarkvara tükeldada. Tükeldamine on vajalik tarkvara keerukusega toimetulekuks ja töö paremaks organiseerimiseks. Ülevaade võimalikest mudelitest, mida saab kasutada tarkvara kirjeldamiseks. Ka agiilne süsteemiarendus ütleb, et modelleerimine on vajalik. Tuleb luua mudeleid, millest on kasu, mitte linnukese pärast. Erinevates olukordades, võib olla kasu erinevatest mudelitest. Selleks, et osata otsustada, kas mingit tüüpi mudel mingis olukorras sobib või mitte, tuleb esmalt neid mudeli tüüpe teada. Samuti tuleb arendajal osata aru saada nõuetest ja seega ka mudelitest, mida võidakse kasutada nende nõuete väljendamiseks. Inimesed, kes ei näe oma tulevikku arendajana (analüütikud, andmeteadlased, ettevõtjad, projektijuhid, raamatupidajad jne), võivad tulevikus vabalt sattuda infosüsteemi/tarkvara tellija rolli või kaasatud tulevase kasutaja rolli, kellega tellimuse koostamisel ja süsteemi arendamisel konsulteeritakse. Eriti riigiasutuste puhul on kogu rahastamise loogika selline, et enne arenduse algust soovitakse sõlmida võimalikult täpne leping selle kohta, mida süsteem peab tegema. Seega on kõigepealt vaja teha terve süsteemi analüüs ja sisuliselt tähendab see, et arendus vähemasti algab koskstiilis (edasine arendus võib kuid ei pruugi toimuda iteratiivselt). Tark tellija peab teadma, milliseid süsteemianalüüsi mudeleid saab koostada ning ta peab oskama neid mudeleid lugeda. Kaasatud kasutaja peab samuti oskama mudeleid lugeda. SIIN on üks eestikeelne intervjuu targa tellija olulisuse kohta. Puhta koodi põhimõtted on universaalsed ja kehtivad ka mudelite ning andmebaasi disaini puhul. Andmebaasis kitsenduste loomine on üks kaitsva programmeerimise meetod. Kaitsev programmeerimine üritab tagada koodi toimimist ka ettenägematute asjaolude ilmnemisel ja see aitab parandada süsteemi käideldavust ja turvalisust. Siin on raamat, mis on pühendatud kaitsvale andmebaasi programmeerimisele. Informaatika bakalaureuseõppe lõputööde kaitsmiskomisjoni 2024. aasta kevadisel tagasivaataval kohtumisel avaldati kahetsust selle üle, et tarkvara arendamise teemalistes lõputöödes esitati väga vähe mudeleid, samas kui mudelid oleksid hea ning erineva taustaga lugejatele mõistetav viis loodava süsteemi keerukuse selgitamiseks ning oma töö skoobi väljatoomiseks. Selleks, et osata tööriistakastist (erinevat tüüpi mudelite hulgast) kõige sobivamaid tööriistu (mudelite tüüpe) valida, peaks neid tööriistu tundma või olema nendega vähemalt kokku puutunud. Kirjutan järgnevalt täpsemalt ja toon näiteid.1. Tänapäeval on üheks lööksõnaks e "kuumaks teemaks" mikroteenuste arhitektuur. See tähendab, et tarkvara peaks koosnema üksteisest võimalikult vähe sõltuvatest "tükkidest" e teenustest, mida saaks arendada ülejäänud "tükkidest" võimalikult sõltumatult, mida saaks kerge vaevaga asendada uue realisatsiooniga ja mida ei peaks (palju) muutma, kui mõnes teises "tükis" midagi muutub. Iga funktsionaalse allsüsteemi saaks realiseerida mikroteenusena. Selle funktsionaalse allsüsteemi teenindatava registri saaks realiseerida rakenduse andmebaasina.Mikroteenused üritatakse luua üksteisest võimalikult sõltumatuna, eelistades dubleerimist üksteisest ilmutatud viisil sõltumisele. Andmebaaside mõttes tähendaks see, et erinevate teenuste andmebaasides dubleeritaks põhiandmeid (master data) nagu andmed klientide, toodete ja teenuste kohta ja klassifikaatoreid. Kommentaariks ütlen, et see võib tunduda teenuse autonoomsuse mõttes ahvatlev, kuid andmete dubleerimine tähendab suuremat tööd nende sünkroniseerimiseks (nii suuremat tööd arendajatel selle realiseerimiseks/testimiseks kui ka suuremat koormust süsteemile läbiviimisel) ja suuremat võimalust vastuoluliste väidete registreerimiseks. Kas see on sobiv hind või mitte jäägu igaühe enda otsustada ja kindlasti sõltub ka oludest. (Eesti) Riigi infosüsteemide kohta ütleb avaliku teabe seadus selge sõnaga: "§ 43 3.   Andmekogu asutamine (2) Keelatud on asutada ühtede ja samade andmete kogumiseks eraldi andmekogusid." Põhiobjektidest lähtuv allsüsteemide leidmine on üks võimalik viis mikroteenuste kindlaks määramiseks ja põhiobjekti elutsüklist lähtuv funktsionaalsuse leidmine on üks võimalik viis selle teenuse funktsionaalsuse tuvastamiseks. Kui soovida luua mikroteenused võimalikult autonoomsena ja vajadusel dubleerida andmeid erinevate teenuste andmebaasides, siis saaks teenused luua põhiobjektidele, mis vastavad transaktsioonilistele andmetele ning põhiandmetele ja klassifikaatoritele vastavaid andmeid erinevates andmebaasides dubleerida. Siin on näide hotelli infosüsteemi põhiobjektidest andmete liigituse järgi.2. See on väga vähetõenäoline, et mõni ettevõte kasutab süsteemide kirjeldamiseks just sellist dokumendi struktuuri nagu on aineprojektis. Kuid see, et mingil määral kasutatakse modelleerimist ja mudeleid ning mõnda antud projekti mudeli tüüpidest, on väga palju tõenäolisem.Hea allikas, kust saab lugeda erinevate aineprojekti mudelitüüpide kohta, on: Larman, C., 2013. Applying UML and patterns : an introduction to object-oriented analysis and design and iterative development, Prentice Hall. 703 p. Seda saab ka lugeda O'Reilly digitaalse platvormi kaudu elektrooniliselt. Kuidas kasutada O'Reilly digitaalset platvormi? See raamat on pühendatud objektorienteeritud analüüsile ja disainile (eesmärgiga luua objektorienteeritud programmeerimiskeeles tarkvara), kuid räägitakse ka arendusprotsessist. Mudelite koostamine ei ole mitte kuidagi vastuolus iteratiivse arendamisega. Lihtsalt mudeleid ei looda ühekorraga, vaid neid luuakse ja täiendatakse järk-järgult erinevate iteratsioonide käigus. Raamatus kirjutatakse muuhulgas põhjalikult: klassidiagrammidest, mida kasutades luuakse valdkonnamudeleid (domain model), Kontseptuaalne andmemudel ja valdkonnamudel on sugulased ja kontseptuaalse andmemudeli loomise võtted ning mustrid on kõik kasutatavad ka valdkonna klassidiagrammide koostamiseks. Sama kehtib ka antimustrite kohta, mis esitavad esmapilgul häid lahendusi, mis hiljem viivad probleemideni. Need klassidiagrammid on omakorda sisendiks tarkvaraklasside leidmisele (nii nagu kontseptuaalne andmemudel on sisendiks tabelite leidmisele), seisundidiagrammidest, tegevusdiagrammidest, kasutusjuhtude mudelist, paketidiagrammidest, Saab kasutada arhitektuuri kirjeldamiseks. süsteemi operatsioonide lepingutest Need on sarnased andmebaasi operatsioonide lepingutega. Süsteemi operatsioonid kirjeldavad teenuseid, mida funktsionaalsed allsüsteemid (tarkvara) pakuvad pädevusaladele (lõppkasutajatele). Andmebaasi operatsioonid kirjeldavad teenuseid, mida andmebaasi alamosad (registrid) pakub funktsionaalsetele allsüsteemidele (tarkvarale). Nii nagu süsteemi operatsioonide lepingutest tekivad tarkvara klasside meetodid, tekivad andmete muutmise operatsioonide lepingutest andmebaasiserveris talletatud rutiinid (funktsioonid ja protseduurid). Operatsioonide lepingud võiksid huvi pakkuda ka seetõttu, et need lähtuvad lepingprojekteerimise (design by contract) põhimõttest. See põhimõte töötati välja seoses objektorienteeritud programmeerimiskeelega Eiffel ning esitab tarkvara elementide käitumist viisil, mida ideaalis saaks hiljem kasutada tarkvara kontrollimiseks või koodi genereerimiseks. Sellel teemal mõtlejaid on teisigi (vaadake History alamosa Larmani raamatu süsteemi operatsioonide lepingute peatükist) ja nende idee on kasvanud välja arvutiteaduse (computer science) ringkondadest. Järgnev raamat argumenteerib, miks kontseptuaalse andmemudeli ja andmebaasi disainimudeli loomine ei ole ka agiilse andmebaasi arenduse mõttes ajaraisk, vaid igati kasulik ettevõtmine.Burns, L., 2011. Building the Agile Database. How to Build a Successful Application Using Agile Without Sacrificing Data Management, Technics Publications. 276 p. CRUD maatrikseid on arvutiteaduses üritatud kasutada süsteemide struktuuri leidmiseks ja see on huvitav uurimissuund (vaadake näitena seda artiklit ja ka seda).Tüüpiliselt kulub tarkvara hooldamisele igal aastal 15–20% tarkvara loomiseks tehtud kulutustest. Seega tarkvarale, mis on olnud kasutusel 10 aastat, on hooldamiseks kulunud kaks korda rohkem raha kui algseks loomiseks.  Edukaid süsteeme hooldatakse tavaliselt 10 kuni 20 aastat. Täpsed, kooskõlalised ning süsteemi tegelikku seisu peegeldavad mudelid aitavad tarkvara hooldusega tegelejatel (kes võivad, kuid ei pruugi, olla süsteemi loojad) tarkvarasüsteemist (sealhulgas andmebaasist) aru saada.Tarkvara ja andmebaas peavad ajaga kaasas käima – evolutsioneeruma. Tarkvara/andmebaas pole nagu kivi, mis on miljoneid aastaid ühesugune, vaid nagu elusloodus, mis peab kohanduma ja muutuma. Muudatuste tegemisele aitab kaasa kvaliteetse dokumentatsiooni olemasolu.3. Lugege näiteks siit, kuidas peaaegu igale koodi halvale lõhnale vastab mingi analoogiline probleem seoses infosüsteemi/tarkvara mudelitega. Samamoodi esinevad andmebaasis ja tekitavad sellest arusaamisel, õppimisel, hooldamisel ja edasiarendamisel probleeme näiteks halvad andmebaasiobjektide nimed, kasutama andmebaasiobjektid, ebatäpsed kommentaarid, üleliigne dubleerimine ja järjekindlusetus disainiotsuste tegemisel.Veel mõtteid dokumenteerimise vajalikkuse kohta Dokumenteerimine aitab süsteeme edasi arendada. Viimasel ajal kaitstakse üha rohkem lõputöid, kus üksinda või rühmas arendatakse edasi mingit tarkvara (näiteks erinevad ülikooli õppesüsteemid), mida eelnevad üliõpilased on juba oma lõputöödes arendanud. Kuulates 2023. aasta kevadel selliste lõputööde kaitsmisi oli esinemisest esinemisesse korduv väide, et eelmine tegijate rühm ei olnud oma tööd piisavalt dokumenteerinud (sh polnud kirja pandud nõudeid ja kirjeldatud loodud tabeleid), mistõttu kulus väga palju (liigselt palju) aega süsteemi eelmise versiooni arenduskeskkonnas ülespanekule ja sellest arusaamisele ning vastavalt jäi loodetust vähem aega süsteemi edasiarendamisele. Kaks tsitaati lõputöö ülesandepüstitusest - järjekorras kolmas tarkvara tegijate töörühm hakkas tarkvara nullist ümber tegema. Nad kirjutasid: „Eelmise projektiga tegelenud tiimid hakkasid kohe arendama, millest tulenevadki praeguse lahenduse vead ning vajadus projekti ümbertegemisele.“ Veel lisasid nad: "Arenduse käigus paneme suurt rõhku koodi dokumenteerimisele mis oli eelnevate lahenduste puhul väga suureks probleemiks." Eelmised tegijad hakkasid kohe suure hooga arendama, kuid lõpuks polnud ei korralikult toimivat tarkvara, ega ka korralikku dokumentatsiooni selle kohta. Veel üks eluline näide. Tootmisettevõte tahab oma töö efektiivsemaks muutmiseks võtta kasutusele tehisintellekti, mis kliendi hinnapäringu alusel koostab automaatselt hinnapakkumise ja tootmise plaani. Tehisintellekt vajab oma tööks andmeid. Andmed tulevad andmebaasist. Info andmebaasi ülesehituse kohta (mis andmed on mis tabelites ja veergudes) on andmebaasi tegija peas. Enne kui saab süsteemi arendamisega pihta hakata tuleb see info peast kätte saada ning ilmutatult kirja panna, mis võttis märkimisväärse aja projektile ettenähtud ajast. Dokumenteerimine aitab tagada süsteemide turvalisust. Eesti infoturbestandard esitab nõuded ning juhised organisatsiooni infoturbe halduse süsteemi käivitamiseks, rakendamiseks, käigushoiuks ja täiustamiseks. Eesti avalikke ülesandeid täitavad organisatsioonid peavad E-ITSi nõudeid täitma, eraettevõtted võivad neid täita. Teiste sõnadega e-riigi süsteemides peab igal juhul E-ITSi nõudeid järgima. "E-ITSi eesmärk on tagada avalike ülesannete täitmiseks kasutatavate äriprotsesside ja infosüsteemide kõikehõlmav kaitse ning saavutada infoturbe ühtlane tase nende kõigis osades kogu elutsükli jooksul." Nende eesmärkide täitmiseks tuleb E-ITSi rakendaval ettevõttel muuhulgas äriprotsessid kirjeldada ja arvele võtta (st teemaks on modelleerimine ja dokumenteerimine). See on standardi rakendamise eeldus. E-ITS kirjeldab turvameetmed, mis jagunevad põhimeetmeteks ja standardmeetmeteks. Põhimeetmeid tuleb rakendada igal juhul, sest see on absoluutne miinimum mida turvalisuse tagamiseks teha. Standardmeetmete rakendamiseni jõudmine tagab suurema turvalisuse ja nende rakendamiseni jõudmine peaks olema iga organisatsiooni eesmärk. E-ITS pakub etalonturbe süsteemi, kus väljapakutud meetmed on jagatud erinevatele teemadele vastavatesse moodulitesse. Moodulirühmas "Kontseptisoonid ja metoodikad" olevas moodulis "Tarkvaraarendus" on üks standardmeede "Detailne tarkvara dokumentatsioon". Meetme kirjelduses tuuakse välja, et tarkvara kohta peab olema üksikasjalik ja põhjalik dokumentatsioon ning loetletakse selle dokumentatsiooni minimaalselt nõutavad osad. Ühtlasi rõhutatakse, et dokumentatsiooni detailsus peab olema piisav, et nõutava tasemega tehniline ekspert suudaks dokumentatsioonile tuginedes tarkvaratoote halduse ja arendamise üle võtta. Samuti tuleb valida selline tarkvaraarenduse metoodika, mis näeb ette dokumentatsiooni loomise. Moodulirühmas "Rakendused" olevas moodulis "Tellimustarkvara arendus" on üks standardmeede "Tellimustarkvara nõuete põhjalik dokumenteerimine". Meetme kirjelduses tuuakse välja vajadus dokumenteerida nii funktsionaalsed kui ka mittefunktsionaalsed nõuded, kusjuures mittefunktsionaalsete nõuete juures nimetatakse ka nõuete liigid, mis tuleb kindlasti välja tuua. Samuti rõhutatakse, et "pärast tarkvaramuudatuste ja funktsionaalsete uuendite installimist kontrollitakse nõuetele vastavust ning vajadusel uuendatakse tarkvara nõuete dokumentatsiooni." See, et taolistest asjadest turvalisuse tagamise standardis kirjutatakse, on loogiline, sest üks kolmest infoturbe põhikomponendist on käideldavus. Käideldav süsteem on ettenähtud ajal ettenähtud mahus kättesaadav. Selle tagamiseks tuleb süsteemi pidevalt hooldada ja vajaduse tekkides edasiarendada ning selleks on omakorda vaja süsteemist detailideni aru saada (vt esimene mõte). Dokumenteerimine aitab vältida pärandsüsteemidest (legacy system, taakvara) tulenevaid probleeme.  Riigi Infosüsteemi Ameti (RIA) küberturvalisuse 2022. aasta aastaraamatus kirjutatakse: "Taakvara vaevab paljusid pikka aega tegutsenud ettevõtteid ja asutusi. Näiteks ei pruugi kümme aastat tagasi arendatud süsteemi praegustel omanikel olla täielikku teadmist selle ülesehitusest ega funktsioonidest. Organisatsioonid muutuvad ajas, inimesed  vahetuvad ning pahatihti ei ole kunagi kasutusele võetud lahendused „järeltulijatele“ korralikult dokumenteeritud. Seetõttu pole sageli täpselt teada, millise doominoefekti võib ühe osa uuendamine kuskil süsteemi teises otsas kaasa tuua." Iga tarkvara, mida piisavalt pikka aega kasutatakse, muutub ühel hetkel taakvaraks. Dokumenteerimine aitab kaasa taaskasutamisele. Erinevate Eesti riigiasutuste koostöös valminud tehisintellekti ja andmete valges raamatus aastateks 2024-2030 kirjutatakse: "Andmete taaskasutus saab toimida ainult siis, kui erinevate osapoolte poolt hallatavad andmed on standardiseeritud, korrastatud, kirjeldatud, avalikustatud, kontrollitud kvaliteediga ning varustatud andmete taaskasutust toetava dokumentatsiooni ja toega." Samas dokumendis kirjutatakse, et Eesti e-riigis ei ole sellega sugugi kõik korras, sest "vaid 8% riigiasutustest on juurutanud andmekirjelduse standardi, 28% on kaardistanud kõik oma andmed, põhiandmed on kaardistanud ja kirjeldanud 36% asutustest". Sama dokumendi kohaselt puudub 2023. aasta seisuga 58%-l asutustest täielik ülevaade oma andmestikest ja 55% asutustest ei uuenda ja avalikusta regulaarselt andmekirjeldusi. Kokkuvõtteks, päriselu ei ole AINULT idufirmad. Nendes võibolla tõesti on eesmärk kiiresti midagi tööle saada, et enne konkurente turule jõuda. Kui firma jääb püsima, siis pigem varem kui hiljem tuleb hakata arvestama eelnevalt kirjeldatud probleemidega. **Märksõnad:** iseseisev töö, projekt, dokument, dokumentatsioon, mudelid, project, diagramm, diagrammid, puhas kood, allsüsteem, funktsionaalne allsüsteem, register, andmebaasioperatsioon, andmebaasioperatsioonide lepingud ## Küsimus: Meie töövihiku projekti teemaks on treeningute funktsionaalne allsüsteem. Dokumendi punktis 1.2.3 (Allsüsteemi poolt vajatavad registrid) me kirjutame, et kasutame saalide registrit. Kas see tähendab, et meie projekti kontseptuaalse andmemudeli osaks peab olema saalide registri olemi-suhte diagramm? **Vastus:** Jah! Kommentaarid: 1. Töövihiku korral, kui X=Treening, siis Treening = Ainekaart Öelda, et iga treening on seotud täpselt ühe saaliga oleks sama, kui öelda näiteks ÕISis "Andmebaasid I" ainekaardil, et seda õpetatakse ainult ruumis ICT-404. Tegelikult saab seda ainet õpetada paljudes ruumides. Võimalik on anda sellele seosetüübile uus tähendus ja öelda, et tegemist on eelistatud saaliga selle treeningu läbiviimiseks. Selleks saab mudelis määrata saali rolli selle seosetüübi kontekstis. [Treening]-0..*-----+eelistatud saal-1-[Saal] 2. Igal põhiobjektil on elutsükkel ja infosüsteemis peab olema võimalik jälgida, millises seisundis on selle eksemplarid. Sellest sõltuvad süsteemis tehtavad tegevused. Näiteks ma ei tohiks saada siduda treeningut "Suletud" seisundis saaliga. Seega peab kontseptuaalses andmemudelis olema: [Saal]-0..*-----------1-[Saali seisundi liik] Samuti tuleb treeningu registreerimise ja treeningu andmete muutmise andmebaasioperatsioonide eeltingimustes ära kirjeldada, millises seisundis saalidega saab treeningut siduda. 3. Võimalik lihtsustus on käsitleda saali klassifikaatorina. Sellisel juhul oleks mudelis Saal Klassifikaatori alamtüübiks ja eraldi saalide registrit pole äriarhitektuuris vaja. Selline lahendus sobib, kui saalide andmete haldamiseks tehtavad toimingud ei erine teiste klassifikaatorite andmete haldamiseks tehtud toimingutest ja saalide elutsükkel ei erine teiste klassifikaatorite elutsüklist. Sellisel juhul puudub mudelist olemitüüp Saali_seisundi_liik. ## Küsimus: Miks on kasulik tükeldada infosüsteemi allsüsteemideks? **Vastus:** Juhin Teie tähelepanu Postimehe 21.02.2017 artiklile "Riigi olulisema infosüsteemi seis: tengelpung lõhki, kalender ribadeks, aga lootust on". Paljude infosüsteemide arendamisel tekib kahjuks olukord, et arendus läheb oodatust kallimaks ja võtab eeldatust rohkem aega. Selles artiklis on sellise olukorra tekkimise ja põhjuste väga ilmekas kirjeldus Eesti pensionide ja sotsiaaltoetuste maksmise infosüsteemi (SKAIS) uue versiooni (SKAIS2) näitel. Seda infosüsteemi kasutatakse igapäevaselt 110 erinevat liiki toetuse ja pensioni maksmiseks kokku 700 000 inimesele. Kokkuvõtlikult: Arenduse valmimine lükkus edasi vähemalt 1,5 aastat . Projekt läks kallimaks vähemalt 1,5 miljonit. Arendajad olid artikli kirjutamise ajaks maksnud riigile 180 000 eurot trahve. Otsene seos käesoleva aine temaatikaga tekib sellest, et algselt asuti kogu keerulist süsteemi arendama tervikuna. See oli korraga närimiseks liiga suur suutäis. Tõmmake paralleele sellega, et võtate suu täis mingit kõva maiustust ja siis ei saa isegi hambaid liigutada. Nüüdseks on otsustatud arendamist jätkata osade kaupa. Need osad vastavad funktsionaalsetele allsüsteemidele. Süsteemi jagamine allsüsteemideks võimaldab allsüsteemide arendamist järk-järgult, arenduse tellimist erinevate hangetega ja võimalik, et erinevatelt firmadelt - täpselt nii nagu nüüd plaanitakse. Kuna iga hanke tulemusena tuleb teha valmis väiksem "tükk", siis on ka tähtajad paremini saavutatavad. 11.08.2017 sai see lugu kurva jätku, kui tehti teatavaks, et riik katkestab lepingu süsteemi senise arendajaga ja kuulutab välja uue hanke. Kokkuvõttes läks arendus algselt plaanitust vähemalt kaheksa miljonit EURi kallimaks (algne plaanitud maksumus 7.1 miljonit EURi) ja valmimine lükkus viis aastat edasi. 15.04.2018 kirjutati, et uues SKAIS2 arendamise lepingus pandi paika eeldatav tööde kestus (neli aastat), kuid ei fikseeritud täpseid tähtaegu ega arendamise graafikut. Täpne ajagraafik pannakse paika pärast infosüsteemi arhitektuuri analüüsi. Näib, et see analüüs meenutab siin aines kirjeldatavat strateegilist analüüsi. Strateegiline analüüs määrab süsteemi skoobi, leiab arhitektuuri (või arhitektuuri variandid), tuvastab riskid ja paneb paika arendamise ajakava. Lepingus määrati ära üldine tegevuste järjekord: SKAISi arhitektuuri analüüs, olemasolevate teenuste vastavusse viimine uue arhitektuuriga, uute teenuste arendamise alustamine. 28.01.2019 kirjutas ajakirjandus, et juba 15 miljonit maksma läinud projekti jätkamiseks kuulutati 2019. aasta jaanuari keskel välja riigihange mahus 8 miljonit eurot. Olemasolevad arenduspartnerid jätkavad tööd vastavalt sõlmitud lepingule. Uue hanke eesmärk on samaaegselt arendada täiendavat funktsionaalsust.25.09.2020 tegi ajakirjandus vahekokkuvõtte, et selleks ajaks on süsteemile kulunud 12 miljonit eurot, kuid lepinguid on töödele kokku 44 miljoni euro eest. Projektiga tegeleb kuus IT-ettevõtet. Mõned asjad nagu iseteeninduskeskkond koos proaktiivse (ennetava) perehüvitise teenusega on valmis jõutud. ## Küsimus: Miks on vaja klassifikaatorite funktsionaalset allsüsteemi? **Vastus:** Eluline näide, kuidas klassifikaatorite väärtuste hulk võib ajas täieneda. See näide on soo klassifikaatori kohta. Selliste täienduste tegemine (hetkel uute väärtuste lisamine) toimuks infosüsteemi äriarhitektuuri mõttes läbi klassifikaatorite funktsionaalse allsüsteemi. Kasutajatele esitatavate klassifikaatori väärtuste nimetused peaksid olema ühes inimkeeles. Kui süsteem peaks võimaldama kasutajaliidese keelt muuta, siis lõppkasutaja jaoks peaks keele muutmisel muutuma nii kasutajaliidese kui klassifikaatori nimetuste keel. Viimase saavutamiseks on erinevaid SQL-andmebaasi disaine. Süsteemide mitmekeelsuse küsimusi puudutab ka järgnev töö: Hövel, E., 2017. Mõned mitmekeelsete SQL-andmebaaside disainimustrid. Bakalureusetöö. TTÜ Tarkvarateaduse instituut [WWW] https://digi.lib.ttu.ee/i/?8271 ## Küsimus: Miks suurte IT-süsteemide arendamine pahatihti ebaõnnestub? **Vastus:** 2019. aasta sügisel avaldas riigikontroll aruande (kokkuvõte) selle kohta, miks riigi tarkvaraarenduse projektid (mis enamasti on suuremahulised) nii mõnigi kord ebaõnnestuvad. Viimasel ajal on selle kohta päris mitmeid näiteid. See aruanne oli üheks ajendiks, miks Andres Kütt pidas 4. oktoobril 2019 Tallinna Tehnikaülikoolis avaliku loengu teemal "Õppetunnid suurtest IT projektidest". Tundub, et riigikontrolli aruanne tabas valusalt närvi, sest arvajaid ning kaasamõtlejaid oli palju. Tõstaksin veel esile Kaimar Karu arvamusloo teemal "Riigi tarkvaraprojektide õnnestumise võimalikkusest". **Märksõnad:** arendus, infosüsteem ## Küsimus: Millised on soovitused kasutusjuhtude mudeli nullist loomiseks? **Vastus:** Sobiv suurus kasutusjuhtudele oleks elementaarne äriprotsess - toimingute jada ühel ajal ja kohas ühe tegutseja poolt, mille tulemusena täidetakse mõni  tema eesmärk ja pakutakse tegutsejale selle kaudu väärtust. Ebasobiv on näiteks "Halda avaldust", sest sellega tegeleb pikema aja jooksul mitmeid erinevaid tegutsejaid. Ebasobiv oleks näiteks "Vali avaldusele ettevõte", sest see on üksik toiming suuremast toimingute jadast, mille tulemusel saaks tegutseja mõne oma eesmärgi täidetud. Ilmutatult esitatud seosed (include, extend) kasutusjuhtude vahel pigem suurendavad mudeli keerukust ja seega võiks neid kasutada pigem vähem kui rohkem. Ärge palun unustage, et neid seoseid peab kajastama ka kasutusjuhtude tekstikirjeldustes. Kasutusjuhtude vahelised seosed tulevad paremini välja nende laiendatud tekstikirjeldustes olevatest eel- ja järeltingimustest. <<include>> seosel oleks mõtet, kui mitmel kasutusjuhul on ühine funktsionaalsus, mille kirjelduse saaks nendest välja tõsta ("sulgude ette panna").  Näide: (A)---<<include>>--->(B)<-------<<include>>--(C) Kasutusjuhtu B nimetatakse abikasutusjuhuks. Kui <<include>> abil kutsub kasutusjuhtu B välja ainult üks kasutusjuht, siis pole B-l eraldi kasutusjuhuna mõtet.   Näide:   Tegutseja1--------(kasutusjuht1)---<<include>>--->(kasutusjuht2)---<<include>>-->(kasutusjuht3)----Tegutseja2   Mõistlikum oleks:   Tegutseja1--------(kasutusjuht1+kasutusjuht2)      (kasutusjuht3)----Tegutseja2   Kasutusjuhtude leidmiseks saab kasutada järgnevat protsessi. Koostada põhiobjekti seisundidiagramm (seisunditel võivad olla alamseisundid). Üldiselt vastab igale seisundi üleminekule eraldi kasutusjuht (seisundi ülemineku põhjustanud sündmus käivitab ka kasutusjuhu). Erinevad seisundi üleminekud samasse seisundisse võib saada panna kokku üheks kasutusjuhuks, kuid nagu alati, on reeglil erandeid. Näide: Aktiivse teenuse või mitteaktiivse teenuse lõpetamise (kaks eraldi seisundi üleminekut koos neile vastava sündmusega) saab panna kokku kasutusjuhuks "Lõpeta teenus", eeldusel, et nii aktiivse kui mitteaktiivse teenuse lõpetamisega tegeleb sama tegutseja. Erandi näide: kui on kaks võimalust - esindaja esitab avalduse ise või süsteem esitab avalduse automaatselt, siis need on kaks eraldi kasutusjuhtu. Kui panna need kokku üheks, siis tekib küsimus, milline stsenaarium on põhistsenaarium ja milline alternatiivne. Lisanduvad andmete muutmise kasutusjuhud (parandamine, mis pole seotud seisundi muutmisega). Lisanduvad andmete vaatamise kasutusjuhud (detailandmete või koondandmete aruanded). Iga eeldefineeritud aruanne võiks olla esitatud eraldi kasutusjuhuna. ## Küsimus: Milliseid allikaid soovitate UMLiga tutvumiseks või selle kohta teadmiste värskendamiseks lugeda? **Vastus:** Ma olen ka koostanud ühe eestikeelse konspekti, mida huvilised saavad lugeda lisamaterjalide lehelt (kasutajanimi: SIS2 ja parool: SIS2) SELLEST MATERJALIST. Raamatutest soovitan eestikeelset raamatut: Fowler, M., 2007. UMLi kontsentraat. 3. redaktsioon. Objektmodelleerimise standardkeele UML2.0 lühijuhend. Cybernetica AS. [WWW] https://www.ester.ee/record=b2282809~S1*est Kaanepilt: https://www.apollo.ee/umli-kontsentraat.html Seda raamatut on paraku väga vähe saadaval. Kui näete kuskil pakkumist või saate laenutada, siis soovitan sellest kinni haarata. Järgnevatest allikatest leiate ingliskeelse ülevaate UML 2.X erinevatest diagrammitüüpidest: Larman, C., 2013. Applying UML and patterns : an introduction to object-oriented analysis and design and iterative development, Prentice Hall. 703 p. [WWW] https://www.ester.ee/record=b2048056*est Raamatut saab lugeda O'Reilly digitaalselt platvormilt SIIN Kuidas kasutada O'Reilly digitaalset platvormi? http://agilemodeling.com/essays/umlDiagrams.htm https://www.uml-diagrams.org/ **Märksõnad:** tegevusdiagramm, kasutusjuhtude diagramm, seisundidiagramm, klassidiagramm, olemi-suhte diagramm, andmebaasi diagramm, olekumasin, olekumasina skeem ## Küsimus: Milliseid täiendusi tuleb arenduse tulemites (mudelid, andmebaas+rakendus) teha, kui tekivad uued nõuded, mida rakendus peab realiseerima? **Vastus:** Süsteemiarenduse tulemid (artefaktid) on omavahel läbipõimunud. Muutes ühte, on vaja muuta ka paljusid teisi. Toon näite. Vastuvõtuaegade süsteemis lisandus nõue, et vastuvõtt võib toimuda Interneti vahendusel, st mitte enam kindlas ruumis füüsiliselt kohtudes. Lahenduseks on, et info virtuaalse kohtumise kohta pannakse kirja vastuvõtu kommentaari ning kui vastuvõtul puudub ruum, siis peab sellel olema kommentaar.Tegin süsteemiarenduse tulemites järgmised muudatused.Muutused mudelites. Lisandus ärireegel: "Kui vastuvõtt toimub Internetis, siis tuleb see kirjutada vastuvõtu kommentaari. Igal vastuvõtul peab olema registreeritud vähemalt üks kahest – ruum võikommentaar." Olemi suhte diagrammil muutus võimsustik: [Vastuvõtt]-0..*-------------------1-[Ruum] => [Vastuvõtt]-0..*-------------------0..1-[Ruum] Muutus ja dokumendis tuli asendada nii kontseptuaalse andmemudeli eskiismudeli diagramm kui ka vastuvõtuaegade registri detailanalüüsi täpsusega olemi-suhte diagramm. Kontseptuaalse andmemudeli atribuutide definitsioonis lisandus Vastuvõtt atribuudile kommentaar kitsendus: {Vähemalt üks kahest – ruum võikommentaar peab olema registreeritud.} Muutusid detailanalüüsi täpsusega kasutusjuhtude kirjeldused - vastuvõttude nimekirjas tuleb nii õppejõule kui üliõpilasele lisaks vastuvõtu hoonele/ruumile näidata ka vastuvõtu kommentaari. Andmebaasi disaini mudelis muutus tabeli Vastuvott veerg ruum_id mittekohustuslikuks. Andmebaasi disaini mudelis tuli kirjeldada CHECK kitsendus, mille kohaselt igas tabeli Vastuvott reas peab olema määratud vähemalt üks kahest - kommentaar või ruum_id. Vastuvõtuaegade registri muutunud disaini diagramm tuli dokumendis asendada. Muutused realisatsioonis. Tabeli Vastuvott veerult ruum_id tuli kustutada NOT NULL kitsendus. Tabelile Vastuvott tuli luua valideerimisreegel, mille kohaselt igas tabeli Vastuvott reas peab olema määratud vähemalt üks kahest - kommentaar või ruum_id. Vastuvõttude nimekirjavormidele tuli lisada ka vastuvõtja kommentaari väli, et nimekirja vaataja näeks kohe, et vastuvõtt toimub Internetis. Vastuvõtu lisamise/muutmise vormile tuli lisada abitekst selle kohta, et kui vastuvõtt toimub Internetis, siis peab selle kirjutama kommentaari. Muutused testides. Kui need oleksid loodud peaks muutma ka neid. ## Küsimus: Palun tooge näiteid töödest, kus kasutatakse neid diagramme e skeeme, mida andmebaaside õppeaine iseseisva töö dokumendis tuleb koostada. **Vastus:** Võtsin ette Tallinna Tehnikaülikooli digikogu. Väga palju lõputöid on sellised, millega lahendatakse mingi konkreetse organisatsiooni jaoks oluline ülesanne - näiteks kavandatakse ja realiseeritakse mingi tarkvara.Otsisin lõputöid, mille pealkirjas on sõna "süsteemianalüüs". 19.01.2025 seisuga oli tulemuses 37 lõputööd. Sorteerisin tulemuse alguse aja järgi kahanevalt ning vaatasin töid, mis kaitsti 2022-2024. Kokku oli selliseid töid 16. Nendest 15 olid magistritööd ja 1 oli bakalaureusetöö. Mõned tööd olid kaitstud kinnisel kaitsmisel ning nende dokument ei olnud avalik. Kõikide ülejäänute puhul oli suuremal või vähemal määral loodud neid mudeleid, mida ka selle aine projekti raames tuleb luua. Mõned kommentaarid: UML tegevusdiagrammide (activity diagram) asemel kasutati enamasti Business Process Model and Notation (BPMN) keeles loodud mudeleid. Võibolla on need veidi ilmekamad kui UML tegevusdiagrammid, aga üldiselt on need üsna ühesugused (st sama info mis on BPMN mudelis saaks esitada ka tegevusdiagrammina). Olemi-suhte diagrammide nime all esitati tabelite kirjeldusi (loogilise disaini andmemudelit). Olemi-suhte diagrammi, nagu õpime seda tunda siin aines, esitleti nime all "äriinfo mudel". Enefit Green AS-i tootmisobjektidega seotud sündmuste menetlemise keskkonna äri- ja süsteemianalüüs Loodi: BPMN, kasutusjuhtude diagramm, kasutusjuhud laiendatud formaadis, seisundidiagramm, kontseptuaalne andmemudel   Äri- ja süsteemianalüüs nõusolekuteenuse haldusliidese võimekuse parendamiseks Loodi: äriinfo mudel, ärireeglid, BPMN, kasutusjuhtude diagramm, kasutusjuhud laiendatud formaadis   Süsteemianalüüs muuseumide audiogiidide veebirakendusele Loodi: tegevusdiagramm   Tuulikulabade inspektsiooniandmete infosüsteemi äri - ja süsteemianalüüs tuulikulabade vigastuste ennetavaks tuvastamiseks Enefit Green AS-i näitel Loodi: ärireeglid, äriinfo mudel, BPMN, kasutusjuhtude diagramm, kasutusjuhud laiendatud formaadis, loogilise disaini andmemudel    Ristumiskohtade ehitamise menetlusprotsessi äri- ja süsteemianalüüs Ehitisregistri näitel Loodi: ärireeglid, äriinfo mudel, BPMN, kasutusjuhtude diagramm, kasutusjuhud laiendatud formaadis   Maksu- ja Tolliameti pääsuõiguste ja volituste halduse infosüsteemi äri- ja süsteemianalüüs eesmärke toetava teenuse kujundamiseks Loodi:  ärireeglid, äriinfo mudel, BPMN, kasutusjuhtude diagramm, kasutusjuhud laiendatud formaadis   Mürgistusteabekeskuse uue infosüsteemi äri- ja süsteemianalüüs Loodi: ärireeglid, äriinfo mudel, BPMN, seisundidiagramm   Püsimaksetel põhineva maksemeetodi iseteenindusportaali äri- ja süsteemianalüüs Loodi: ärireeglid, äriinfo mudel, BPMN, kasutusjuhtude diagramm, kasutusjuhud laiendatud formaadis, loogilise disaini andmemudel   Äri- ja süsteemianalüüs Meistri töölaua funktsionaalsuse lisamiseks Columbus Eesti AS tootmise tagasiside lahendusele ColMES Loodi: ärireeglid, äriinfo mudel, BPMN, kasutusjuhtude diagramm, kasutusjuhud laiendatud formaadis, loogilise disaini andmemudel   Vaimse tervise spetsialisti teenuse ja kontakti otsingusüsteemi äri- ja süsteemianalüüs Loodi: ärireeglid, äriinfo mudel, BPMN, kasutusjuhtude diagramm, kasutusjuhud laiendatud formaadis, loogilise disaini andmemudel   Kinnipeetavatele digitaalset kohtumenetlust võimaldava rakenduse äri- ja süsteemianalüüs Loodi: BPMN, kasutusjuhtude diagramm, loogilise disaini andmemudel   E-kviitungite keskse portaali äri- ja süsteemianalüüs Loodi: ärireeglid, äriinfo mudel, kasutusjuhtude diagramm, kasutusjuhud laiendatud formaadis   Tallinna Tehnikaülikooli Moodle õpikeskkonna ja õppeinfosüsteemi (ÕIS) integratsiooni toetav äri- ja süsteemianalüüs Loodi: BPMN, kasutusjuhtude diagramm, loogilise disaini andmemudel   ## Küsimus: Teeme töövihiku järgi ning põhiolemiks on hoiuruum. Küsimus: Kas olekudiagrammile oleks loogiline lisada ka "renditud" olek? Mõtlesime selle üle ning tundus, et see viib vastuoluni, et hoiuruum peab olema korraga nii aktiivne kui ka renditud/vaba. (See oleks justkui nagu aktiivse oleku alam-olek). Samas informatsioon selle oleku kohta, kas hoiuruum on välja renditud või vaba on väga vajalik. Kas seda olekut peaks kajastama hoiuruumi seisundi diagrammil või kuskil mujal? **Vastus:** Ei ole vaja kajastada. Jah, kontseptuaalselt on "Renditud" oleku "Aktiivne" alamolek. Andmebaasi mõttes saab kindlaks teha, kas hoiuruum on parajasti renditud või mitte selle kaudu, kui teha päring rentimiste registrisse ja veenduda, kas leidub selle hoiuruumi kehtiv rentimine, mille puhul hetke aeg jääb selle rentimise alguse aja ja lõpu aja vahele. Hoiuruum võib olla täna vaba, järgmine kuu renditud, ülejärgmine kuu jälle vaba. Küsimus - mis seisundis ta siis on - vaba või hõivatud. Praktikas muidugi võiks tahta hoiuruumi lõpetamisel kontrollida, kas sellel on mõni lõpetamata rentimine või mitte. Aga sellisel juhul tuleks projektis ka projekteerida ja realiseerida rentimiste register. Selle tegemine poole keelatud, kuid ei ole ka nõutud.Kokkuvõte:  Seda ei pea seisundidiagrammis kajastama, selle pärast ei pea kasutsjuhtude mudelit muutma ja see jääb käesoleva töö skoobist välja. **Märksõnad:** seisundidiagramm, olekumasin ## Küsimus: Töövihiku projekti muutes tekkis küsimus, kui suurt rõhku tuleks panna ainsuse/mitmuse kasutamisele X-i asendamisel? Nt. allsüsteemide juures on isikute, töötajate jne allsüsteemid, loogiliselt võttes tuleks seal asendada X mitmuse vormiga, aga kas see oleks korrektne? Läbivalt on kasutusel muidugi (meie projekti puhul) kaup kui ainsuse vorm, kuid mõned kohad tekitavad segadust, kas panna mitmusesse või ainsusesse. Kuidas sellises olukorras tegutseda? **Vastus:** Öeldakse, et arvutiteaduses on kaks keerulist asja ja nendest üks on nimede andmine. X ainsuse ja mitmuse vormi valikul on oluline järjekindlus – sama tüüpi elemente (nt allsüsteemid, kasutusjuhud, olemitüübid, tabelid) tuleb nimetada ühes stiilis. Minu soovitus on kasutada funktsionaalsete allsüsteemide ja registrite nimetamisel mitmuse vormi (nt kaupade funktsionaalne allsüsteem ja kaupade register) ning olemitüüpide ja tabelite nimetamisel ainsuse vormi (nt Kaup). Kasutusjuhtude korral, kui protsess tegeleb korraga ühe eksemplariga (nt ühe kauba lõpetamine), siis kasutage ainsuse vormi (nt kasutusjuht Lõpeta kaup). Kui protsess tegeleb korraga mitme eksemplariga, siis kasutage mitmuse vormi (nt kasutusjuht Vaata kõiki kaupu). --- # Teema: Vahendid - CASE ## Küsimus: Kas iseseisva töö projektis võib kasutada mõnda muud CASE vahendit kui Enterprise Architect (EA) või Rational Rose (RR)? **Vastus:** Keelatud see ei ole. Kuid palun arvestage järgnevaga. Sõltumata kasutatavast vahendist tuleb lõplikus töös esitada kõik nõutud visuaalsed skeemid e diagrammid: tegevusdiagramm e tegevusskeem, kasutusjuhtude diagramm e kasutusmalliskeem, olemi-suhte diagrammid e olemi-suhte skeemid (tükeldatult nii, et iga registri kohta on eraldi diagramm e skeem), seisundidiagramm e olekumasina mudel, andmebaasi füüsilist disaini esitavad diagrammid e skeemid (tükeldatult nii, et iga registri kohta on eraldi diagramm e skeem). Kui Te ei kasuta EA või RR, siis Te ei saa kasutada töövihiku projekti puhul eelnevalt valmistehtud diagramme ja peate need nullist käsitsi joonistama. Kui Te ei kasuta mõnda andmete modelleerimisele spetsialiseerunud CASE vahendit (näiteks kasutate ArgoUMLi või Cacood), siis Te ei saa kasutada kontseptuaalsest andmemudelist andmebaasi disaini mudeli genereerimise võimalust ja peate andmebaasi disaini mudeli looma nullist käsitsi. Kui Te ei kasuta mõnda andmete modelleerimisele spetsialiseerunud CASE vahendit (näiteks kasutate ArgoUMLi või Cacood), siis Te ei saa kasutada andmebaasi disaini mudelist SQL koodi genereerimise võimalust ja peate SQL koodi tabelite loomiseks kirjutama nullist käsitsi. ## Küsimus: Kas iseseisva töö projekti tegemiseks piisab mõnest andmete modelleerimiseks mõeldud modelleerimisvahendist (nt Vertabelo Data Modeler)? **Vastus:** Lisaks andmebaasi disaini mudelile (mida saab näiteks Vertabelo Data Modeler abil teha) on projektis vaja ka luua: tegevusdiagramm e tegevusskeem (activity diagramm), kasutusjuhtude diagramm e kasutusmalli skeem (use case diagram), paketidiagramm e paketiskeem (package diagram), seisundidiagramm e olekumasinaskeem (state-transition diagram), olemi suhte diagrammid (seal pole välisvõtmeid ega andmebaasisüsteemi spetsiifilisi andmetüüpe) UML klassidiagrammidena e klassiskeemidena (class diagram). Kui vahend nende loomist ei toeta, siis sellest vahendist üksi ei piisa. Kui projekti töövihiku järgi tegemisel Enterprise Architecti või Rational Rose'i mitte kasutada, siis tuleb kõik diagrammid e skeemid luua nullist ja see kulutab rohkem aega võrreldes nendega, kes täiendavad etteantud diagrammi põhju. **Märksõnad:** CASE, modelleerimisvahend, Enterprise Architect, EA, Rational Rose, RR, modelleerimisvahend, UML ## Küsimus: Kuidas käivitada Enterprise Architecti mudeliteisenduste täiendust arvutiklassi arvutites? **Vastus:** Kuna laienduse autor ei teadnud installeerimise programmi loomisel kõiki tsentraalse installeerimise eripärasid, siis on selle laienduse korrektseks tööle hakkamiseks vaja arvutiklassi arvutis (kas kohapeal olles või kaugkasutuse korral kasutades) käivitada reg.reg fail. Seda saavad üliõpilased oma konto alt ise teha. Pärast seda, peale EA taaskäivitamist, hakkab laiendus tööle. Isiklikule arvutile installeerides seda pole vaja teha - peaks koheselt töötama, kui olete juhendis olevat installeerimise protseduuri järginud.Mingil põhjusel funktsioneerib see mudeliteisendus vaid osades arvutiklassi arvutites. Seega, kui see ühes ei tööta proovige teist. **Märksõnad:** kaugkasutus ## Küsimus: Kuidas ma saan Enterprise Architect 12 vahendis MS Accessi andmebaasi kirjeldavas füüsilise disaini mudelis kasutada veeru tüübina Decimal? **Vastus:** Kui andmetüüpi ei ole disaini mudelis veeru andmetüüpide valikus, siis saab teha järgnevat. Valige menüüst Project => Settings => Database Datatypes Avanenud aknas valige liitboksist Product Name: "MS Access" Lisage uus andmetüüp järgnevate andmetega (vaadake ka vastusele lisatud faili) Datatype: Decimal Common type: decimal Precision & scale: Default: 28, 13; Max: 28 Maksimaalne väärtus 28 näitab seda, et maksimaalne numbrikohtade arv MS Accessi Decimal tüüpi väärtuses on 28 Precision e täpsus - maksimaalne numbrikohtade arv Scale e skaala - kohtade arv peale koma Vajutage nupule Save. Kui Te nüüd kirjeldate MS Accessi andmebaasi tabeleid ja valite andmetüübiks Decimal, siis vaikimisi pakutakse täpsuseks ja skaalaks 28 ja 13, kuid seda valikut saab tabeli veergude kirjelduse juures muuta (vaadake ka vastusele lisatud faili). ## Küsimus: Kuidas on võimalik Rational Rose'ist eksportida mõni diagramm bmp/jpg/gif/png kujul? **Vastus:** Diagrammi dokumenti kopeerimiseks pole seda vaja teha. Piisab, kui teete diagrammi aktiivseks, valite klaviatuurilt Ctrl+A (vali kõik diagrammi elemendid), Ctrl+C (kopeeri) ning dokumendis valite Ctrl+V (kleebi). Kui see mingil põhjusel ei sobi, siis näiteks Windowsi puhul võib kasutada spetsiaalset operatsioonisüsteemiga kaasa tulevat abiprogrammi (Windows Snipping Tool). ## Küsimus: Kuidas parandada Enterprise Architect CASE vahendis loodud andmebaasi disaini mudelis riknenud tabelite vahelist seost? **Vastus:** Vaadake palun SEDA videot või vastusele lisatud faili.Kui vaatamata kõigele ei õnnestu seose kirjeldust parandada, siis jätke see nii nagu on ja tehke parandus genereeritud SQL koodis. **Märksõnad:** välisvõti, foreign key, fk, võõrvõti, viga, andmebaasi disaini mudel, katki, katkine, kirjeldus ## Küsimus: Kuidas teha nii, et Enterprise Architect 12 vahendis ei genereeritaks MS Accessi andmebaasi disaini mudeli põhjal koodi, mida peab käsitsi parandama? **Vastus:** Tuleb muuta malle (template), mille põhjal koodi genereeritakse. Malle tuleb muuta eraldi iga faili puhul, milles olevast mudelist soovitakse koodi genereerida.Järgnevad probleemid esinevad nii EA12-ga kui ka EA16-ga vaikimisi kaasa tulevates mallides.Mallide vaatamiseks ja muutmiseks valige Package=>Database Engineering=>Edit DDL TemplatesSeejärel valige liitboksist Language andmebaasisüsteem - antud juhul MSAccess. Malli muutmise järel tuleb salvestamiseks selle juures vajutada Save nupule või vajutada Ctrl+S.1. Kuidas teha nii, et genereeritud koodis poleks andmebaasiobjektide identifikaatorid e nimed nurksulgudes? Näiteks lause CREATE TABLE [Riik] (... asemel tahaksin lauset CREATE TABLE Riik (....Valige mall DDL Left Surround ja kustutage sealt avav nurksulg ([). Ärge ridu kustutage.Valige mall DDL Right Surround ja kustutage sealt sulgev nurksulg (]). Ärge ridu kustutage.2. Kuidas teha nii, et genereeritud koodis oleksid andmebaasi disaini mudelis kirjeldatud vaikimisi väärtused, välisvõtmete kompenseerivad tegevused, CHECK kitsendused, veeru tüüp DECIMAL ja et indeksi loomise lauses oleks tabeli nimi.Selleks laadige alla selle vastusega seotud fail ning muutke oma mudelifailis järgmised mallid selliseks nagu need on selles failis. Jälgige, et iga malli lõpus oleks tühi rida. Kui klõpsate EA-s mallide nimekirjas veerul Name, siis saate need tähestiku järgi sorteerida. DDL Check Constraint DDL Column Definition DDL Create Table DDL Data Type DDL Index DDL Reference Definition DDL Script File **Märksõnad:** parandatud, mall, template, koodi genereerimine, generaator, SQL ## Küsimus: Kuidas toimida, kui kasutan Enterprise Architect 12 vahendit, soovin MS Accessi andmebaasi disaini mudelis määrata veeru tüübiks Decimal, kuid seda tüüpi ei ole pakutavate tüüpide valikus? **Vastus:** Project => Settings => Database Datatypes Sealt alt saaks lisada uusi andmetüüpe, mida andmebaasi disaini mudelis kasutada. Valige avanenud aknas Product Name: MS AccessPeate määrama baastüübi (Common Type) (saate valida decimal), täpsuse+skaala ja peate andma tüübile nime. Seejärel tuleb vajutada Save nupule.Decimal tüüpi veerg on mõeldud kümnendmurdude e püsikomaarvude registreerimiseks. Kasutage seda kui on vaja registreerida komakohtadega arve ning on teada maksimaalne kohtade arv peale koma. Kui  Te just ei tegele teadusmõõtmiste andmete registreerimisega, siis peakski komakohtadega arvude registreerimisel kasutama Decimal tüüpi. Sõltuvalt ujukomatüüpi andmete sisemise salvestamise viisist võivad nende puhul tekkida koondandmete leidmisel ümardamise vead.Muide, sellisel juhul peaks kontseptuaalses andmemudelis vastava atribuudi definitsioonis olema kirjas, kui palju komakohti on vaja.Decimal tüübi kasutamise puhul tuleb ära määrata täpsus (precision) ja skaala (scale). precision määrab ära maksimaalse numbrikohtade arvu ja skaala kohtade arvu peale koma. Näiteks veerus, mis on tüüpi Decimal (3,1), saab olla maksimaalne väärtus 99.9 ja minimaalne väärtus -99.9 (kolm numbrikohta, üks peale koma). **Märksõnad:** kümnendmurd, püsikomaarv, ujukomaarv, MSAccess ## Küsimus: Kui Enterprise Architect (EA) ei luba töötada DDLenhace-ga ja mudeli disain tuleb teha DDL-ga, siis kuidas kontrollida millised parameetrid peavad olema kohustuslikud ja millised PK või FK ning millistel parameetritel peab olema vaikimisi väärtus? **Vastus:** Atribuutide alusel tekkivate veergude kohustuslikkus Atribuutide definitsiooni tabelis (jaotises 2.2.1 - peale olemi-suhte diagramme ja olemitüüpide definitsioone) peab iga atribuudi puhul kitsenduste osasse kirjutama, kui see on kohustuslik, st selle väärtus peab olema alati määratud - {Registreerimine on kohustuslik.} Lisaks tuleb Enterprise Architecti abil tehtud olemi-suhte diagrammides ära näidata, millised atribuudid on kohustuslikud (võimsustik (multiplicity) 1) ja millised mittekohustuslikud (võimsustik 0..1). Kui teisendate kontseptuaalse andmemudeli SQL-andmebaasi disaini mudeliks, siis laias laastus vastab igale atribuudile eraldi tabeli veerg. Kui atribuut on kohustuslik, siis vastavale veerule tuleb deklareerida NOT NULL kitsendus. Kui atribuut ei ole kohustuslik, siis seda kitsendust ei ole. Kontseptuaalse andmemudeli mallis olevatest atribuutidest on mittekohustuslikud: Isik.eesnimi Isik.perenimi Isik.elukoht Amet.kirjeldus Ülejäänud atribuudid on kohustuslikud (st vastavatel veergudel peab olema NOT NULL). Võimalik, et lisatud X atribuutide hulgas on ka mõni mittekohustuslik (nt kirjeldus või kommentaar), kuid see valik on juba Teie teha. Seosetüüpide alusel tekkivate veergude kohustuslikkus Mis puudutab välisvõtme veergude kohustuslikkust, siis see sõltub seosetüübi võimsustikest (multiplicity). Näide: [Riik]-1-+isikukoodi riik-----------0..*-[Isik] Iga isik on seotud täpselt ühe isikukoodi riigiga. Järelikult tabelisse Isik tekkival välisvõtme veerul riik_kood peab olema NOT NULL kitsendus. [Riik]-0..1-+isikukoodi riik-----------0..*-[Isik] Iga isik on seotud nulli või ühe isikukoodi riigiga. Järelikult tabelisse Isik tekkiv välisvõtme veerg riik_kood võib lubada NULLe. Malli järgi projekti tehes peaks kõikidele välisvõtme veergudele deklareerima NOT NULL kitsenduse. Vaikimisi väärtused Vaikimisi väärtused on mugavusvahend, juhuks, kui paljudes/kõigis uutes ridades on ühesugune väärtus või ühesugusel viisil leitav väärtus. Vaikimisi väärtus ei ole kitsendus - sellest saab alati jõuga üle sõita. Malli järgi tehtavas projektis peaksid olema järgmised vaikimisi väärtused. Välisvõtme veergudel, mis viitavad seisundiklassifikaatorite tabelitele (Isiku_seisundi_liik, Tootaja_seisundi_liik, Kliendi_seisundi_liik, X_seisundi_liik) - väärtus, mis näitab esimesena saadava seisundi koodi. Näiteks X korral on selleks seisundile "ootel" vastav kood, sest seisundidiagrammi alusel (vt jaotis 2.2.3) läheb iga X kõigepealt seisundisse "ootel". Need vaikimisi väärtused peavad olema tabelites Isik, Tootaja, Klient, X. Isik.reg_aeg ja X.reg_aeg - avaldis, mille poole pöördumisel tagastatakse hetke kuupäev ja kellaaeg (näiteks MS Accessis Now()). Klient.on_nous_tylitamisega - FALSE - tulenevalt vaikimisi andmekaitse põhimõttest. Primaarvõtmed Hästi kavandatud SQL-andmebaasi tabelis tuleb jõustada kõik kandidaatvõtmed - üks primaarvõtmena (PRIMARY KEY kitsendus) ülejäänud alternatiivvõtmetena (UNIQUE+NOT NULL kitsendus). Kontseptuaalses andmemudelis tuleb atribuutide definitsiooni kirja panna, kui mingi atribuut või atribuutide kombinatsioon on unikaalne identifikaator. Primaarvõti tuleb kas jõustada ühele nendest vastavate veergude alusel või defineerida surrogaatvõti. Surrogaatvõtme väärtused on süsteemi poolt genereeritud unikaalsed täisarvud, mida kasutatakse olemitele viitamiseks ainult tarkvarasüsteemi siseselt, mitte inimeste maailmas. Malli alusel tehtavas projektis on surrogaatvõti mõistlik ainult tabelis Isik - (isik_id). Ülejäänud tabelites saab valida sisulise võtme - näiteks tabelis Riik (riik_kood), tabelis X (X_kood) jne. Tabelites Klient ja Tootaja peaks primaarvõti (isik_id) kokku langema välisvõtmega, mis viitab tabelile Isik. Välisvõtmed Üks-mitmele seosetüübi korral tekib välisvõti mitu poolel olevasse tabelisse. [Riik]-1-+isikukoodi riik-----------0..*-[Isik] - välisvõti on tabelis Isik. Mitu-mitmele seosetüübi korral tekib vahetabel koos kahe välisvõtmega. **Märksõnad:** teisendus, mudeliteisendus, DDLEnhanched, DDL_enhanced ## Küsimus: Kui Enterprise Architecti litsentsi kehtivus lõpeb, siis kuidas saada litsents uuesti? **Vastus:** Litsents kehtib 10 nädalat. Litsentsi uuesti laenutamine toimub samamoodi nagu litsentsi algselt laenutamine: sulgege EA, käivitage sisseloginud tavakasutaja õigustes bat fail, looge FortiClient VPN ühendus, käivitage EA. **Märksõnad:** vpn ## Küsimus: Kui mina muudan näiteks kaupade registri diagrammis klassi seost, siis mina pean uuesti genereerima SQL tabelite disaini kirjelduse? **Vastus:** Teil tuleb tagada kontseptuaalse andmemudeli, andmebaasi füüsilise disaini kirjelduse ja valmistehtud tabelite kooskõla. Selle saavutamiseks on erinevaid strateegiaid, uuesti genereerimine on nendest üks. Arvan, et kui muudatus kontseptuaalses andmemudelis ei ole väga suur, siis tulenevalt kasutatavate CASE vahendite tehnilistest piirangutest, võib muuta kontseptuaalset andmemudelit, siis muuta käsitsi andmebaasi füüsilise disaini kirjeldust ning siis genereerida uuesti SQL kood. ## Küsimus: Kui mul on Enterprise Architect (ver 12) CASE vahendis loodu mudelis Isiku klass koos atribuutidega Isikute registris, aga sooviksin teistes registrites nt Klientide registris seda klassi ilma atribuutideta kuvada, siis kuidas seda teha? **Vastus:** Aktiveerite klassi => parem hiireklõps Features and Properties => Feature and Compartment Visibility. Avanenud aknas eemaldate ülevalt vasakult nurgast linnukesed valikute "Attribute Visibility => All" ja "Operation Visibility => All" eest. **Märksõnad:** olemi-suhte diagramm, refaktoreerimine ## Küsimus: Kumba CASE vahendit eelistada projekti tegemiseks - kas Enterprise Architect (EA) või Rational Rose (RR)? **Vastus:** Mõlemad vahendid on projekti tegemiseks sobivad. Järgnevalt tuuakse esile kummagi tugevad küljed võrreldes teisega. EA eelised RR ees Palju uuem, ettevõtetes rohkem kasutusel 2018. aastal avaldatud ettevõtte arhitektuuri hetkesesisu uuringu kohaselt oli EA ülekaalukalt kõige populaarsem ettevõtte arhitektuuri modelleerimise vahend. Toimetaja hinnangul oli selle vahendi hind selline, et see sobib kasutamiseks paljudes erinevat tüüpi organisatsioonides. 2020. aastal avaldatud uuringu kohaselt (109 vastajat) oli EA kõige populaarsem UML keeles visuaalsete mudelite koostamise vahend sõltumata loodavate mudelite tüüpidest ja eluvaldkonnast, kus vastajad toimetasid. Näiteks funktsionaalsuste modelleerimiseks kasutas seda 53% vastajatest. Andmete modelleerimiseks kasutas seda 45% vastajatest ning teisi UML modelleerimisvahendeid selle ülesande jaoks peaaegu ei kasutatud. Installeerimine ja litsentsi hankimine lihtsam Võimalused luua palju rohkem erinevat tüüpi mudeleid (kuid selles aines ei lähe neid vaja) Võimalik programmeerida juurde laiendusi. Kahte täiendust võiksite proovida kasutada - vaadake palun ja proovige installeerida Tarkvara/EA mudeliteisenduse täiendus Tarkvara/EA klassidiagrammist inimkeelsed laused Andmebaasi disaini mudeli saab luua spetsiifiliselt PostgreSQL või MS Accessi jaoks Semestri alguses loengus projekti tehes kasutan EA-d (samas on RR kasutamise kohta olemas videod) Töövihiku järgi tehtud näiteprojekt on tehtud EA-s, st selle mudelite vaatamiseks on vaja EA-d RR eelised EA ees Litsentsi ei pea 10 nädala tagant värskendama Vähem funktsionaalsust (selleks aineks kõik vajalik olemas), kuid tänu sellele ka lihtsam ja kiiremini kasutatav kasutajaliides Kaasa tulev genereerimismoodul, mis tekitab kontseptuaalsest andmemudelist füüsilise SQL-andmebaasi disaini mudeli, on parem (disaineril on hiljem vaja teha vähem käsitsi muudatusi) Väga palju lihtsam ja kiirem on muuta SQL-andmebaasi disaini kirjeldustes välisvõtmeid - tegevus, mida on vaja päris palju teha Genereeritav SQL kood on lihtsamini käivitataval ja loetaval kujul - koodi tuleb vähem käsitsi muuta Mõlema vahendi nõrkused Fail võib rikneda, mis tähendab, et eelnev töö läheb kaotsi SQL lausete generaator teeb vaikimisi vigu (EA puhul on Teile välja jagatud mallides mitmed vead ära parandatud. Seda sai teha, sest EA puhul saab muuta malle, mille alusel vahend andmebaasi disaini mudelist SQL koodi genereerin) SIIN kataloogis on viited videotele Rational Rose kasutamise kohta. Seal on paralleelselt näha nii Rational Rose kasutamist kui on räägitud ka loogikast loodud mudelite taga. SIIN on demonstratsiooni käigus loodud tulemid (mudelid, SQL kood, loodud andmebaas). Slaidiesitlus, mille teises pooles antakse ülevaade EA ja RR probleemidest seoses andmete modelleerimisega. Rational Rose eestikeelne juhend.NB! Ülikooli vahendusel litsentsi saamise võimalus on vaid ülikooli pakutud tarkvara versioonidele. Tarkvara tegijate kodulehelt või kuskilt mujalt võrgust alla laaditud tarkvara (uuematele) versioonidele see võimalus ei laiene. ## Küsimus: Ma ei suuda Enterprise Architect (EA) vahendi menüüde rägastikus orienteeruda. Millised on kõige olulisemad menüüpunktid antud aine jaoks? **Vastus:** Järgnevalt on nimetatud EA12 näitel mõnede oluliste funktsioonide asukoht menüüsüsteemis. Tööriistakast, kust saab valida mudelisse lisamiseks uusi elemente. Kui olete selle kinni pannud, siis saate uuesti avada: Diagram=>Toolbox (kiirkorraldus ALT+5) Projekti elementide hierarhia. Kui olete selle kinni pannud, siis saate uuesti avada: View=>Project Browser (kiirkorraldus ALT+0) Andmebaasi disaini mudeli loomiseks mõeldud täiustatud teisenduse kasutusele võtmine: Project=>Data Management=>Import Reference Data Enne andmebaasi disaini mudeli teisenduse abil loomist tuleb määrata, millise andmebaasisüsteemi jaoks disaini mudel luuakse: Project=>Settings=>Database Datatypes Avanenud aknas tuleb soovitud andmebaasisüsteemi juures märkida Set as Default Mudeliteisendus kontseptuaalsest andmemudelist andmebaasi disaini mudeliks: Package=>Model Transformation (MDA)=>Transform Current Package SQL koodi genereerimine: Package=>Database engineering=>Generate package DDL ## Küsimus: Meil tekkis andmebaasi füüsilise disaini mudeli genereerimisega probleem: veerg nimega kood esineb mitmes kohas. Milles võib olla probleem? **Vastus:** See probleem tekib Enterprise Architecti (EA) täiendatud mudeliteisenduse kasutamise korral. Tekib, sest ka EA täiendatud mudeliteisendus pole paraku ideaalne. Konkreetne põhjus on selles, et kontseptuaalses andmemudelis on olemitüüp Klassifikaator, millel on atribuut kood. Klassifikaatoril on palju alamtüüpe (Riik, Amet, Töötaja_seisundi_liik jne) millest igaühe põhjal luuakse eraldi tabel. Kõikidesse nendesse tekib teisenduse tulemusena primaarvõtme veerg kood. See veeru nimi tuleb ära muuta nii klassifikaatorite tabelites kui ka tabelites, kuhu koodid lähevad välisvõtmeks. Näiteks kui tabelis Amet on veerg kood, siis selle uus nimi võiks olla amet_kood. Kui tabelis Töötaja on välisvõtme veerg kood, milles olevad andmed viitavad ridadele tabelis Amet, siis ka sellele veerule tuleb anda nimi amet_kood. Järgnevalt esitan soovitusliku parandamise algoritmi. Kõigepealt terminoloogiast: [Amet]-1--------0..*-[Töötaja] Välisvõti on tabelis Töötaja Amet - primaarne tabel, antud juhul klassifikaatori tabel Töötaja - sõltuv tabel 1. Juhul kui sõltuvas tabelis on täpselt üks välisvõtme veerg nimega kood (näiteks töövihiku kasutamise korral Klient). Muuda primaarvõtme veeru nime klassifikaatori tabelis (näiteks tabelis Kliendi_seisundi_liik: kood=> kliendi_seisundi_liik_kood). Muuda vastavat välisvõtme veeru nime sõltuvas tabelis (antud juhul tabelis Klient: kood=> kliendi_seisundi_liik_kood). 2. Juhul kui sõltuvas tabelis on rohkem kui üks välisvõtme veerg nimega kood (näiteks töövihiku kasutamise korral Töötaja). Kustuta sõltuvast tabelist kõik välisvõtme kitsendused, mis viitavad klassifikaatorite tabelitele (näiteks kaks kitsendust tabelist Töötaja). Muuda primaarvõtme veeru nime kõikides asjassepuutuvates klassifikaatori tabelites (näiteks tabelis Amet: kood=> amet_kood; tabelis Töötaja_seisundi_liik: kood=> töötaja_seisundi_liik_kood). Muuda vastavate välisvõtme veergude nimesid sõltuvas tabelis (antud juhul tabelis Töötaja: kood=> amet_kood; kood=> töötaja_seisundi_liik_kood ). Loo välisvõtme kitsendused mudelis käsitsi uuesti. ## Küsimus: Mida teha, kui arvutiklassi arvutis küsib Enterprise Architect (EA) avamisel võtit ja ei ole nõus ilma selleta käivituma? **Vastus:** Sulgege EA. Valige: Control Panel => System and Security => Configuration Manager => Configurations => evaluate CB WRK Enterprise Achitect Key Seejärel avage EA uuesti. **Märksõnad:** litsents, värskendamine, laenutamine, arvutiklass ## Küsimus: Mul registrite analüüsi mudel loodud. Pärast andmebaasi disaini mudeli nagu videos õppeaine kodulehel. Kokku kõik on korras, aga tekib tõsine probleem. CASE vahend ehitab seosed Kliendi, Ameti, Treeningu ja Töötaja seisundi liigi vahel. Aga ei peaks ja ma ei taha. Mida teha? **Vastus:** Arvan, et põhjuseks on analüüsi mudelisse kogemata tehtud ja korralikult kustutamata jäänud valed seosed. Konkreetsel juhul võtke palun lahti analüüsi mudelis klientide registri olemi-suhte diagramm ja lohistage sellele mudelist olemitüübid (klassid) Amet, Töötaja_seisundi_liik ja Treening. Kui selle tulemusel tekivad diagrammile ka seosed Kliendiga, siis kustutage need seosed. Seose mudelist kustutamiseks tehke: Enterprise Architect (EA) CASE vahendis seos aktiivseks; valige parema hiire klahvi alt hüpikmenüüst "Delete connector" või vajutage Delete klahvile; valige "Delete the connector from the model". Rational Rose (RR) CASE vahendis seos aktiivseks; valige parema hiire klahvi alt hüpikmenüüst "Edit" => "Delete from Model". Seejärel genereerige andmebaasi disaini mudel uuesti. Samuti eemaldage klientide registri olemi-suhte diagrammilt Amet, Töötaja_seisundi_liik ja Treening. Kuna kasutate analüüsi mudelit uue tehise (disaini mudeli) genereerimiseks, siis on väga oluline, et analüüsi mudelisse ei jääks "prügi". ## Küsimus: Rationa Rose-il pole menüüs punkti Data Modeler => New => Database, millega genereerida andmebaasi füüsilise disaini mudelit. Mis on valesti? **Vastus:** Selleks, et saaksite kasutada Rational Rose'i (2007) Data Modeleri, peab arvutis eelnevalt olema installeeritud .NET Framework redistributable (ver. 1.1) või kõrgem Installige enne .NET ja siis Rational. ## Küsimus: Soovin Enterprise Architect 12 vahendis genereerida SQL lauseid, kuid lausete genereerimise aknas ei saa ma muuta tabelite järjekorda genereeritavas skriptis (nupud järjekorra muutmiseks ei tööta). Mida teha? **Vastus:** Jah, see on EA probleem, mida mõnikord tuleb ette.Küsimus on selles, et kui mul on tabelite loomise kood, milles välisvõtmete deklareerimine on osa CREATE TABLE lausest, siis on lausete käivitamise järjekord oluline.CREATE TABLE A(a_id INTEGER,CONSTRAINT pk_a PRIMARY KEY (a_id));CREATE TABLE B(b_id INTEGER,a_id INTEGER NOT NULL,CONSTRAINT pk_b PRIMARY KEY (b_id),CONSTRAINT fk_b_a FOREIGN KEY (b_id) REFERENCES B(b_id));Kõigepealt tuleb luua tabel A ja siis saab luua tabeli B.EA vahendis saab koodi genereerimisel määrata tabelite loomise lause järjekorra. See on oluline, kui koodi genereerimisel on määratud: Options=>Separate Constraints from Tables=False Mida EA vahendis teha, kui selline probleem esineb? Proovida liigutada nimekirjas suvalisi tabeleid üles/alla. Mõnikord see justkui lukustab nimekirja lahti ja ka tabeleid, mida seni ei saanud nimekirjas üles/alla liigutada, saab peale seda liigutada. Siiski on suur tõenäosus, et see ei aita. Viia järjekord soovitule nii lähedaseks kui saab, genereerida SQL laused ja muuta genereeritud koodis lausete järekorda käsitsi. Valige Options=>Separate Constraints from Tables=True ning genereerida kood, kus tabeli loomise lausete järjekord ei ole oluline. ## Küsimus: Üritan Mauruse keskkonnas taotleda uut Enterprise Architect programmi litsentsi. Olen kunagi EA litsentsi juba taotlenud, seega saan veateate, et "Te olete seda ressurssi juba taotlenud". Mida teha? **Vastus:** Uuesti ei saagi taotleda, sest üks taotlus on olemas, rahuldatud ja endiselt kehtiv. Pääsete rahuldatud taotlustele vastavatele failidele ligi "Minu taotlused" alt. Sealt saate nii failid, millega EA enda arvutisse installeerida kui ka litsentsi taotlemiseks mõeldud bat faili. Tallinna Tehnikaülikooli ruumides saab laenutamist teha üle Wi-Fi. Väljaspool ülikooli tuleb enne laenutamist luua FortiClient VPN ühendus. Litsentsi aegumise järel tuleb laenutamist korrata. Veenduge, et Enterprise Architect (EA) on suletud, käivitage bat fail ning avage EA, veendumaks, et litsents on laenutatud ning programm avaneb. **Märksõnad:** vpn --- # Teema: Vahendid - MS Access ## Küsimus: Kas ja millised on MS Accessi eelised SQLi õppimisel? **Vastus:** SQL andmekäitluskeele lausete (SELECT, INSERT, UPDATE, DELETE) koostamiseks saab kasutada graafilist kasutajaliidest - Query Designer. See graafiline kasutajaliides realiseerib visuaalse andmebaasikeele Query by Example. Võimalik on tõlkida lauseid ühest keelest (SQL ja Query by Example) teise. Siit saab vaadata videoid Query by Example abil päringute koostamisest. Tabelites on läbi graafilise kasutajaliidese lihtne teha andmemuudatusi. Nii saab kergelt teha andmemuudatusi, kontrollimaks, et koostatud SQL laused annavad igas olukorras oodatud tulemuse. MS Accessi SQLi mägimurrak ei ole nii suurte võimalustega kui võimekamatel SQL-andmebaasisüsteemidel, kuid kõik põhiline on olemas. Näiteks lendama õppimisel ei alustata praktiseerimist ka mitte kohe reisi- või sõjalennukist, vaid kõigepealt saavutatakse põhjendatud enesekindlus väikesel lennukil ja sellega sillutatakse teed aina suuremate lennukitega lendamiseks. PostgreSQL ja Oracle lisavõimalusi võib vaadata lisamaterjalide lehelt (kasutajanimi: SIS2 ja parool: SIS2) SIIT. ## Küsimus: Kas MS Accessis tuleks hoiduda Decimal tüübi kasutamisest? **Vastus:** Ei!Kui loete soovitusi (nagu see siin), siis pöörake tähelepanu millise süsteemi versiooni kohta need on. See konkreetselt on vana versiooni kohta ning vähemalt MS Access 2019 ja uuemates ei kehti. Tehke katse. Käivitage oma andmebaasis ükshaaval järgmised laused:CREATE TABLE Decimal_test (v DECIMAL (3,2));INSERT INTO Decimal_test (v) VALUES (1.0);INSERT INTO Decimal_test (v) VALUES (-1.0);INSERT INTO Decimal_test (v) VALUES (-3.22);INSERT INTO Decimal_test (v) VALUES (-1.01);INSERT INTO Decimal_test (v) VALUES (0);Seejärel proovige päringut:SELECT * FROM Decimal_testORDER BY v;Päringu tulemuses on sorteerimisega on kõik korras. **Märksõnad:** MSAccess ## Küsimus: Kirjutan MS Accessi päringus ajahetke esitava stringi niimoodi - '31.12.2010 23:59:59' - ja saan vea. Kuidas on õige ajatemplit esitavat väärtust kirja panna? **Vastus:** MS Accessis tuleb ajatemplit esitav string e sõne (märkide jada) kirjutada formaadis - #YYYY-MM-DD HH24:MI:SS#Kasutage ISO 8601 standardis kirjeldatud formaati.Näide: #2100-12-31 23:59:59#See on 31. detsember 2100 kell 23:59:59.SELECT *FROM ReserveerimineWHERE lopu_aeg<#2010-12-31 23:59:59#;Alternatiiviks on kasutada funktsiooni DateValue.SELECT *FROM ReserveerimineWHERE lopu_aeg<DateValue('31.12.2010 23:59:59');Võrdluseks - PostgreSQLis.SELECT *FROM ReserveerimineWHERE lopu_aeg<'2010-12-31 23:59:59';SELECT *FROM ReserveerimineWHERE lopu_aeg<to_date('31.12.2010 23:59:59', 'DD.MM.YYYY HH24:MI:SS');to_date funktsiooni esimene argument on ajahetke esitav string ja teine argument on muster, mis ütleb süsteemile, kuidas seda interpreteerida. **Märksõnad:** PostgreSQL ## Küsimus: Kuidas jõustada MS Accessis kitsendus, et isikukood peab koosnema ainult tähtedest, numbritest, tühikutest, sidekriipsudest, plussmärkidest, võrdusmärkidest ja kaldkriipsudest? **Vastus:** MS Access ei paku täielikku toetust regulaaravaldiste kasutamisele, kuid selle LIKE predikaadi mustrite koostamise võimalusi on laiendatud regulaaravaldistest tuntud võimalustega. Kui on valitud File => Options => Object Designers => Query design => SQL Server Compatible Syntax (ANSI 92) => This database(Fail => Suvandid => Objektikujundajad => Päringu kujundus => SQL Serveriga ühilduv süntaks (ANSI 92) => See andmebaas), siis * asemel tuleb kasutada % ja ? asemel _MS Accessi andmebaasi saab lokaliseerida (konkreetse keele keskkonnaga kohandada), määrates andmebaasis tekstiliste väärtuste sorteerimiseks kasutatava keele:Fail=>Suvandid=>Üldist=>Uue andmebaasi sortimisjärjestusFile=>Options=>General=>New database sort orderKonkreetse andmebaasi puhul kasutatav keel määrab, milliste märkide vahemikku tuleks mustri koostamisel kasutada. Eesti tähestiku esimene täht on A ja viimane täht on Y. Kui andmebaasis on sorteerimise keeleks eesti keel, siis lisan tabelis Isik veerule isikukood valideerimisreegli:Not ALike '%[!A-Y0-9 +=/\-]%'Isikukood ei tohi olla selline, kus sisaldub mõni lubatud märkide hulka mittekuuluv märk. Hüüumärk tähistab Accessis selles kontekstis eitust - ei kuulu loetletud märkide hulka.[!A-Y0-9 +=/\-]Nii tähistatakse märkide hulka, kuhu kuulub üks märk. Selles märkide hulgas on kõik märgid, mis ei ole tähemärgid, numbrimärgid, tühik, plussmärk, võrdusmärk, kaldkriips, sidekriips.Kui andmebaasis on sorteerimise keeleks määratud general e inglise keel, siis lisan tabelis Isik veerule isikukood valideerimisreegli, sest inglise tähestiku esimene täht on A ja viimane Z:Not ALike '%[!A-Z0-9 +=/\-]%'Võrdluseks - PostgreSQLis ja Oracles tuleks kasutada regulaaravaldist '^[[:alnum:] +=-\/\]*$'. Alates stringi algusest (^) kuni lõpuni ($) peab selles olema null või rohkem(*) nurksulgudes kirjeldatud märkide hulka kuuluvat märki. [[:alnum:]] on eeldefineeritud märkide klass, kuhu kuuluvad tähed ja numbrimärgid. PostgreSQLis oleks CHECK kitsenduse tingimus  isikukood~'^[[:alnum:] +=-\/\]*$' ~ on operaator tõstutundlikuks (case sensitive) regulaaravaldise mustrile vastavuse kontrollimiseks.Oracles oleks CHECK kitsenduse tingimus REGEXP_LIKE(isikukood,'^[[:alnum:] +=-\/\]*$')REGEXP_LIKE on funktsioon regulaaravaldise mustrile vastavuse kontrollimiseks. **Märksõnad:** valideerimisreegel, check, validation rule, PostgreSQL, Oracle ## Küsimus: Kuidas jõustada MS Accessis kitsendus, et kui üks ja sama töötaja omab ühte ja sama rolli mitu korda, siis ei tohi rolli omamise ajaperioodid kattuda? **Vastus:** Saan jõustada nõrgema kitsenduse, mille kohaselt andmete registreerimise hetke seisuga ei tohi ühel ja samal töötajal olla ühe ja sama rolli kohta rohkem kui üks kehtiv rolli omamine. Kehtiv rolli omamine on selline, mille puhul hetke aeg jääb rolli omamise alguse ja lõpu aja vahele. Seega, kui töötajal 1 on 01.01.2022 kuni 01.01.2023 roll koodiga 3, siis ei saa 06.01.2022 lisada sellele töötajale teist rolli 3 omamist vahemikuks 01.05.022 kuni 01.05.2023.ALTER TABLE Tootaja_rolli_omamineADD CONSTRAINT chk_tootaja_rolli_omamine_unikaalsusCHECK (NOT EXISTS(SELECT isik_id, tootaja_roll_koodFROM Tootaja_rolli_omamineWHERE Now() BETWEEN alguse_aeg AND lopu_aegOR (alguse_aeg<=Now() AND lopu_aeg IS NULL)GROUP BY isik_id, tootaja_roll_koodHAVING Count(*)>1));MS Accessis, erinevalt paljudest teistest andmebaasisüsteemidest, saab CHECK kitsenduses kasutada alampäringut. SQL standard ei luba CHECK kitsendustes kasutada mittedeterministlikku funktsiooni. Selline funktsioon tagastab samade argumentidega väljakutsudes erinevatel hetkedel erineva tulemuse. Now() on mittedeterministlik funktsioon.MS Access (aga ka näiteks PostgreSQL) lubavad CHECK kitsendustes selliseid funktsioone kasutada.Võrdluseks - PostgreSQLis saab küsimuses nimetatud piirangu jõustada täielikult. Selleks tuleb luua EXCLUDE kitsendus. EXCLUDE kitsendus on unikaalsuse kitsenduse edasiarendus, mille puhul saab väärtuste unikaalsuse e kordumatuse kontrollimiseks kasutada ka mõnda muud operaatorit kui võrdsuse kontrolli operaator (=), mida kasutab UNIQUE kitsendus. Vaadake täpsemat näidet slaidikomplektist. Otsige sealt fraasi "Kattuvate perioodide vältimine". **Märksõnad:** valideerimisreegel, check, validation rule, PostgreSQL ## Küsimus: Kuidas jõustada MS Accessis kitsendus, et meiliaadress on isiku tõstutundetu unikaalne identifikaator? **Vastus:** Tõstutundetu unikaalsus tähendab näiteks, et kui süsteemis on registreeritud isiku meiliaadress Mati@mets.ee, siis mõnele teisele isikule meiliaadressi mati@mets.ee registreerida ei saa.Tõstutundetu unikaalsuse jaoks MS Accessis piisab kui defineerite unikaalsuse kitsenduse. MS Access, erinevalt paljudest teistest andmebaasisüteemidest, kasutab tõstutundetut stringide võrdlemist.Seega näiteksSELECT *FROM IsikWHERE perenimi='METS';leiab nii isikud perenimega mets, Mets kui ka METS. Unikaalsuse e kordumatuse kontrollimisel kasutatakse väärtuste võrdlemist. MS Accessi jaoks on järgnev tõene väide: Mati@mets.ee=mati@mets.eeSeega veerus e_meil ei saa need väärtused samaaegselt olla.Võrdluseks - PostgreSQLis ja Oracles on unikaalsuse kontroll vaikimisi tõstutundlik, st Mati@mets.ee<>mati@mets.ee ja erinevatel isikutel võivad sellised meiliaadressid olla registreeritud.PostgreSQLis tuleks sellise reegli jõustamiseks luua kas funktsioonil (upper või lower) põhinev unikaalne indeks või EXCLUDE kitsendus. EXCLUDE kitsendus on unikaalsuse kitsenduse edasiarendus, mille puhul saab väärtuste unikaalsuse e kordumatuse kontrollimiseks kasutada ka mõnda muud operaatorit kui võrdsuse kontrolli operaator (=), mida kasutab UNIQUE kitsendus. Oracles tuleks luua funktsioonil (upper või lower) põhinev unikaalne indeks.Ei indekseid ega ka EXCLUDE kitsendust SQL standard ette ei näe, st tegemist on võimalustega, mis on spetsiifilised konkreetsele andmebaasisüteemidele. **Märksõnad:** PostgreSQL, Oracle ## Küsimus: Kuidas jõustada MS Accessis kitsendus, et mittelõpetatud tubade nimetused peavad olema unikaalsed? **Vastus:** Kui andmebaasis defineerida tabelis Tuba unikaalsuse kitsendus UNIQUE (nimetus), siis on nimetus globaalselt unikaalne. Seega, kui tuba on lõpetatud, siis uuesti sama nimetusega tuba registreerida ei saa. Järelikult selline UNIQUE kitsendus ei sobi. Kustutan kõigepealt sellise unikaalsuse kitsenduse:ALTER TABLE TubaDROP CONSTRAINT AK_Tuba_nimetus;MS Accessis saab kasutada CHECK kitsendustes alampäringuid. Ülesande lahendamiseks tuleb tabelile Tuba lisada järgnev kitsendus. Eeldame, et seisund "Lõpetatud" on koodiga 4. ALTER TABLE TubaADD CONSTRAINT chk_toa_nimetuse_unikaalsusCHECK (NOT EXISTS(SELECT nimetusFROM TubaWHERE toa_seisundi_liik_kood<>4GROUP BY nimetusHAVING Count(*)>1));Ei tohi eksisteerida olukorda, et mittelõpetatud tubasid, mis on ühesuguse nimega, on rohkem kui üks.Võrdluseks - PostgreSQLis tuleks sellise reegli jõustamiseks luua kas osaline unikaalne indeks (see on indeks, mis on loodud ainult teatud tingimustele vastavatele ridadele - partial unique index) või EXCLUDE kitsendus. EXCLUDE kitsendus on unikaalsuse kitsenduse edasiarendus, mille puhul saab väärtuste unikaalsuse e kordumatuse kontrollimiseks kasutada ka mõnda muud operaatorit kui võrdsuse kontrolli operaator (=), mida kasutab UNIQUE kitsendus. Oracles tuleks luua osaline unikaalne indeks.Ei indekseid ega ka EXCLUDE kitsendust SQL standard ette ei näe, st tegemist on võimalustega, mis on spetsiifilised konkreetsele andmebaasisüteemidele. **Märksõnad:** PostgreSQL ## Küsimus: Kuidas jõustada MS Accessis kitsendus, et riigi kood koosneb täpselt kolmest suurtähest, kusjuures täpitähed ja katusega tähed pole lubatud? **Vastus:** MS Access ei paku täielikku toetust regulaaravaldiste kasutamisele, kuid selle LIKE predikaadi mustrite koostamise võimalusi on laiendatud regulaaravaldistest tuntud võimalustega. Kui on valitud File => Options => Object Designers => Query design => SQL Server Compatible Syntax (ANSI 92) => This database(Fail => Suvandid => Objektikujundajad => Päringu kujundus => SQL Serveriga ühilduv süntaks (ANSI 92) => See andmebaas), siis * asemel tuleb kasutada % ja ? asemel _Lisan tabelis Riik veerule riik_kood, valideerimisreegli, mis koosneb omavahel seotud alamtingimusest, mis peavad kõik olema täidetud.Not ALike '%[!ABCDEFGHIJKLMNOPQRSTUVWXYZ]%' And StrComp([riik_kood];UCase([riik_kood]);0)=0 And Len([riik_kood])=3Not ALike '%[!ABCDEFGHIJKLMNOPQRSTUVWXYZ]%' - Riigi kood ei tohi vastata mustrile, mille kohaselt on seal vähemalt üks märk, mis ei ole ABCDEFGHIJKLMNOPQRSTUVWXYZ. Need on võimalikud tähed, mida riikide koodides kasutatakse. Täpitähed ja katusega tähed sinna hulka ei kuulu. Hüüumärk (!) ütleb, et märk ei kuulu nende märkide hulka.StrComp([riik_kood];UCase([riik_kood]);0)=0 - MS Access on stringide võrdlemisel vaikimisi tõstutundetu (case insensitive). Seega MS Accessi jaoks on EST ja est ühesugused (võrdsed) stringid. StrComp on MS Accessi funktsioon, mis võimaldab stringide tõstutundlikku võrdlemist. Tõstutundlikult võrreldes peab riigi kood olema võrdne suurtähtedeks teisendatud riigi koodiga.Len([riik_kood])=3 - Riigi kood peab olema täpselt kolm märki pikk. Len on MS Accessi funktsioon, mis leiab etteantud stringi pikkuse.Võrdluseks - PostgreSQLis ja Oracles tuleks kasutada regulaaravaldist '^[A-Z]{3}$'. Alates stringi algusest (^) kuni lõpuni ($) peab selles olema täpselt kolm suurtähte A-Z. PostgreSQLis oleks CHECK kitsenduse tingimus  riik_kood~'^[A-Z]{3}$' ~ on operaator tõstutundlikuks (case sensitive) regulaaravaldise mustrile vastavuse kontrollimiseks.Oracles oleks CHECK kitsenduse tingimus REGEXP_LIKE(riik_kood, '^[A-Z]{3}$')REGEXP_LIKE on funktsioon regulaaravaldise mustrile vastavuse kontrollimiseks. **Märksõnad:** valideerimisreegel, check, validation rule, PostgreSQL, Oracle ## Küsimus: Kuidas jõustada MS Accessis kitsendus, et tuba saab aktiivsesse seisundisse viia ainult siis, kui see tuba on seotud vähemalt ühe kategooriaga? **Vastus:** Eeldame, et seisund "Aktiivne" on koodiga 2. Tuleb luua CHECK kitsendus.ALTER TABLE TubaADD CONSTRAINT chk_tuba_aktiivne_peab_olema_kategooriaga CHECK (NOT EXISTS (SELECT *FROM TubaWHERE toa_seisundi_liik_kood=2AND NOT EXISTS (SELECT *FROM Toa_kategooria_omamineWHERE Tuba.tuba_kood=Toa_kategooria_omamine.tuba_kood)));Ei tohi eksisteerida mitte ühtegi aktiivses seisundis tuba, millel pole ühtegi seotud kategooriat.See kitsendus rakendub, kui muudetakse toa seisundit tabelis Tuba. See kitsendus ei keela aktiivsete tubade kategooriad ära kustutada.Töövihiku projektis tuleneb see kitsendus sellest, et aktiivsete tubade vaatamine toimub kategooriate järgi. Kui aktiivne tuba pole üheski kategoorias, siis selle toa andmeid vaadata ei saa. Töövihiku projektis on see kitsendus väljendatud valvurtingimusena seisundidiagrammil oleval seisundi üleminekutel seisundisse "Aktiivne". SQL näeb ka ette andmebaasiobjekti tüüpi üldine kitsendus (assertion). See on eraldisseisev nimega CHECK kitsendus, mis pole seotud otseselt ühegi tabeliga, kuid mille loogikaavaldises olev päring võib viidata andmebaasi erinevatele tabelitele. Tänapäeva turul olevad andmebaasisüsteemid paraku sellise andmebaasiobjekti loomist ei võimalda. Oracle foorumis tekitas sellist tüüpi objekti toe lisamine väga palju positiivset tagasisidet, kuid Oracle andmebaasisüsteemi pole seda tüüpi objekti tuge ikkagi lisatud.MS Accessis saab luua lisakitsendusi tabeliga seotud CHECK kitsendustena. Erinevalt paljudest teistest andmebaasisüsteemidest (nt PostgreSQL, Oracle, MySQL), saab MS Accessis kasutada sellistes CHECK kitsendustes alampäringuid. Üldised kitsendused ja tabeli CHECK kitsendustes alampäringute kasutamine võimaldavad jõustada keerukamaid reegleid ühes kohas, kaitstavatele andmetele lähedal (andmebaasis), kontrollist möödahiilimist vältival viisil, väikese koodi hulgaga. Tulles tagasi vastuse alguses oleva näite juurde, siis kui selle kitsenduse saaks jõustada üldise kitsendusena (assertion), siis keelaks see ka aktiivselt toalt kõikide kategooriate kustutamise. Praegune lahendus seda ei keela.Võite küsida, milleks sellest rääkida, kui paljudes teistes andmebaasisüsteemides sellist kitsendust luua ei saa. Vastusena ütleksin, et siin on MS Access ajast ees, mitte ajast maas. Kui kitsendusi saab luua andmebaasi tasemel väikese koodi hulgaga ja möödahiilimist välistaval viisil, siis see lihtsustab märkimisväärselt andmebaasirakenduse loomist.Nende teiste, kaasaegsemate ja võimekamate süsteemide puhul, tuleb kontrolle teha andmebaasis trigeritega, andmete registreerimiseks mõeldud andmebaasiserveris talletatud rutiinides, rakenduses või jätta üldse tegemata - kõigi selliste lahendusvariantidega on seotud omad suured probleemid ja raskused. **Märksõnad:** valideerimisreegel, check, validation rule, PostgreSQL, Oracle ## Küsimus: Kuidas jõustada MS Accessis tabeliga seotud kitsendus, et elukoht ei tohi olla ainult numbritest koosnev string? **Vastus:** MS Access ei paku täielikku toetust regulaaravaldiste kasutamisele, kuid selle LIKE predikaadi mustrite koostamise võimalusi on laiendatud regulaaravaldistest tuntud võimalustega. Nimetatud kitsenduse jõustamiseks on abi, kui see kitsendus ümbersõnastada. Kui elukoha stringis on vähemalt üks numbrimärk, siis peab selles olema ka mõni selline märk, mis ei ole numbrimärk. Teatavasti võib binaarset loogilist operatsiooni implikatsioon kasutava avaldise P=>Q kirjutada teisendusreeglite alusel ümber samaväärseks avaldiseks: NOT (P) OR Q. Sellise avaldise saab aga juba tabelitaseme valideerimisreeglina kirja panna. Antud juhul P="Kui elukoha stringis on vähemalt üks numbrimärk" Q="peab selles olema ka mõni selline märk, mis ei ole numbrimärk" Seega seon MS Accessis veeruga elukoht valideerimisreegli: Not ([elukoht] ALike '%[0-9]%') Or ([elukoht] ALike '%[!0-9]%') [!0-9] ütleb mustris, et leiduma peab vähemalt üks märk, mis ei kuulu numbrimärkide hulka. Veel üks võimalus on defineerida MS Accessis veeruga elukoht seotud valideerimisreegel: IsNumeric([elukoht])=False Võrdluseks, PostgreSQL ja Oracle võimaldavad regulaaravaldiste kasutamist: PostgreSQLis tuleks tabeliga Isik siduda CHECK kitsendus: CHECK (elukoht!~'^[[:digit:]]+$') Oracles tuleks tabeliga Isik siduda CHECK kitsendus: CHECK(NOT REGEXP_LIKE(elukoht,'^[[:digit:]]+$')) Need kitsendused kontrollivad, et elukoht ei vastaks mustrile, mille kohaselt sisaldab see ainult numbrimärke. **Märksõnad:** MSAccess ## Küsimus: Kuidas kirjeldada Decimal tüüpi veergu läbi tabeli graafilise disaineri? **Vastus:** Määrake veeru omaduste juures järgnevat:Data Type (Andmetüüp): Number (Arv)Field Size (Välja suurus): Decimal (Kümnendarv)Precision (Täpsus): Soovitud maksimaalne numbrikohtade arvScale (Mastaapimine): Soovitud kohtade arv peale komaValik Decimal Places (Kümnendkohad) määrab kuvatavate komakohtade arvu ja sinna võib jätta Auto (Automaatne).Näiteks veerus, mis on tüüpi Decimal (3,1), saab olla maksimaalne väärtus 99.9 ja minimaalne väärtus -99.9 (kolm numbrikohta, üks peale koma). Antud juhul on täpsus 3 ja skaala 1. ## Küsimus: Kuidas saab MS Accessis ja PostgreSQLis lisada veergudele kommentaare? **Vastus:** MS Accessis saab minna tabeli disainivaatesse e kujundusvaatesse ja kirjutada kommentaari tekst veeru juurde välja Kirjeldus (Valikuline) / Description (Optional).PostgreSQLis saab kommentaari lisada SQL-standardis mitte ettenähtud COMMENT lausega. COMMENT ON COLUMN Amet.max_tootunde_nadalas IS 'Maksimaalne töötundide arv nädalas peab olema vahemikus 0 – 50 (otspunktid kaasa arvatud)';PostgreSQLis saab kommentaari lisada ka kitsendusele, MS Accessis ei saa.COMMENT ON CONSTRAINT chk_synni_kp ON Tootaja IS 'Sünni kuupäev peab olema vahemikus 1. jaanuar 1920 ja tänane kuupäev (otspunktid kaasa arvatud).';Kommentaarid on kasulikud, sest need säilitatakse andmebaasis ja tulevased andmebaasi hooldajad ning arendajad saavad neid lugeda. ## Küsimus: Kuidas saab MS Accessis ja PostgreSQLis tagada andmete reeglitele vastavuse kontrollimisel "ilusaid" veateateid? **Vastus:** Kui luua andmebaasis CHECK kitsendus (saab luua nii MS Accessi kui PostgreSQL andmebaasides), siis juhul kui andmemuudatus eksib selle kitsenduse vastu, siis veateates näidatakse kitsenduse nime. Muutes nime arusaadavamaks, muutub ka veateade arusaadavamaks.SQL standard kirjeldab trigeri objekti (CREATE TRIGGER lause). PostgreSQLis saab trigereid luua. Triger on andmebaasis olev programm, mis käivitub tabelis tehtava andmemuudatuse tulemusel. Trigerite abil saab kontrollida andmemuudatuste reeglitele vastavust ja ebasobiva muudatuse tagasi lükata. Kui tahaksite, et PostgreSQL annaks andmete reeglitele vastavuse kontrolli käigus "ilusaid" veateateid, siis tuleks luua andmebaasis tabeliga seotud triger. MS Accessis trigereid luua ei saa, aga seal on väga sarnane võimalus luua andmemakrosid (data macros) - sisuliselt sama asi, lihtsalt loomiseks ei saa kasutada andmebaasikeelt, vaid see tuleb ehitada graafilises kasutajaliideses."Ilusate veateadete" jaoks pole MS Accessis andmemakrosid üldiselt vaja, sest piiranguid saab jõustada valideerimisreeglitega ning sinna juurde saab lisada valideerimisteksti. Valideerimisteksti kuvatakse siis, kui andmemuudatus selle reegli vastu eksib.PostgreSQLis (ja SQL-andmebaasisüsteemides üldiselt) on trigerite abil "ilusate veateadete" saamisel kõrge hind - rohkem koodi, rohkem testimist, kerge teha vigu ning andmebaasisüsteem ei oska trigerite abil jõustatud reegleid SQL lausete täitmise optimeerimisel ära kasutada.Seega PostgreSQL korral (ja SQL-andmebaasisüsteemides üldiselt) oleks eelistatud lahendus deklaratiivne (ütlen, mida peab kontrollima, mitte kuidas peab kontrollima) kitsenduste jõustamine CHECK kitsenduste abil.Samas leidub keerukamaid reegleid (kontroll hõlmab andmete lugemist erinevatest tabelitest või sama tabeli erinevatest ridadest), mida PostgreSQLis (ja SQL-andmebaasisüsteemides üldiselt) ei saagi muul viisil realiseerida kui trigeritega. **Märksõnad:** Postgres ## Küsimus: Kuidas teha nii, et MS Accessis oleksid avatud aknad (näiteks tabelid või SQL lausete kirjutamise aknad) organiseeritud sakkidena (kaartidena) üksteise kõrval (vt lisatud pilt)? **Vastus:** Valige File=> Options=> Current Database => Tabbed DocumentsSee valik on üsna pakutavate valikute nimekirja alguses.Samuti veenduge, et sealsamas on märgistatud "Display Document Tabs".Kui soovite, et aknad oleksid üksteisest sõltumatult väiksemaks ja suuremaks tehtavad ning võivad ka üksteist katta,siis sealsamas on valik "Overlapping Windows".Vt ka: https://599cd.com/glossary/access/overlappingwindowstabbeddocuments/?key= ## Küsimus: Kust saab infot MS Accessis kasutusel oleva SQL mägimurraku e dialekti kohta? **Vastus:** Kuigi SQL on rahvusvaheline standard, ei realiseeri paraku ükski andmebaasisüsteem seda täielikult. Ilmselt on põhjus selles, et standard on väga mahukas. See tähendab, et mistahes SQL-andmebaasisüsteemis on ilmselt võimalusi, mida standard näeb ette, kuid süsteem ei paku nagu ka võimalusi, mis on spetsiifilised sellele süsteemile. See on paraku elu tõsiasi. Need on mõned allikad, kus aine materjalidele lisaks MS Accessi SQL mägimurraku kohta lugeda. Jet SQL (see on MS Accessi aluseks oleva andmebaasimootori nimi), Microsoft Access SQL reference. **Märksõnad:** mägimurrak, MSAccess, MS Access ## Küsimus: Käivitan MS Accessis päringu (query), mis ei ole SELECT lause. Tulemuseks on teade: Päringul peab olema vähemalt üks sihtväli/Query must have at least one destination field. Mida ma teen valesti? **Vastus:** Te olete avanud ekraanil päringu (query) ning käivitamiseks teete topeltklõpsu selle päringu ikoonil Accessi objektide nimekirjas (vt lisatud pilti). Selle peale arvab MS Access, et tahate käivitada SELECT lauset ja tulemuseks on nimetatud viga. Lause käivitamiseks tuleb antud juhul valida lindilt (ribbon) menüü Kujundus (Design) ning vajutada seal hüüumärgiga nupule Käivita (Run). **Märksõnad:** MS Access ## Küsimus: Mille poolest erineb MS Accessi andmetüüp BIT (YESNO) SQL standardis ettenähtud andmetüübist BOOLEAN? **Vastus:** MS Accessis on BIT tüüp selline, mille korral tehakse teisendus NULL=>FALSECREATE TABLE Toode (toode_kood INTEGER,on_aktiivne BIT DEFAULT TRUE,CONSTRAINT pk_toode PRIMARY KEY (toode_kood));INSERT INTO Toode (toode_kood, on_aktiivne) VALUES (1, NULL);SELECT Count(*) AS cntFROM ToodeWHERE on_aktiivne=FALSE;--Tulemuses 1 ridaSELECT Count(*) AS cntFROM ToodeWHERE on_aktiivne IS NULL;--Tulemuses 0 ridaSamas tõelise BOOLEAN tüübi korral seda ei tehta. Näide PostgreSQList.CREATE TABLE Toode (toode_kood INTEGER,on_aktiivne BOOLEAN DEFAULT TRUE,CONSTRAINT pk_toode PRIMARY KEY (toode_kood));INSERT INTO Toode (toode_kood, on_aktiivne) VALUES (1, NULL);SELECT Count(*) AS cntFROM ToodeWHERE on_aktiivne=FALSE;--Tulemuses 0 ridaSELECT Count(*) AS cntFROM ToodeWHERE on_aktiivne IS NULL;--Tulemuses 1 ridaNULL tähistab antud juhul tõeväärtust UNKNOWN. Seega registreerisin väite, et pole teada, kas toode 1 on aktiivne või mitte. Vältimaks kolmevalentse loogika kasutamist, mille korral väite kontrolli tulemus võib olla TRUE/FALSE/UNKNOWN, tuleks veerule on_aktiivne deklareerida NOT NULL kitsendus. **Märksõnad:** PostgreSQL, MS Access ## Küsimus: Millised on MS Accessi eelised teiste SQL-andmebaasisüsteemide ees? **Vastus:** Iga töö jaoks on oma tööriistad. Töövahend pole universaalselt halb ega hea, vaid sellel on sobivad ja mittesobivad kasutusvaldkonnad. Ma pole nõus nendega, kes MS Accessi põlastavad ja selle peale nina kirtsutavad. Prototüüpide, üksikkasutajate andmebaaside ja väikeettevõtete andmebaaside loomiseks on see väga hea vahend. Saan aru, kui kõhklusi tekitab hind, suletud lähtekood või tootjafirma maine, kuid funktsionaalsuselt on see väga hea vahend. Lihtsalt "ilusate silmade" eest selles pingereas kõrgele kohale ei jõua (MS Access on seal esikümnes või selle lähedal).Siin on näide artiklist, kus tuuakse välja MS Accessi puuduseid. Samas selles samas artiklis välja toodud alternatiivide juures tuuakse välja nende nõrgad küljed, mis näitavad nende alternatiivide nõrkuseid. Selle sama artikli kommentaaride osas on elav arutelu, kus ei olda autoriga nõus. Muuhulgas viidatakse seal 2019. aasta intervjuule MS Accessi programmijuhiga, kes kinnitab Microsofti jätkuvat pühendumust MS Accessi edasi arendada. Siin, siin ja siin on hiljutised arutelud selle kohta, kas "Access on surnud" (arutlejad on üldiselt seisukohal, et ei ole).Nimetan järgnevalt mõningaid MS Accessi eeliseid konkurentide ees. MS Access on töölaua andmebaasisüsteem. Võrreldes "vanemate vendade/õdedega" - serveri andmebaasisüsteemidega (nt PostgreSQL, Oracle erinevad väljaanded, MySQL) - on sellel palju puudujääke. Kuid kas on ka eeliseid? Jah on. Üksiti võttes võivad tunduda väikesed asjad, kuid palju väikeseid asju annab kokku ühe suure. Tabeli veergude järjekorra muutmiseks tabelis tuleb tabeli disainivaates veergu sobivale kohale lohistada. SQL tabelites on veerud vasakult paremale järjestatud. Igal veerul on järjekorranumber. Mõnes olukorras tuleb seda järjekorranumbrit teada. Paraku ei paku SQL  lauset tabeli veergude järjekorra muutmiseks või veeru lisamiseks konkreetsele positsioonile. Seega on teistes süsteemides enamasti lahenduseks tabeli kustutamine ja uuesti loomine. CHECK kitsendustes saab kasutada alampäringuid. Võimaldab realiseerida deklaratiivsel viisil keerukate reeglite kontrolli. See tähendab, et süsteemile öeldakse, mida peab kontrollima, mitte kuidas seda teha. Näiteks PostgeSQL ja Oracle ei luba CHECK kitsendustes alampäringuid ning keerukamate reeglite andmebaasi tasemel jõustamiseks ei jää üle muud kui luua trigereid. Trigerites kirjeldatakse andmete kontrolli protseduur. Koodi on palju rohkem kui deklaratiivsete kitsenduste puhul ning lihtne on teha vigu. Muide, ka MS Accessis on võimalus sisuliselt luua trigereid - selleks tuleb luua andmemakrod. Attachment tüübi kasutamine veeru tüübina, mida saab määrata ainult läbi graafilise kasutajaliidese, võimaldab lihtsalt ja mugavalt realiseerida failide andmebaasis hoidmise. Andmebaasirakenduse kaudu hallatavate failide (näiteks veebipoe kaupade pildid) hoidmine väljapool andmebaasi (andmebaasisüsteemi kontrolli alt väljas) on üks SQL disaini antimustritest - Assume You Must Use Files (Phantom Files) (Chapt 12). Tabeli disainivaates saab valideerimisreeglitega koos määrata valideerimisteksti. Seda näidatakse kasutajale kui tema andmemuudatus eksis selle reegli vastu. Niimoodi on võimalik kerge vaevaga määrata (loodetavasti head ja arusaadavad) veateated, mida kasutajale näidatakse. Paraku ei pöörata veateadete heale kasutatavusele paljude programmide puhul piisavat tähelepanu. Päringute kujundaja (query designer) pakub ka võimalust andmete muutmise lausete (INSERT/UPDATE/DELETE) koostamiseks. SELECT lausete graafilise kasutajaliidese abil koostamise võimalust pakutakse paljudes programmides, kuid andmete muutmise lausete sellise koostamise võimalusega polegi ma muudes programmides kokku puutunud. TOP predikaat, mida saab kasutada ka teistes Microsofti andmebaasisüsteemides, kuid mida ei kirjelda SQL standard, võimaldab mitmeid ülesandeid lihtsamalt lahendada. Näiteks - leia hotellid, milles on toimunud kõige rohkem reserveerimisi (selliseid hotelle võib olla rohkem kui üks). SELECT TOP 1 hotelli_nrFROM ReserveerimineGROUP BY hotelli_nrORDER BY Count(*) DESC; Andmebaasisüsteemiga ühte programmi integreeritud andmebaasirakenduste loomise võimalus on hea näide väikese kodeerimise vajadusega arenduskeskkonnast (low code development environment). See on IT süsteemide arenduse üks oluline tulevikusuund. IT on igal pool ja inimestel on vajadus/soov luua kiiresti endale kõige sobivamat tarkvara. Süsteemiarendus demokratiseerub, st võimalikult paljud peaksid seal saama kaasa lüüa. Näiteks Oracle veebirakenduste kiirprogrammeerimise keskkonnas Apex andmebaasirakenduse loomise kasutajakogemus meenutab väga palju MS Accessi kasutamise kogemust. Vahe on selles, et Apexis on kogu arendusliides veebipõhine ja arenduse tulemusena valmib Oracle andmebaasi kasutav veebirakendus. Võimalus kasutada SQL lausetes parameetreid, mille väärtust küsitakse lõppkasutajalt või loetakse mõnelt ekraanivormilt. Andmebaasirakenduse mugavam muutmine. Muutes tabeli/veeru nime muudetakse paljudel juhtudel automaatselt (siiski küll mitte alati) ka salvestatud SQL lauseid (queries) nii, et need arvestaksid uute nimedega. Paraku alampäringuid ei osata muuta. Muutes tabeli/veeru nime muudetakse paljudel juhtudel automaatselt (siiski küll mitte alati) ka ekraanivorme nii, et need arvestaksid uute nimedega.  Muudetakse just selliseid vorme, mis on seotud tabelitega (bound forms), st mitte selliseid, kus andmete leidmine ja esitamine käib kasutaja kirjutatud VBA koodi kaudu. **Märksõnad:** MSAccess ## Küsimus: Mis probleem tekib MS Accessi andmebaasi kasutamisel universaalse andmebaasi haldamise programmi (nt DBeaver ja DbSchema) kaudu? **Vastus:** Nende vahendite kaudu saab käivitada SQL lauseid, mis on illegaalne SQL, ei ole kooskõlas MS Accessi SQL dialektiga, st lauseid otse andmebaasisüsteemis käivitades need ei toimi. Põhjus saab olla selles, et see programm kui vahendaja kirjutab lauseid enne käivitamist ümber andmebaasisüsteemile sobivaks. See muutub probleemiks, kui  sellise vahenda puudumisel ei oska kasutaja andmebaasisüsteemis toimivat koodi kirjutada.Esitan järgnevalt näiteid.Illegaalse SQLi näideSELECT [oppimine] , tulemusFROM [Oppimine] INNER JOIN [Eksam] ON Oppimine.[oppimine] =Eksam.[oppimine];Veerg oppimine on nii tabelites Oppimine kui Eksam. Veerule viidates ei täpsustata tabelit, milles see veerg sisaldub.Korrektne oleks:SELECT Oppimine.[oppimine] , tulemusFROM [Oppimine] INNER JOIN [Eksam] ON Oppimine.[oppimine] =Eksam.[oppimine];Näited lausetest, mida MS Accessi SQL dialekt ei toeta, kuid mida saan DBeaveris MS Accessi andmebaasi põhjal käivitadaSELECT Count(DISTINCT aine) AS arvFROM [Oppimine];--leian erinevate ainete arvu, mida on vähemalt korra õpitudWITH erinevad AS (SELECT DISTINCT [aine]  FROM [Oppimine])SELECT Count(*) AS arvFROM erinevad;/*ühine tabeli avaldis (Common Table Expression) - deklareerin alampäringu ja siis kasutan*/SELECT *FROM [Oppimine]ORDER BY [oppim_algus] DESC LIMIT 2;SELECT *FROM [Tudeng] INNER JOIN [Oppimine] ON Tudeng.[tudkood] = Oppimine.[tudeng] INNER JOIN [Aine] ON Oppimine.[aine] = Aine.[aine_kood] --ühendamisoperatsioonid pole sulgudesSELECT *FROM [Tudeng] JOIN [Oppimine] ON Tudeng.[tudkood] = Oppimine.[tudeng] JOIN [Aine] ON Oppimine.[aine] = Aine.[aine_kood] --sõna JOIN fraasi INNER JOIN asemelSELECT *FROM [Oppimine] INNER JOIN [Eksam] USING (oppimine);--kompaktsem süntaks ühendamiseks üle samanimeliste veergudeSELECT *FROM [Oppimine] WHERE Extract(YEAR FROM [oppim_algus])=1999;--Extract funktsioon kuupäevast aastaarvu eraldamiseksSELECT *FROM [Oppimine] WHERE [oppim_algus]='1999-09-01'--Kuupäevastring on ülakomade vahelNäited SQL lausetes, mida saab MS Accessis otse käivitadaSELECT Count(aine) AS arvFROM (SELECT DISTINCT [aine]FROM [Oppimine]) AS ap; SELECT *FROM ([Tudeng] INNER JOIN [Oppimine] ON Tudeng.[tudkood] = Oppimine.[tudeng])INNER JOIN [Aine] ON Oppimine.[aine] = Aine.[aine_kood] --sulud ühendamisoperatsioonide ümberSELECT *FROM [Oppimine] WHERE Year([oppim_algus])=1999;--MS Accessis on funktsioon YearSELECT *FROM [Oppimine] WHERE [oppim_algus]=#1999-09-01#; ## Küsimus: Teen MS Accessis currency veeru põhjal näiteks summeerimise või keskmise leidmise päringu. Tulemuses ei ole valuuta tähiseks Eur. Mida teha? **Vastus:** Põhjus on Windowsi regionaalsetes sätetes. Tähis võetakse sealt ning järelikult peitub ka tulemuse põhjus seal. **Märksõnad:** euro ## Küsimus: Võtsime lahti Accessi faili, mida sai kunagi arvutiklassis täiendatud, ning nüüd viskab Error 2950-it (Action name: Set property). Milles on probleem ja kuidas seda lahendada? **Vastus:** Avasite 32-bitises MS Accessis tehtud faili 64-bitises MS Accessis. Kui seda teha, siis võib olla vaja VBA koodi parandada. --- # Teema: Vahendid - muu ## Küsimus: Kas "Andmebaasid I" iseseisvas töös võib rakenduse prototüübi tegemisel kasutada mõnda ORM (Object-Relational Mappers, objekt-relatsioonvastenduse) vahendit. **Vastus:** See pole keelatud. Kuid palun tutvuge ka probleemidega, millest ma kirjutan pikemalt SIIN.NB! "Andmebaasid II" aines pole see ka keelatud, kuid siis tuleb tingimata tagada, et loodud rakendus kasutab andmebaasi läbi avaliku andmebaasi liidese e virtuaalse andmete kihi. Teiste sõnadega peaks rakendus lugema andmeid vaadetest (näiteks Djangos on see võimalik) ning muutma andmeid kasutades andmebaasiserveris talletatud rutiine (näiteks Djangos on see võimalik). Andmete kitsendustele vastavuse kontroll peab toimuma andmebaasi tasemel (kasutades deklaratiivseid kitsendusi ja reegleid), mitte rakenduse tasemel nagu ORM vahendid üldiselt propageerivad. "Andmebaasid I" õppeaines, kus iseseisva töö üheks tulemuseks on rakenduse prototüüp, ei ole avaliku andmebaasi liidese loomine nõutud. Küll aga tuleb ka selles aines kitsendusi maksimaalselt andmebaasi tasemel jõustada. **Märksõnad:** rutiin, funktsioon, protseduur, hetktõmmis, materialiseeritud vaade, virtuaalne andmete kiht, andmebaasi avalik liides ## Küsimus: Kas on nõuandeid, kuidas saada FortiClient VPN tööle Linuxi (Ubuntu) alt? **Vastus:** Järgnev on väljavõte ülikooli IT-sõprade töörühmas toimunud vestlusest. X: Kas ma saan õigesti aru, et mingit inimlikku viisi Linuxi (Ubuntu 24.04.1 LTS) all VPNi kasutada ei ole?   forticlient ei installeeru, OpenFortiGUI (mille installeerimine mingist suvalisest repost iseenesest on juba kahtlane) pangestub   Y: Paistab et FortiClient on mõeldud vanemale Ubuntule (22.04 LTS) https://www.fortinet.com/support/product-downloads/linux Ubuntu 24.04 jaoks leidsin miskit sellist, äkki on abiks: https://community.fortinet.com/t5/Support-Forum/Ubuntu-24-04-Forticlient-VPN-installation-w-DNS-resolution-fix/m-p/312896 FortiClient Linux downloads information for specific versions of Linux.     X: Jah, ma pidasin silmas inimlikku viisi, mitte mingit sellist häkkimist   Z: Tere, mina sain Ubuntu 24.04 peal seda õpetust kasutades Forticlient tööle. Sellega installib puuduvad dependencied ära. Tray ikooni tundub, et ikkagi ei teki aga taskbaril lahti olles töötab. Sellega ei pidanud conf midagi mässama.  package management - How to install and use the app depends on libappindicator1 in Ubuntu 24.04? - Ask Ubuntu   X: Ma leidsin ka selle, aga mingi teise distributsiooni package'ite installeerimine on üldjuhul halb idee   S: Sarnane nagu Z pakutu, Fortineti foorumist, mis nõuab vähem häkkimist https://community.fortinet.com/t5/Support-Forum/Support-for-FortiClient-VPN-7-4-for-Ubuntu-24-04-LTS/m-p/351426/highlight/true#M254415   2 pakki tuleb käsitsi lisada, ülejäänu automaagiliselt   X: Automaagiliselt ei tööta siin midagi, Forticlient ei taha ühenduda. Proovisin nii external browseri kui internali'iga, ikka sama:    Z: Jah, minu viga vaatasin, et ühendus ära. Tegelikult jäi connecting peale. Tundub, et enne seda korrektselt tööle ei saa kui FortiClient uuendab 24.04 peale ennast.    S: Mina sain käima, Ubuntu 24.04.2 LTS peal. Ikoonid ja systray ja kõik toimib 100%. * virtualbox + Ubuntu 24.04.1 LTS iso + installer upgrade to Ubuntu 24.04.2 LTS + install to local hard drive + 1 add-apt-repository universe 2 wget -nd https://repo.fortinet.com/repo/forticlient/7.4/ubuntu22/DEB-GPG-KEY 3 apt-key add DEB-GPG-KEY 4 add-apt-repository "deb https://repo.fortinet.com/repo/forticlient/7.4/ubuntu22/ stable non-free" 5 apt-get update 6 apt-get upgrade 7 apt-get install forticlient 8 reboot S: Sain selle "free" versiooni ka käima uninstallisin litsentsi tahtva ja eemaldasin repod + puhastasin süsteemi (rm -rf /etc/forticlient) laadisin alla 'VPN Agent' .deb paki,  https://links.fortinet.com/forticlient/deb/vpnagent laadisin alla 2 lisa pakki http://mirrors.kernel.org/ubuntu/pool/universe/liba/libappindicator/libappindicator1_12.10.1+20.10.20200706.1-0ubuntu1_amd64.deb http://mirrors.kernel.org/ubuntu/pool/universe/libd/libdbusmenu/libdbusmenu-gtk4_16.04.1+18.10.20180917-0ubuntu8_amd64.deb installisin need 3 pakki dpkg -i libdbusmenu-gtk4_16.04.1+18.10.20180917-0ubuntu8_amd64.deb  dpkg -i libappindicator1_12.10.1+20.10.20200706.1-0ubuntu1_amd64.deb  dpkg -i forticlient_vpn_7.4.0.1636_amd64.deb  ja reboot ## Küsimus: Kas on võimalik kasutada aines vajalikku tarkvara ilma seda enda arvutisse installeerimata? **Vastus:** Jah, alates 2024. aastast on selleks võimalik kasutada arvutiklasside arvuteid kaugkasutuse korras vastavalt SELLELE juhendile. **Märksõnad:** mac, linux, kaugkasutus, kaugtöölaud, remote desktop, vpn, kaug, kaugtöö, arvutiklass, kaugligipääs, kaugühendus ## Küsimus: Kas projekti dokumenti võib teha Githubi Wikis, Google Docs'is või muus sarnases rühmatööd toetavas keskkonnas? **Vastus:** Miks mitte, kuid soovitan ikkagi kaaluda MS Wordi kasutamist, sest seal on mudeli koostajale väga kasulik funktsionaalsus - Split screen. See funktsionaalsus lihtsustab projekti erinevate osade kooskõla kontrollimist. Ükskõik mis vahendit Te dokumendi loomiseks kasutate, siis õppejõud soovib hindamiseks projekti dokumenti sellises formaadis, et seda saab MS Word programmis avada ja "Split screen" abil vaadata. Projekti pealkirjade struktuur PEAB täpselt vastama mallis ette antud struktuurile. See on vajalik, et oleks võimalik lühikese ajaga suur hulk projekte kiiresti läbi vaadata ja sisukat tagasisidet anda. ## Küsimus: Kas Teil on nõuandeid, kuidas luua andmebaasirakendust kasutades suuri keelemudeleid? **Vastus:** Allpool on esitatud näited andmebaasirakendustest, mis on loodud kasutades suuri keelemudeleid. Lisaks andmebaasirakendusele loodi vastuvõtuaegade näite puhul suure keelemudeli abil ka andmebaasi avaliku liidese elemendid (vaated ja funktsioonid), mida see rakendus kasutab.  Kasutatud keelemudelid olid 2025. aasta veebruari seisuga koodi genereemise mõttes parimate hulgas. Sellele lähenemisele on isegi juba nimi antud - vibe coding. Esitan mõned tähelepanekud, mis tekkisid nende rakenduste loomisel. Korduvalt on öeldud, et tulevikus on ainus programmeerimiskeel inglise keel. Järgnevate näidete korral sobis eesti keel täpselt sama hästi. Andmebaasi avaliku liidese (funktsioonid, vaated) elementide genereerimiseks vajalike viipade loomiseks kasutasin: tabelite loomise laused, andmebaasioperatsioonide lepingud (et luua andmete muutmise funktsioone), kasutusjuhtude laiendatud formaadis kirjeldusi (et luua vaateid). Andmebaasirakenduste genereerimiseks kasutasin: funktsioonide signatuure, vaadete veergude nimesid, kasutusjuhtude laiendatud formaadis kirjeldusi (funktsionaalsed nõuded), mittefunktsionaalsed nõuded. Tabelite, veergude, funktsioonide, parameetrite sisukad nimed aitasid kindlasti genereerimisele palju kaasa. Kui rakenduse loomise viipades viidata funktsioonidele/vaadetele, siis muutub viip kompaktsemaks võrreldes sellega, et viidata tabelitele. Andmebaasi avaliku liidese elementide (vaated ja funktsioonid) eraldi loomine võimaldas nende loomisel keskenduda sellele, milliseid andmeid tahan ja mida tahan nende andmetega teha ja rakenduse loomise viipades sai seetõttu rohkem keskenduda kasutajaliidesele. Tegin koodis minimaalselt käsitsi muutuseid - paari vaate korral lisasin id veerge, mille lisamise vajadust generaator ette ei näinud. Kasutajaliidese loomisel töötas minu jaoks kõige paremini järgnev lähenemine. Lase genereerida funktsionaalsus, veendu et töötab. Seejärel hakka väikeste sammudega kasutajaliidest paremaks muutma. Hindan kõigi nende rakenduste loomisele kulunud ajaks koos viipade koostamise ning korduva katsetamisega umbes kaks tööpäeva. Tundub, et see hetk, kus CRUD (andmete haldamise) veebirakenduse saab sellisel viisil (kiiresti) loodud, on juba käes. Kui tarkvara suudab koodi genereerida, siis saab keskenduda sellele, mida on vaja teha ning miks on seda vaja teha ning kuidas see teadmine süsteemi tulevastelt kasutajatelt kätte saada ning generaatorile arusaadavaks teha (e äri- ja süsteemianalüüs).  Ka selliste lihtsate veebirakenduste loomisel tuleb vastava keele mingil määral tundmine kindlasti kasuks ning mida suurem ja keerulisem rakendus, seda rohkem on seda vaja. Kui teostub unistus tehisintellekti-põhistest agentidest, siis muutub kõik see üleliigseks, sest selliseid programme polegi vaja. Ongi andmebaasid ja nendega toimetavad agendid. Vastuvõtuaegade veebirakendus (nii õppejõu kui üliõpilase töökohad), mis on loodud kasutades PHP-d ja PostgreSQLi. Tabelid olid olemas. Andmebaasi avaliku liidese (vaated ja funktsioonid) ja veebirakenduse loomiseks on kasutatud tehisintellekti. Põhiliselt on kasutatud xAI Grok 3 mudelit. Mõned vaated on loodud DeepSeek R1 abil.   Õppejõu töökoht  kasutajanimi: kasutaja1 parool: testparool2   kasutajanimi: kasutaja4 parool: testparool4   SIIT saab alla laadida nii koodi (andmebaas ja rakendus) kui ka selle genereerimiseks esitatud küsimused.   Üliõpilase töökoht kasutajanimi: t990995 parool: testparool1   kasutajanimi: t990998 parool: nali   SIIT saab alla laadida nii koodi (andmebaas ja rakendus) kui ka selle genereerimiseks esitatud küsimused.Töövihiku alusel realiseeritud haigla infosüsteemi protseduuride funktsionaalse allsüsteemi juhataja töökoht, mis on loodud kasutades PHP-d ja PostgreSQLi. Kasutajanimi: tiina.maasikas@gmail.com Parool: wenametchainasama   Andmebaas (tabelid, vaated, funktsioonid) oli olemas. See loodi töövihiku põhjal. Rakenduste loomiseks kasutati suuri keelemudeleid. Küsimuste koostamisel kasutati projekti dokumendis esitatud funktsionaalseid nõudeid (kasutusjuhud laiendatud formaadis) ning mittefunktsionaalseid nõudeid. Rakendusest on kaks versiooni.   https://apex2.taltech.ee/haigla_deepseek/ Rakenduse lähtekood on genereeritud kasutades suurt keelemudelit DeepSeek R1  SIIT saab alla laadida nii lähtekoodi kui ka selle genereerimiseks esitatud küsimused. Ainus parandus koodis oli andmebaasi kasutaja kasutajanime ning parooli muutmine. https://apex2.taltech.ee/haigla_grok/ Rakenduse lähtekood on genereeritud kasutades suurt keelemudelit xAI Grok 3.  SIIT saab alla laadida nii lähtekoodi kui ka selle genereerimiseks esitatud küsimused. Ainus parandus koodis oli andmebaasi kasutaja kasutajanime ning parooli muutmine. **Märksõnad:** AI, TI, prompt, viip, generatiivne tehisintellekt, LLM, suur keelemudel ## Küsimus: Kuhu panna apex2 serveris PHP rakendus ja kuidas sellele ligi pääseb? **Vastus:** Serveris on PHP 7. Rakenduse failid tuleb laadida serverisse kasutades selleks näiteks WinSCP programmi.   Failid tuleb panna kataloogi   /var/www/html   alamkataloogi.   Näiteks, kui loote sinna alamkataloogi "rakendus", siis on veebiaadress   https://apex2.taltech.ee/rakendus/   **Märksõnad:** andmebaasirakendus, kasutajaliides, iseseisev töö projekt, veebirakendus ## Küsimus: Kuidas kasutada PostgreSQLi küsitlustulemuste analüüsimiseks sh vabatekstiliste vastuste analüüsimiseks? **Vastus:** Moraal on selles, et vaba teksti väljas olevate väärtuste analüüsimine nõuab rohkem tööd ning kui andmebaasis oleks vaja registreerida andmeid millegi kohta, et nende andmete alusel saaks hiljem teha otsinguid, siis vabateksti asemel tuleks eelistada rohkem struktureeritud väärtuste salvestamist.Küsitlus Microsoft Forms keskkonnas, kus on viis küsimust: Kui heaks hindate Te 10 palli skaalal oma SQLi oskust (0 üldse ei oska - 10 väga hea)? (vastuseks arv 0-10) Milline on Teie varasem kokkupuude andmebaaside loomisega? (vastus vabatekst) Milliseid andmebaasisüsteeme Te olete oma elus kasutanud (võib valida mitu)? (vastus etteantud valikust) Kui olete kasutanud mõnda andmebaasisüsteemi, mida eespool ei nimetatud, siis kirjutage see palun siia (vastus vabatekst) Millised on Teie ootused "Andmebaasid I" õppeaine suhtes? (vastus vabatekst) Laadin alla vastused Exceli failina.Kustutan üleliigsed veerud. Faili jääb viis veergu. Esimene rida on päis, väärtuste eraldaja on ;Jätan alles tabeli päise.Salvestan CSV formaadis. Laen faili Kysitlus_k2025.csv serverisse, kus on PostgreSQL, kataloogi tmp.Järgnevad laused käivitan PostgreSQL andmebaasis./*Loon andmebaasis laienduse, et saaksin andmebaasis kasutada andmebaasivälises failis olevaid andmeid.*/CREATE EXTENSION IF NOT EXISTS file_fdw; CREATE SERVER file_fdw_server FOREIGN DATA WRAPPER file_fdw; /*Loon välise tabeli, mille kaudu saan vaadata serverisse laaditud CSV failis olevaid andmeid.Määran, et fail on CSV formaadis, failis on tabelil päis (veergude nimed), näitan faili asukoha, määran kuidas esitatakse jutumärke ningpuuduvaid andmeid ning milline on väärtuste eraldaja.*/ CREATE FOREIGN TABLE kysitlus ( SQL SMALLINT, varasem TEXT, andmebaasisysteemid TEXT, andmebaasisysteemid_muu TEXT, ootused TEXT) SERVER file_fdw_server OPTIONS (format 'csv',header 'true', filename '/tmp/Kysitlus_k2025.csv', quote '"', delimiter ';', null ''); /*Leian vastuste arvu.*/ SELECT Count(*) AS arv FROM Kysitlus; /*Mediaanväärtuse leidmiseks kasutan andmebaasis kasutaja poolt loodud funktsiooni.*/ SELECT Median(SQL) AS mediaan, Avg(SQL) AS aritmeetiline_keskmine FROM Kysitlus; /*Moodi e kõige sagedamini esineva väärtuse leidmiseks saab kasutada spetsiaalset kokkuvõttefunktsiooni. NB! Kui on mitu ühesugust väärtust, siis valitakse nendest juhuslikult üks.*/ SELECT mode() WITHIN GROUP (ORDER BY SQL) AS mood FROM Kysitlus; /*Erinevate SQL oskuse hinnangute arv sorteerituna arvu järgi kahanevalt.*/ SELECT SQL, Count(*) AS arv FROM Kysitlus GROUP BY SQL ORDER BY arv DESC; /*Milliseid SQL oskuse hinnanguid ei ole kordagi antud? generate_series funktsioon genereerib antud juhul tabeli,kus on 11 rida ning igas reas on üks täisarv (0-10). Alampäringus peab olema tingimus SQL IS NOT NULL, sest kui küsitluses oleks mõnel juhul SQL oskuse hinnang puudu, siis ilma selle tingimuseta poleks päringu tulemuses kunagi ühtegi rida.WITH klauslis on ühine tabeli avaldis (common table expression), mis võimaldab defineerida alampäringu, anda sellele nime ning seda hiljem lauses kasutada.*/WITH voimalikud AS (SELECT generate_series(0,10) AS hinnang)SELECT hinnangFROM voimalikudWHERE hinnang NOT IN (SELECT SQL FROM KysitlusWHERE SQL IS NOT NULL)ORDER BY hinnang; /*Jagades hinnangud nelja klassi - 0, 1-3, 4-6, rohkem kui 6, siis kui mitu vastajat kuulub igasse klassi ning milline on igasse klassi kuuluvate vastajate protsent kõigi vastajate arvust. Arvestatakse vaid vastuseid, kus SQL hinnang on antud. Kasutan massiivi konstruktorit ARRAY[], et saada iga hinnangu juurde väärtus, mille alusel sorteerides on hinnangud madalamast kõrgema suunas sorteeritud.*/ WITH eeltootle AS (SELECT CASE WHEN SQL=0 THEN ARRAY['ei tea midagi','a'] WHEN SQL BETWEEN 1 AND 3 THEN ARRAY['teab vähe','b'] WHEN SQL BETWEEN 4 AND 6 THEN ARRAY['teab keskmiselt','c'] ELSE ARRAY['teab hästi','d'] END AS hinnang FROM Kysitlus WHERE SQL IS NOT NULL) SELECT hinnang[1] AS hinnang, Count(*) AS arv, Round(Count(*)*(SELECT Count(*) FROM eeltootle)/100,1) AS protsent FROM eeltootle GROUP BY hinnang ORDER BY hinnang[2]; /*Kui mitmes vastuses pole nimetatud ühtegi andmebaasisüsteemi?*/ SELECT Count(*) AS arv FROM Kysitlus WHERE andmebaasisysteemid IS NULL; /*Milline on andmebaasisüsteemide populaarsus e mainimise sagedus? Lause töötleb väljapakutud nimekirjast valitud vastuseid, mis CSV failis on kujul "PostgreSQL;MySQL;" Funktsioon regexp_split_to_table võimaldab tükeldada tekst osadeks ja esitada iga tükk eraldi reana.*/ WITH tykelda AS (SELECT regexp_split_to_table(andmebaasisysteemid, ';') AS andmebaasisysteemid FROM kysitlus) SELECT andmebaasisysteemid, Count(*) AS arv FROM tykelda WHERE andmebaasisysteemid<>'' GROUP BY andmebaasisysteemid ORDER BY arv DESC; /*Kui mitu andmebaasisüsteemi on erinevates vastustes mainitud? Kasutatakse aknafunktsiooni ROW_NUMBER(), et saada iga vastuse jaoks unikaalne identifikaator.*/ WITH tykelda AS (SELECT row_number() OVER () AS vastus_id, regexp_split_to_table(andmebaasisysteemid, ';') AS andmebaasisysteemid FROM kysitlus), systeemide_arv AS (SELECT Count(*) AS andmebaasisysteemide_arv FROM tykelda WHERE andmebaasisysteemid<>'' GROUP BY vastus_id) SELECT andmebaasisysteemide_arv, Count(*) AS arv FROM systeemide_arv GROUP BY andmebaasisysteemide_arv ORDER BY arv DESC; /*Milliseid andmebaasisüsteemide paare on ühes ja samas vastuses mainitud. Leia kõik paarid, kus esinemiste arv on suurem kui 1.*/ WITH vastused AS (SELECT row_number() OVER () AS vastus_id, regexp_split_to_table(andmebaasisysteemid, ';') AS andmebaasisysteem FROM kysitlus), vastuse_element AS (SELECT vastus_id, andmebaasisysteem  FROM vastused WHERE andmebaasisysteem<>'') SELECT va1.andmebaasisysteem AS systeem1, va2.andmebaasisysteem AS systeem2, Count(*) AS arv FROM vastuse_element AS va1,  vastuse_element AS va2 WHERE va1.vastus_id=va2.vastus_id AND va1.andmebaasisysteem>va2.andmebaasisysteem GROUP BY va1.andmebaasisysteem, va2.andmebaasisysteem HAVING Count(*)>1 ORDER BY arv DESC, systeem1, systeem2; /*Kui mitmes vastuses on mainitud lisaks täiendavaid andmebaasisüsteeme?*/ SELECT Count(*) AS arv FROM Kysitlus WHERE andmebaasisysteemid_muu IS NOT NULL; /*Kas täiendavate andmebaasisüsteemide kirjelduses on korduvaid sõnu?/ WITH tykelda AS (SELECT trim(regexp_split_to_table(translate(andmebaasisysteemid_muu,',',';'), ';')) AS andmebaasisysteemid_muu FROM kysitlus) SELECT andmebaasisysteemid_muu, Count(*) AS arv FROM tykelda WHERE andmebaasisysteemid_muu<>'' GROUP BY andmebaasisysteemid_muu ORDER BY arv DESC; /*Millised on kõige sagedasemad varasema andmebaaside loomise kogemuse iseloomustamiseks kasutatavad sõnad?Eemaldatakse stoppsõnad ning esitatakse vaid sõnad, mida esitatakse rohkem kui üks kord.*/ WITH eemalda (sone) AS (VALUES ('ja'),('ning'),('või'),('ka'),('on'),('et'),('mis'),('kui'),('kuid')), eeltootle AS (SELECT translate(lower(varasem),';,.-','') AS varasem FROM kysitlus), tykelda AS (SELECT regexp_split_to_table(varasem, ' ') AS varasem FROM eeltootle), puhasta AS (SELECT varasem FROM tykelda WHERE varasem NOT IN (SELECT sone FROM eemalda)) SELECT varasem, Count(*) AS arv FROM puhasta WHERE varasem<>'' GROUP BY varasem HAVING Count(*)>1 ORDER BY arv DESC; /*Millised on kõige ootuste iseloomustamiseks kasutatavad sõnad? Eemaldatakse stoppsõnad ning esitatakse vaid sõnad, mida esitatakse rohkem kui üks kord.*/ WITH eemalda (sone) AS (VALUES ('ja'),('ning'),('või'), ('-'),('ka'),('on'),('et'),('mis'),('kui'),('kuid')), eeltootle AS (SELECT translate(lower(ootused),';,.-','') AS ootused FROM kysitlus), tykelda AS (SELECT regexp_split_to_table(ootused, ' ') AS ootused FROM eeltootle), puhasta AS (SELECT ootused FROM tykelda WHERE ootused NOT IN (SELECT sone FROM eemalda)) SELECT ootused, Count(*) AS arv FROM puhasta WHERE ootused<>'' GROUP BY ootused HAVING Count(*)>1 ORDER BY arv DESC; Tulemuse, kus on sõnad ja nende kaalud (näiteks esinemiste arv), saab anda sisendiks tasuta veebipõhisele sõnapilve koostamise tarkvale nagu näiteks SEE. Sinna saab anda sisendi CSV formaadis ning PostgreSQLis olevaid andmeid saab CSV formaadis eksportida näiteks COPY TO lausega. Sellised vahendid võimaldavad sisendiks võtta ka lihtsalt teksti, kuid taolise päringu tulemusel sisendi leidmine on kasulik seetõttu, et selle abil saab eemaldada just eesti keele stoppsõnu. **Märksõnad:** tekstikaeve, vabatekst, Postgres, Postgre ## Küsimus: Kuidas on seotud andmebaasid ja tehisaru (AI)? **Vastus:** Andmebaasisüteemid on seotud tehisaruga erinevates aspektides. Treeningandmed võivad tulla andmebaasist. Mingisugune osa tehisaru süsteemidest saab olla realiseeritud andmebaasisüsteemi vahendeid kasutades – mitte andmed ei tule realisatsiooni juurde, vaid realisatsioon tuleb andmete juurde. Süsteem tuleb ise realiseerida, kasutades pakutavaid andmetüüpe, luues rutiine. Süsteemi loomiseks saab kasutada valmis komponente. Andmebaasisüsteem kasutab oma sisemise toimimise korraldamiseks tehisaru. See on võimalik isejuhtivate andmebaasisüsteemide puhul. Andmebaasiga seotud ülesannete lahendamiseks kasutatakse tehisaru.   Miks andmebaasis?   Miks realiseerida tehisaru süsteeme kasutades andmebaasisüsteemide pakutavaid võimalusi? Momijan (2024) põhjendab seda sellega, et tehisaru süsteemid nõuavad palju andmeid ning efektiivsem on tuua algoritmid andmete juurde, selle asemel, et viia andmeid algoritmide juurde. Eeliseks on, et andmetele juurdepääs on lihtne ja kiire ning arvesse saab võtta kõige värskemaid andmeid. Jääb ära ajakulu andmete ülekandmisele andmebaasist rakenduse juurde. Kuna andmeid ei pea liigutama üle võrgu, siis on andmete turvalisus ja andmesubjektide privaatsus paremini tagatud. Kuna väheneb kasutatavate serverite hulk, siis on ka süsteemi tehniline arhitektuur lihtsam.   Tehisaru‑põhistel süsteemidel võib olla abi erinevatest andmebaasisüsteemides realiseeriseeritud võimalustest nagu näiteks tehingute haldus, andmete samaaegse kasutamise võimalus erinevate kasutajate poolt, varundamine ning taastamine, keerukad andmetüübid, täistekstotsing ning erinevat tüüpi indeksid.    Andmebaasist andmete lugemisel saab kasutada kõiki andmekäitluskeele võimalusi. Samuti on abiks andmete maskimise (PostgreSQL, Oracle) ja anonümiseerimise võimalused.      Retrieval Augmented Generation   Lugemisega täiendatud genereerimine (Retrieval-Augmented Generation, RAG) on suurte keelemudelite kasutatav tehnika, mille korral enne kasutaja küsimusele inimkeelse vastuse genereerimist otsitakse andmeid välistest allikatest nagu dokumendid, veebilehed ja andmebaasid. Nii parandatakse vastuse täpsust ja olulisust ning vähendatakse hallutsioneerimist (e jama ajamist). Süsteem otsib kasutaja päringule vastamiseks välistest allikatest vastuse jaoks olulist sisendit. Leitud sisend ühendatakse kasutaja promptiga (küsimusega), et anda keelemudelile vastuse genereerimiseks täpsemat konteksti. Niimoodi moodustatud uus prompt antakse sisendiks teksti genereerimisele. Selline lähenemine võimaldab  võtta arvesse värskeimat infot, ilma, et peaks keelemudeleid uuesti treenima.    RAG süsteemi osaks võiks olla andmebaas, kus on dokumendid (tekst, pildid, videod) ning iga dokumendiga on seotud n‑mõõtmeline vektor (embedding), mis seda dokumenti iseloomustab. Sõltuvalt kasutatavast mudelist võib n olla mitusada või isegi mitu tuhat. Üldiselt, mida suurem n, seda täpsem tulemus. Vektorite moodustamiseks kasutatakse transformerit, mis teisendab muutuva pikkusega sisendi fikseeritud pikkusega vektoriks. Loodud vektor on hulk ujukomaarve, mis ei ütle inimkasutajale midagi.  Oracle OCI nimetab sellist andmebaasi vektorandmebaasiks. Etteantud andmete alusel vektori arvutamise teenust pakuvad erinevad tehisaru arendavad ettevõtted. Nende vektorite omavaheline võrdlemine leiab väärtuste semantilist sarnasuse – mida sarnasemad väärtused, seda sarnasemad vektorid. Seda saab kasutada otsinguks, klasterdamiseks, soovitamiseks, anomaaliate tuvastamiseks, mitmekesisuse mõõtmiseks ja klassifitseerimiseks.    RAG süsteem võtab kasutaja päringu, laseb selle põhjal (mõnel välisel teenusel) arvutada vektori, leiab selle vektori alusel oma andmebaasist päringule kõige sarnasemad (päringu jaoks kõige olulisemad) dokumendid, lisab need kasutaja päringule ning algatab selle alusel vastuse genereerimise. Kuna andmebaasisüsteemi poolt vektori ükshaaval kõigi ülejäänud vektoritega võrdlemine kõige lähedasemate vastete leidmiseks võib võtta liiga palju aega, siis kasutatakse ka optimeeritud algoritme, mis leiavad "piisavalt lühikese ajaga“ "piisavalt hea vastuse". Nende algoritmide kasutamise eelduseks on, et andmebaasis on vektoritele loodud spetsiaalne indeks.RAGi kasutava süsteemi näiteks on teadusartiklite kokkuvõtete andmebaas Scopus, mille tehisaru‑põhine funktsionaalsus (Scopus AI) võimaldab kasutajal esitada inimkeeles küsimusi, millele genereeritakse teadusartiklite põhjal neid kokkuvõttev vastus. Selles kokkuvõttes on viited allikatele, mille põhjal vastus koostati. Graph Retrieval Augmented Generation   Valdkonna teadmiste graafis (knowledge graph) esitatakse valdkonna mõisted ja nende vahelised seosed – mõisted on graafi tipud ja mõistete seosed on graafi kaared. Rathle (2024) argumenteerib selle poolt, et vektorid ei pruugi olla päringule vastava konteksti otsimisel piisavad ning lisaks vektoritele võiks otsida sobivaid seotud dokumente ka teadmiste graafi (knowledge graph) kasutades. Sellist lähenemist võiks nimetada GraphRAG - graafi lugemisega täiendatud genereerimine. Rathle (2024) märgib, et stringide e sõnede (strings) töötlemise asemel on parema tulemuse jaoks vaja töödelda asju (things) ning graaf on viis kuidas "asju" kirjeldada.   Autori hinnangul oleks graafipõhised andmebaasid sellise süsteemi loomiseks justkui loodud. Programm moodustaks valdkonna kohta konteksti pakkuvate dokumentide alusel teadmiste graafi, mis salvestatakse graafipõhisesse andmebaasi. Sinna salvestatakse ka dokumente iseloomustavad vektorid. GraphRAG süsteem kasutaks seda andmebaasi, et anda suurele keelemudelile ette kasutaja päringule vastamiseks vajalikku kontekstteavet. Teadmiste graaf on kombinatsioon leksikaalsest graafist ja valdkonna graafist. Leksikaalne graaf esitab dokumendi struktuuri elemente ja nende seoseid ning selle koostamine on lihtne. Valdkonna graaf esitab dokumendi käsitletavas sisus esinevaid mõisteid ja nende seoseid. Neo4j (graafipõhine andmebaasisüsteem) pakub selleks tööriista Neo4j Knowledge Graph Builder. SQL‑andmebaasis olevate struktureeritud andmete importimiseks saab kasutada Neo4j Data Importer töövahendit.   Rathle (2024) toob välja GraphRAG erinevaid eelised ainult vektoreid kasutava RAGi ees. Teadmiste graafide sellisel viisil kasutamine võimaldab anda kasutajate päringutele täpsemaid, täielikumaid ja seega ka kasulikumaid vastuseid. Rathle viitab erinevatele uuringutele, mis seda väidet kinnitavad.  Graaf on arusaadav nii inimesele kui masinale. Süsteemi kasutaja saab uurida dokumentide alusel moodustatud graafi ning saab selle kaudu ette parema pildi andmetest ja oskab seega ka süsteemi antavaid vastuseid teistele paremini selgitada.  Dokumentide vektorite uurimine (iga vektor on suur hulk ujukomaarve) sellist pilti kindlasti ei anna.  Graafis olevate viitade kaudu saab liikuda tagasi vigade algpõhjusteni.  Graafi andmebaasis jagatavate õiguste kaudu (milliste tippude ja kaarte andmeid on konkreetsel kasutajal lubatud lugeda) saab reguleerida seda, milline info antakse suurele keelemudelile sisendiks. Juurdepääs andmetele sõltub kasutaja rollist. Näiteks, kui päringu teeb arsti rollis kasutaja, siis  keelemudeli sisendiks lähevad ka patsiendi diagnoosi andmed, kuid kui päringu teeb klienditeenindaja, siis ei lähe.   Kokkuvõttes saab öelda, et Neo4j pakub graafiliste kasutajaliideste kaudu võimaluse dokumentide või SQL‑andmebaasides olevate andmete importimiseks, nende põhjal graafi genereerimiseks ning siis graafi vaatamiseks. See on kasulik funktsionaalsus isegi siis, kui ei hakata GraphRAG süsteemi realiseerima.   Andmebaasisüsteemide võimalusi   Andmebaasisüsteemid pakuvad vahendeid tehisaru kasutavate süsteemide, sh RAG süsteemide, hõlpsamaks realiseerimiseks.  Leidub spetsiifiliselt vektorite haldamiseks mõeldud andmebaasisüsteeme, kuid ka  olemasolevaid üldotstarbelisi andmebaasisüsteeme saab selleks otstarbeks kohandada. Näiteks võivad SQL‑andmebaasisüsteemid pakkuda vektori andmetüüpi, mida saab kasutada tabeli veeru tüübina. PostgreSQLis tuleb selle kasutuselevõtuks installeerida laiendus pgvector (Jelinek, 2024). Seda tüüpi veergudele saab otsingute kiirendamiseks luua spetsiaalsed indeksid.  Oracles on oodata sellise tüübi lisandumist versiooni 23.4ai (Curtis, 2024). Näiteks OpenAI pakub rakendusliidest, et arvutada tekstilise väärtuse põhjal välja seda iseloomustav n‑mõõtmeline vektor. Jelinek (2024) esitab koodinäite, kuidas neid vektoreid PostgreSQL andmebaasi laadida. Sewrathan et al. (2024) kirjutab veel kahest PostgreSQL laiendusest – pgai ja pgvectorscale. pgvectorscale parandab võrreldes laiendusega pgvector vektorite kasutamise jõudlust ning skaleeritavust. pgvector on kirjutatud C ja pgvectorscale on kirjutatud Rust keeles. pgvectorscale lisab StreamingDiskANN tüüpi indeksi. pgai muudab vektorite kasutamisel põhinevate süsteemide loomise lihtsamaks. Esimeses versioonis saab OpenAI poolt arvutatavaid vektoreid laadida otse andmebaasis, ilma, et peaks selle jaoks kirjutama eraldi andmebaasivälise programmi. Samuti saab otse andmebaasist kasutada OpenAI Chat Completion rakendusliidest, mis on mõeldud vestlusrobotite ning virtuaalsete assistentide loomiseks. Momijan (2024) demonstreerib PostgreSQLi põhjal masinõppe algoritmi realiseerimist. Treeningandmete ja kaalude registreerimiseks luuakse tabelid. Masinõppe algoritmi realiseerimiseks luuakse funktsioone (plperl protseduurses keeles), mida kasutatakse päringutes.   Näiteks selle kohta, kuidas andmebaasisüsteemi on sisseehitatud tehisaru süsteemide loomiseks vajalikud võimalused, on Oracle viimastesse põlvkondadesse lisandunud masinõppe tugi (In-database machine learning).    Veel üheks näiteks on Oracle 23ai lisandunud Select AI funktsionaalsus (Gubar, 2023 ja 2024), mis võimaldab esitada Oracle Autonomous Database pilvepõhise andmebaasi suhtes päringuid kasutades loomulikku keelt (inimkeelt), kusjuures võib ka kasutada teisi keeli kui inglise keel. Süsteem kasutab suurt keelemudelit, mis moodustab kasutaja inimkeelse päringu põhjal SQL lause. Süsteemiga saab pidada vestlust (esitada jätkuküsimusi), mis tähendab, et süsteem oskab arvestada eelnevalt küsitud küsimustega. Muutmaks vestlussüsteemide loomine arendajatele võimalikult lihtsaks on täiendatud SQL keelt. Päringu vastus on SQL tabel. Oracle SQL toetab nüüd lauset kujul.   SELECT AI [täpsustus, mida tagastada] Inimkeelne küsimus;   Näide:   SELECT AI  Millised on 5 kõige suurema ostude arvuga kaupa, mis tulid turule peale 2020. aastat;   [täpsustus, mida tagastada] chat – ära küsi andmeid andmebaasist, vaid lase suurel keelemudelil vastus genereerida. narrate – genereeri andmete põhjal sõnaline vastus. showsql – näita genereeritud SQL lauset. runsql – käivita genereeritud SQL lause (vaikimisi).   Sellist SQL lauset võib näiteks käivitada SQL Developeris või luua selle põhjal  Oracle APEX veebirakendus.   Süsteem on loodud sellisena, et toetada erinevaid suuri keelemudeleid ning kasutaja saab valida, millist nendest kasutada.   Funktsionaalsuse kasutamiseks tuleb paketis DBMS_CLOUD_AI oleva protseduuri create_profile abil kirjeldada profiil, kus määratakse ära AI pakkuja, suur keelemudel ning see, kas peetakse vestlust. Profiili rakendamiseks sessiooni käigus tuleb käivitada paketis DBMS_CLOUD_AI olev protseduur set_profile.   PostgreSQLi maailmas on näiteks avatud lähtekoodiga pgml laiendus, mille andmebaasi lisamisel tekivad sinna erinevaid tehisaru aspekte realiseerivad funktsioonid. See on osa tasulisest pilvepõhisest PostgresML platvormist, mis põhineb PostgreSQL andmebaasisüsteemil. PostgresML realiseerib andmebaasisisese masinõppe (In-database machine learning).   pgml lisatavad funktsioonid võimaldavad teha masinõpet ja kasutada suuri keelemudeleid. Suurte keelemudelitega seotud funktsioonid: chunk – dokumendi tükeldamine osadeks. embed – vektori genereerimine etteantud teksti alusel. transform – teksti genereerimine suure keelemudeli poolt. Integratsioon HuggingFace keskkonnaga, et sealt mudeleid alla laadida. See keskkond pakub suure hulga eeltreenitud mudeleid. transform_stream – teksti genereerimine suure keelemudeli poolt ning tulemuse väljastamine voogedastusena, portsude kaupa. tune – peenhäälestamine.   Masinõppega seotud funktsioonid: train – mudeli treenimine (mudeli saab luua erinevate regressiooni, klassifitseerimise ja klasterdamise algoritmide abil). predict – ennustamine (kasutamine). deploy – rakendamine. load_dataset – andmete laadimine.   Teiste sõnadega ei pea masinõppeks või teksti genereerimiseks andmeid kuhugi liigutama ning selle algatamiseks piisab SELECT lausete käivitamisest.   Tehisaru andmebaasisüsteemi teenistuses   Tehisaru kasutamine andmebaasisüsteemi enese ülesannete täitmiseks on kasutusel ise hakkamasaavate andmebaasisüsteemide korral nagu Oracle Autonomous Database. Selline süsteem võiks õppida (kasutada masinõpet) süsteemi toimimise põhjal. Scopus AI genereeritud kokkuvõtte kohaselt võivad sellised süsteemid kasutada masinõpet erinevate ülesannete jaoks. Töökoormuse prognoosimine: masinõppe mudelid ennustavad tulevast töökoormust, võimaldades andmebaasisüsteemil ressursside kasutust ettevalmistada ja optimeerida. Käitumise modelleerimine: masinõpet kasutatakse, et ennustada süsteemi käitumist eri konfiguratsioonide ja töökoormuste korral. See aitab hinnata võimalike muudatuste mõju ilma neid otseselt läbi tegemata (läbitegemine võib olla kallis). Meetmete planeerimine: masinõppe algoritmid otsustavad mineviku tulemuslikkuse andmete ja prognoositud tulemuste põhjal, millised on parimad tegevused näiteks indeksite valiku ja päringute optimeerimise juures. Konfiguratsiooni häälestamine: masinõpet kasutatakse süsteemi juhtparameetrite väärtuste iseseisvaks muutmiseks. Enesekontroll ja diagnoosimine: masinõpet kasutatakse süsteemi jõudluse jälgimiseks, kõrvalekallete tuvastamiseks ja probleemide automaatseks diagnoosimiseks, tagamaks süsteemi tõhususe ning stabiilsuse.   Geneetiline algoritm on Darwini evolutsiooniteoorial ja loomulikul valikul põhinev optimeerimismeetod. Seda kasutatakse selliste probleemide lahendamiseks, kus optimaalset lahendust ei ole tavapäraste meetoditega lihtne leida. Geneetilisi algoritme peetakse tehisaru algoritmideks. PostgreSQL kasutab geneetilist algoritmi kõige sobivama tabelite ühendamise järjekorra leidmiseks, selleks, et suure hulga tabelite ühendamisel ei peaks kõikvõimalikke erinevaid ühendamise järjekordi läbi kaaluma. Kandidaatide (ühendamise järjekordade) sobivuse hindamiseks arvutatakse ühendamise maksumus. "Geneetiline algoritm heidab kõrvale kõige vähem sobivad kandidaadid. Seejärel luuakse uued kandidaadid, kombineerides sobivamate kandidaatide geene – st  kasutades juhuslikult valitud osi teadaolevatest madala kuluga ühendamisjärjestustest, et luua uusi järjestusi, mida saab kaaluda. Seda protsessi korratakse, kuni on kaalutud etteantud arv ühendamisjärjestusi; seejärel kasutatakse otsingu käigus leitud parimat järjestust lõpliku plaani koostamiseks." (PostgreSQL)Andmebaasiga seotud ülesannete lahendamineNäiteid Teksti alusel SQL lause genereerimine SQL lause alusel selle kirjelduse genereerimine **Märksõnad:** tehisintellekt, artificial intelligence, machine learning, masinõpe, ML, transformer ## Küsimus: Kuidas saada juurdepääs Microsoft's Azure Dev Tools for Teaching keskkonnale? **Vastus:** Tallinna Tehnikaülikooli üliõpilastel on juurdepääs Azure Dev Tools for Teaching keskkonnale, kust nad saavad allalaadida mitmesugust Microsofti arendustarkvara, sh MS SQL Server andmebaasisüsteem. Selle keskkonna varasem nimi oli Microsoft Imagine. NB! Varem ülikooli kaudu saadud Microsoft Imagine kontod enam ei toimi. Tuleb teha uus konto järgneva juhendi alusel. Tehke endale Microsofti juures (uus) konto, kus Te ei kasuta @ttu.ee ja @taltech.ee laiendiga meiliaadressi. Konto loomiseks minge: https://signup.live.com. Konto tegemise käigus saate sisestatud meiliaadressile kirja, kus on kinnituskood, mille peate konto tegemise lõpetamiseks sisestama. Kui Teil on varasemast selline konto, siis uut pole vaja teha. Sisenege loodud konto abil: https://azureforeducation.microsoft.com/devtools Sisselogimise järel palutakse Teil kinnitada enda seos ülikooliga, sisestades enda ülikooli meiliaadress (@taltech.ee). Saate enda ülikooli meiliaadressile kirja, kus peate kinnitamiseks klõpsama lingil. Selle kirja lugemiseks minge: https://mail.taltech.ee Kiri tuleb aadressilt maccount@microsoft.com ning algab niimoodi nagu on näidatud teatele lisatud failis. Minge aadressile: https://azureforeducation.microsoft.com/devtools ja logige oma uue kontoga sisse. Tarkvara saab allalaadida valikust Learning Resources=>Software. Juurdepääs keskkonnale peaks kehtima seni, kuni ülikool maksab litsentsid ja kuni inimene on ülikooliga seotud. **Märksõnad:** Microsoft Azure, Microsoft Imagine, MS SQL Server ## Küsimus: Kuidas saavad suured keelemudelid (LLM) hakkama SQL koodi kontrollimisega reeglite suhtes? **Vastus:** Tegin katsetuse 11.03.2025.Kontrollisin hulka tabelite loomise lauseid (MS Accessi SQL murdes) 37 erinevat tüüpi üldise (st mitte Accessi-spetsiifilise) vea suhtes. Keelemudelile esitatud küsimus moodustus prompt + laused.Kontrollitud lausetesse olid meelega tehtud vigu nii, et esindatud olid kõik 37 vigade tüüpi.Laused, prompti ning testi detailsed tulemused saab alla laadida SIIT. Vastuste juures vaadati seda, kui mitut erinevat vea tüüpi tuvastati, kuid ei kontrollitud seda, kas tulemus oli õige. Samas näiteks ChatGPT-l hakkas pealiskaudsel silmitsemisel silma vähemalt üks viga vastuses (osutati kohale koodis, kus viga ei olnud, kuid ei leitud kohta koodis, kus viga oli).Tulemused: Google Gemini 2.5 Pro - leidis 37 tüüpi vigu (100% vigade tüüpidest) Google Gemini 2.5 Flash (Thinking valitud) - leidis 37 tüüpi vigu (100% vigade tüüpidest) DeepSeek V3 (0324) - leidis 33 tüüpi vigu (89% vigade tüüpidest) Reasoning pole sisse lülitatud; mudeli versioon 2025. aasta märtsi lõpust DeepSeek R1 - leidis 32 tüüpi vigu (86% vigade tüüpidest) Google Gemini 2.5 Flash (Thinking polnud valitud) - leidis 31 tüüpi vigu (84% vigade tüüpidest) xAI Grok 3 (DeepSearch ei olnud valitud ja Think olid valitud) - leidis 30 tüüpi vigu (81% vigade tüüpidest) Aega kulus 121 sekundit xAI Grok 3 (DeepSearch ja Think olid valitud) - leidis 29 tüüpi vigu (78% vigade tüüpidest) Aega kulus 71 sekundit xAI Grok 3 (DeepSearch oli valitud, kuid Think ei olnud) - leidis 28 tüüpi vigu (76% vigade tüüpidest) Aega kulus 156 sekundit Alibaba Qwen2.5 Turbo (Thinking) - leidis 28 tüüpi vigu (73% vigade tüüpidest) Claude 3.7 Normal - leidis 25 tüüpi vigu (68% vigade tüüpidest) Alibaba Qwen2.5 Max (Thinking) - leidis 24 tüüpi vigu (65% vigade tüüpidest) xAI Grok 3 (DeepSearch ja Think ei olnud valitud) - leidis 21 tüüpi vigu (57% vigade tüüpidest) ChatGPT 4o - leidis 16 tüüpi vigu (43% vigade tüüpidest) Google Gemini 2.0 Flash - leidis 14 tüüpi vigu (38% vigade tüüpidest) Erinevalt kõigist teistest mudelitest viitas ainult tabelile, mitte täpsemale asukohale Google Gemini 2.0 Flash Thinking Experimental - leidis 13 tüüpi vigu (35% vigade tüüpidest) Täiendavad tähelepanekud: Iga vea tüübi kohta oli vähemalt üks katse, kus see oli leitud. Katsetasin Grok 3 ilma DeepSearchita ja ilma mõtlemiseta ka teist korda ja tulemusena leiti 22 tüüpi vigu (esimesel katsel 21), kusjuures mõnda vigade tüüpi, mida esimesel katsel märgati, teisel katsel ei märgatud ning vastupidi. Grok 3 puhul tasub valida (Think) ning lisaks tasuks tulemust kontrollida veel vähemalt ühe mõne teise ettevõtte mudeliga ja/või Grok 3 (DeepSearch+Think). Viga 2 (Andmebaasis ei ole ühist klassifikaatorite tabelit ), 5 (Klassifikaatorite tabelites sisaldub primaarvõtme veergude nimedes sõna kood või code, mitte id) ja 21 (Kui välisvõti viitab klassifikaatori tabelile, siis ei ole sellel välisvõtmel kompenseerivat tegevust ON DELETE CASCADE) märgati kõigil katsetustel ning viga 12 (Igas tabelis on defineeritud primaarvõtme kitsendus) ainult viies (Google Gemini 2.5Pro, DeepSeek V3, DeepSeek R1, Grok 3 + Think, Claude 3.7 Normal). Grok 3 eelisele ChatGPT tasuta mudelite ees viitab ka näiteks see pingerida. **Märksõnad:** prompt, viip, suur keelemudel, llm, testimine, dokument, iseseisev töö projekt, CREATE TABLE, tabelid, baastabelid, viga, vead, tüüpvead, probleemid, nimetamine, nimed, kitsendused, vaikimisi väärtus, kompenseeriv tegevus, genereeriv TI, tehisintellekt, AI ## Küsimus: Kuidas SQLite korral realiseerida klassifikaatorite tabeleid, kus on kood ja nimetus? Koodi peaks sisestama inimkasutaja, mitte genereerima süsteem. **Vastus:** Katsetasin seda koodi DB Fiddle keskkonnas. CREATE TABLE Tellimuse_seisundi_liik (tellimuse_seisundi_liik_kood INTEGER NOT NULL,nimetus TEXT NOT NULL,CONSTRAINT pk_tellimuse_seisundi_liik PRIMARY KEY (tellimuse_seisundi_liik_kood),CONSTRAINT ak_tellimuse_seisundi_liik UNIQUE (nimetus)); INSERT INTO Tellimuse_seisundi_liik (tellimuse_seisundi_liik_kood, nimetus)VALUES (1, 'Esitatud'); --lisamine õnnestusINSERT INTO Tellimuse_seisundi_liik (nimetus)VALUES ('Kinnitatud'); --lisamine õnnestus, genereeriti kood 2 SELECT * FROM Tellimuse_seisundi_liik; --Tabelis kaks rida INSERT INTO Tellimuse_seisundi_liik (tellimuse_seisundi_liik_kood, nimetus)VALUES (3, 'Kinnitatud'); SELECT * FROM Tellimuse_seisundi_liik; --INSERT lause tekitas vea, mistõttu päringut ka ei täidetud. Selline automaatne väärtuse genereerimine INTEGER tüüpi primaarvõtme veergu on SQLite omapära. Andmebaasi kasutajatel tuleks võtta teadmiseks, et klassifikaatori tabelite korral peab kasutaja tabelisse ka koodi lisama. **Märksõnad:** primaarvõti, esmasvõti, arvujada generaator, surrogaatvõti ## Küsimus: Kuna avastasime, et meie grupil juhtus kodutöö versioonidega mingi viga ja kuhugi kadus parandatud kitsendustega versioon, siis hakkasin hiljem mõtlema, et kuidas edaspidi selliseid vigu vältida. Kas meie kodutöö raames on võimalik versioonihaldamiseks mingit versioonihalduse tarkvara kasutada, nt GitHub vms? **Vastus:** See ei ole kohustuslik, kuid on täiesti võimalik ja minu arvates hea mõte.Tallinna Tehnikaülikooli informaatika õppekavade üliõpilased kasutavad paljudes oma õppekava ainetes GitLabi ning seda kasutatakse ka bakalaureusetöö tegemisel. See on kättesaadav kõigile üliõpilastele, sest sisselogimine on Uni-IDga. Avaleht: https://gitlab.cs.ttu.ee/Alustamise juhend: https://pydoc.pages.taltech.ee/setup/git_ttu.htmlProjektihaldus GitLabis: https://projectdoc.pages.taltech.ee/Tean, et mitmed minu juhendatud üliõpilased on seda kasutanud nii lõputööde kui ka aineprojektide jaoks. Küsimuses mainitud GitHub sobiks muidugi samuti. **Märksõnad:** GitHub, GitLab, Git ## Küsimus: Kus relatsioonilist mudelit peale andmebaaside veel kasutatakse? **Vastus:** Relatsiooniline mudel kirjeldab ühte võimalikku viisi, kuidas andmeid andmebaasides organiseerida ning kuidas neid seal kasutada saab ja seega on relatsioonilise mudeli rakendusvaldkonnaks ikkagi andmebaasid.Samas on see mudel, selle väljatöötamine ja selle põhjal loodud andmebaasikeeled andnud kindlasti inspiratsiooni erinevateks teadus- ja arendustöödeks. Andmemudelite ajalugu algas enne relatsioonilist mudelit, kuid koos relatsioonilise mudeliga saadi aru vajadusest selliste mudelite kirjeldus ka ilmutatult kirja panna. Siin on hea näide, kuidas seda lühidalt ja selgelt teha. Kui mudel on ilmutatult kirja pandud, siis on seda võimalik palju paremini analüüsida ning järjekindlamalt ja täpsemalt realiseerida. Andmestruktuuride normaliseerimise teooria (see on väga läbitöötatud relatsioonilise andmemudeli korral kuid rakendub ka teistele andmemudelitele) on andnud inspiratsiooni normaliseerimise teooria väljatöötamiseks programmikoodi kohta ja laiemalt üldse mistahes liiki süsteemide kohta (normaliseeritud süsteemide teooria - lugege pikemalt siit, peatükist 6). Relatsiooniline mudel ja andmetüübid on ortogonaalsed, st relatsiooniline mudel seab väga vähe nõudeid/piiranguid tüüpidele, mida saab kasutada relatsioonilises andmebaasis näiteks atribuutide või parameetrit tüüpidena. Tüüpide loomise keerukus SQLis on pannud mõtlema, milline võiks olla sobiv andmetüüpide süsteem ja kuidas oleks õige tüüpe pärimise kaudu luua. Eesmärgiks oleks süsteem, kus rakenduse ja andmebaasisüsteemi vahel ei oleks nii põhimõttelisi erinevusi, et nende koostööle sundimiseks oleks vaja mingit ORM-i laadset vahekihti. Relatsioonilise mudeli põhjal loodud reaalne andmebaasikeel - SQL - on vaatamata oma puudustele inspiratsiooniks paljudele uue põlvkonna (NoSQL) andmebaasisüsteemidele deklaratiivse andmebaasikeele väljatöötamise seisukohast. Näiteid: CQL N1QL SPARQL PGQL ## Küsimus: Kust saab infot PostgreSQLis kasutusel oleva SQL mägimurraku e dialekti kohta? **Vastus:** Andmekäitluskeele lausete osas (SELECT, INSERT, UPDATE, DELETE, MERGE) soovitan vaadata seda slaidikomplekti. Seal on lisaks võrdluseks välja toodud, kuidas selliseid ülesandeid saaks lahendada Oracles. Slaidikomplekt keskendub lausekonstruktsioonidele, mida MS Access ei paku.SQL koodi, mida saab käivitada MS Accessis, saab 99%-l juhtudest muudatusteta või pisimuudatustega käivitada ka PostgreSQLis. Kuid PostgreSQL (ja Oracle ja teised serveri andmebaasisüsteemid) pakuvad lisaks täiendavalt veel suure hulga keelekonstruktsioone. Nii et näiteks kui MS Accessis saaks ülesande lahendamiseks kirjutada 5 erinevat SQL lauset, siis PostgreSQLis 10+ erinevat lauset.Internetis leiab keskkondi, mis pakuvad võimaluse veebilehitseja vahendusel lahendada erinevaid PostgreSQL kasutamise ülesandeid - vt SEE ja SEE. ## Küsimus: Kust saada infot andmebaasisüsteemi PostgreSQL kasutamise kohta? **Vastus:** (kasutajanimi: SIS2 ja parool: SIS2) SIIN on "Andmebaasid II" kodulehel olevad slaidid, mille teises osas räägitakse programmidest psql, pgAdmin ja phpPgAdmin, mille kaudu on võimalik andmebaasisüsteemiga suhelda. Samuti tuuakse näiteid PostgreSQLis võimalike SQL lausete ja PostgreSQL kasutamiseks mõeldud programmide funktsionaalsuste kohta. psql on serveris olev käsurea põhine programm. pgAdmin on kasutaja arvutis asuv graafilist kasutajaliidest pakkuv programm ning phpPgAdmin on veebipõhine graafilist kasutajaliidest pakkuv programm.SIIN on eelnevaga sarnast infot pakkuv materjal dokumendi kujul. PostgreSQLile on pühendatud selle esimene peatükk.SIIN on Sharepointi keskkonnas olevad videod PostgreSQL kasutamise kohta. Osad nendest on hääletud ekraanivideod, kuid on ka pikemaid häälega videoid sh "Andmebaasid II" neljanda praktikumi lindistus, kus rääkisin PostgreSQLi kasutamisest (psql'i kaudu).Programme, mille kaudu töötada PostgreSQL andmebaasiga (hallata andmebaasi, käivitada päringuid) on väga palju. Nende hulka kuuluvad ka universaalsed programmid nagu näiteks DBeaver ja DbSchema, mille abil saaks kasutada paljude erinevate andmebaasisüsteemide abil loodud andmebaase. SIIN on nende kasutamis kohta video.Mis puudutab seda, mida head saab PostgreSQLis teha, siis "Andmebaasid I" õppeaine seisukohalt pakuvad esmajärjekorras huvi andmekäitluskeele laused (andmete otsimise ja muutmise laused). Nende võimaluste kohta on väga mahukas slaidikomplekt SIIN. Seal on nii PostgreSQL kui Oracle koodinäited ja keskendutakse SQLi võimalustele, mida lihtsamad ja ainult põhivõimekusi pakkuvad süsteemid nagu MS Access ei paku. Mis puudutab erinevaid andmebaasiobjekte, mida PostgreSQLis saab luua (baastabelid, vaated, domeenid, arvujada generaatorid, rutiinid, trigerid, jne), siis SIIN on nende kohta mahukad slaidikomplektid koos suure hulga koodinäidetega. Kõigis nendes räägitakse võrdlevalt nii PostgreSQList kui Oraclest.SIIN on ingliskeelne materjal PostgreSQL ja MS Access SQL mägimurraku erinevuste kohta. SIIN on näidete katsetamiseks mõeldud MS Access andmebaas ja SIIN on PostgreSQL kood selle andmebaasi loomiseks. PostgreSQL lauseid saaks katsetada näiteks DbFiddle keskkonnas.SIIN saab PostgreSQLi puudutavaid SQL ülesandeid onlainis lahendada. **Märksõnad:** Postgres ## Küsimus: Millega tuleks arvestada koostöökeskkondade kasutamisel? **Vastus:** Sellega, et tegemist on tarkvaraga mille on teinud inimesed. Inimesed on ekslikud ja tarkvaras on vigu. Murphy seaduste kohaselt löövad need välja kõige ootamatumates kohtades ja kõige ebasobivamal ajal. Siiski arvan, et nende keskkondade üldine kasu kaalub üles võimalikud probleemid. Järgnevalt kaks negatiivset kogemust üliõpilaste enda sõnadega.***************"OneDrive ühiselt projekti tegemine võib ahvatlev olla, aga tegelikult võib jamasid tekkida. Meil rollbackis onedrive mingi tundmatu vea tõttu projekti dokumendifaili 40 minuti võrra ning täielikult korruptis EA faili nii, et EA faili avades saime network errori, ning tegime põhimõtteliselt diagrammid nullid uuesti. Minu soov on, et mõnel tudengil tulevikus seda muret ei tekiks"***************Teatele lisatud failis on fragment kolme üliõpilase poolt ühistööna kirjutatud magistritööst. Töö käigus puutusid nad kokku Wordi dokumendi ühise täiendamise probleemidega ja kirjutasid lõpuks oma töösse sellest eraldi alajaotuse. ## Küsimus: Millised on andmebaasisüsteemide MS Access, PostgreSQL ja LibreOffice Base eelised ja puudused võrreldes üksteisega, rõhuga sellel, kuidas neid oleks õppimiseks kasutada? **Vastus:** Mõned omadused on sellised, mida võib vaadata nii hea kui halvana.MS AccessEelised SQL keele põhikonstruktsioonid on toetatud. SQL kood on enamasti väikeste muudatuste järel või üldse muutmata käivitatav ka teistes andmebaasisüsteemides, sh PostgreSQL. Siin on väike PostgreSQL ja Accessi SQL murraku vastavussõnastik. Integreeritud graafiline liides (Query Designer) SQL SELECT, INSERT, UPDATE ja DELETE lausete koostamiseks. Graafilisi liideseid SELECT lausete koostamiseks leiab väga paljudest programmidest, kui INSERT, UPDATE ja DELETE lausete koostamiseks väga väikesest arvust programmidest (nt MySQL jaoks dbForge). Integreeritud graafiline andmebaasi struktuuri vaatamise vaade. Võimalus tabelite disaini (struktuuri ja kitsendusi) muuta nii SQL lausete abil kui graafilise kasutajaliidese kaudu. Integreeritud andmebaasirakenduse tegemise keskkond - pole vaja seda eraldi installeerida. Andmebaasirakenduse tegemise keskkond on hea näide vähese programmeerimise vajadusega kiirprogrammeerimise keskkonnast. Palju asju saab teha visuaalselt ja viisarditega. Andmebaasirakenduse loomise kasutajakogemus on päris sarnane Oracle APEX arenduskeskkonna kasutamisele - see võimaldab luua Oracle andmebaasile veebirakendusi kirjutades ise koodi vähe või üldse mitte. Sobiv vahend ka suuremate organisatsioonide jaoks andmebaasi ja andmebaasirakenduse prototüübi tegemiseks. Sobiv vahend üksikisikute ja väga väikeste ettevõtete andmebaasi tegemiseks. Saab teha nii, et andmebaasirakendus on tehtud MS Accessis ja see kasutab ODBC andmeühenduse tehnoloogia abil serveris asuvat (nt PostgreSQL või MySQL) andmebaasi. Erinevates andmebaasisüsteemide populaarsuse indeksites (vt siia ja siia) endiselt ja jätkuvalt kõrgel kohal. StackOverflow 2024. aasta uuringu kohaselt kuulus ka MS Access kõige populaarsemate, imetletumate ja õppida soovitavate andmebaasisüsteemide valikusse - mitte küll kõige esimeste hulka, kuid arvestades, et andmebaasisüsteeme on üle 400, on ka esimese 20-30 hulgas päris hea koht, kus olla. Uuemad SQLi võimalused pole toetatud. Samas piiratud võimalustega keskkonnas MacGyveri moodi soovitud tulemus saavutada on SQLi põhikonstruktsioonidest arusaamise mõttes väga hea kool. Puudused Uuemad SQLi võimalused pole toetatud. SQL lausete kirjutamise ja käivitamise kasutajaliides on väga halva kasutatavusega - aga, saab kasutada varianti kirjutada ja käivitada SQL lauseid otse Notepad++ tekstiredaktorist. Tarkvara saab alla laadida: https://github.com/aneelm/NppDB NB! Uusimas MS Accessi versioonis on selle kasutajaliidese kasutatavust väga palju parandatud. Tasuline - aga, Tallinna Tehnikaülikooli üliõpilastele tasuta kättesaadav. Võimalik eelarvamuslik suhtumine osade spetsialistide poolt - ahh, see süsteem ei kõlba kuhugi. PostgreSQLEelised Populaarne - kõrge koht erinevates populaarsuse indeksites (vt siia ja siia) ja kasutusel paljudes organisatsioonides (nii ettevõtted kui riigiasutused). StackOverflow 2024. aasta uuringu kohaselt oli PostgreSQL kõige populaarsem andmebaasisüsteem nii kõigi vastajate kui ka professionaalsete arendajate seas. Sama uuringu järgi on PostgreSQL ka kõige rohkem kasutada soovitav ja kõige imetletum andmebaasisüsteem. Väga suur võimaluste hulk andmebaasi programmeerijatele. Hea vastavus SQL standardile, toetab ka uusimaid SQLi võimalusi. Tasuta. SQL lausete harjutamiseks pole vaja tarkvara installeerida ega serverile juurdepääsu küsida - saab kasutada DB Fiddle või SQL Fiddle keskkondi. Väga palju erinevaid programme (nii graafilise kasutajaliidesega kui käsurea-põhiseid), mille vahendusel saate töötada (kas enda või ülikooli) serveris oleva andmebaasiga, sh hallata tabeleid ja vaadata andmebaasi struktuuri. Rakenduse tegemise vahend pole andmebaasi mootoriga integreeritud - saab ise valida keele/keskkonna, milles andmebaasirakendust teha. Palju dokumentatsiooni, Internetis olevaid näiteid, foorumeid jms. Puudused Palju selliseid võimalusi, mis SQLi aluste õppimise kontekstis pole olulised ja sellest tulenev lisakeerukus. Väga palju erinevaid programme (nii graafilise kasutajaliidesega kui käsurea-põhiseid), mille vahendusel saate töötada serveris oleva andmebaasiga, sh hallata tabeleid ja vaadata andmebaasi struktuuri - lisatöö seoses nende seast valiku tegemisega ja installeerimisega. Leidub erinevaid programme, mille abil saab andmebaasipäringuid graafiliselt koostada, aga ka need tuleb endal installeerida ja läbi katsetada. Rakenduse tegemise vahend pole andmebaasi mootoriga integreeritud - tuleb ise valida keel/keskkond, milles andmebaasirakendust teha, see üles panna ja endale selgeks teha. LibreOffice BaseEelised Tasuta alternatiiv MS Accessile. Puudused Ebamugav kasutajaliides SQL lausete käivitamiseks. Mitte nii mugav võimalus andmebaasirakenduse (ekraanivormide) koostamiseks kui MS Accessis. LibreOffice Base kasutab andmebaasimootorina HSQLDB (HyperSQL) versiooni 1.8.See ei ole kõige uuem HSQLDB versioon ja seetõttu ei saa seal kasutada HSQLDB uusimaid võimalusi. Vähe dokumentatsiooni ja näiteid SQL dialekti kohta. HSQLDB 1.8 SQL dialekt. **Märksõnad:** Postgres ## Küsimus: Millised on üldised soovitused ja tähelepanekud suurte keelemudelite jaoks promptide e viipade koostamisel? **Vastus:** Järgnevad soovitused põhinevad tähelepanekutel, mis on tehtud selle aine jaoks tehiste reeglitele vastavuse kontrollimise promptide koostamisel. Osa sellest tekstist on genereeritud Google Gemini 2.5 poolt vastustena küsimustele. Soovitan promptide vaatamise kohta vaadata ka seda videot. Kasutage prompti alamosade esiletõstmiseks markdowni või XMLi. Markdown ## Üldised märkused keelemudelile *   **Sinu roll:** .. *   **Konteksti eeldus:** ... XML <GeneralNotes>     <Note>         <Title>Sinu roll</Title>         <Content>...</Content>     </Note>     <Note>         <Title>Konteksti eeldus</Title>         <Content>...</Content>     </Note> </GeneralNotes> Soovitatav struktuur: # Roll ja eesmärgid # Juhised## Detailsemate juhiste alamkategooriad # Väljundi formaat # Näited## Näide 1 # Kontekst <kontrollitav tekst> # Lõplikud juhised <veelkord kõige tähtsamad juhised> Kui peate promptiga kontrollima tehiste vastavust reeglitele, siis andke keelemudelile reeglid ja paluge need keelemudelile sobivalt ümber sõnastada. Uue reegli versiooni saamisel andke keelemudelile kontrollimiseks ette mõni tehis kus vigu ei ole ja kui keelemudel osutab sellele, et mõni reegel ei ole täidetud, siis paluge väljastada reeglite täiendus, mis arvestab sellega, et raporteeritud veaolukord ei ole tegelikult viga.  Korrake kuni keelemudel ei anna enam valepositiivseid vastuseid. Samamoodi saate anda ette tehiseid, kus on vigu ja kui neid ei leita, siis paluda keelemudelil reeglit täpsustada, et see viga üles leida. Korrake kuni keelemudel ei anna enam valenegatiivseid vastuseid. Kui näiteks oleks vaja kontrollida 100 reegli täidetust, siis töökindlam ja täpsem on kontrolli teha mitmes osas. Põhjused: Kontekstiakna piirangud. Keelemudeli tähelepanu hajumine. Keerukuse haldamine. Väljundi selgus ja kontrollitavus. Potentsiaalne kiirus (mitte alati garanteeritud). Parim viis sõnastada keelemudelile reegel P=>Q, kui kehtib tingimus P, siis peab kehtima ka tingimus Q: Reegel [number] on rikutud, kui [tingimus P on täidetud], AGA [tingimus Q EI OLE täidetud]. Näide: "Reegel 5 on rikutud, kui dokumendis mainitakse uut tarkvaraarendust (P), AGA sellega seotud turvariskide maandamise plaan EI OLE kirjeldatud (Q)." Plussid: Suunab mudeli otse otsima spetsiifilist vastuolu, mis vastab teie soovile leida ainult rikkumisi. Väga selge. Väldib "valepositiivseid" mainimisi, kui P pole täidetud. Miinused: Vajab harjumist, kui olete harjunud reegleid positiivselt sõnastama. Kui kontrollida sama struktuuriga tehiste erinevaid versioone, siis isegi kui kasutada iga kord uut vestluse akent peaks keelemudelile andma selge juhise, et unusta kogu eelnev info, mis on saadud selliste tehiste kontrollimisega ja keskendu ainul sellele konkreetsele tehisele. Põhjused: Selguse tagamine: Annab mudelile ühemõttelise juhise keskenduda ainult sellele, mis on selles konkreetses vestluses esitatud. See välistab igasuguse võimaliku kahemõttelisuse. Võimalike mustrite vältimine: Kuigi mudel ei "mäleta" eelmise dokumendi sisu, võib järjestikuste sarnaste ülesannete täitmine teoreetiliselt mõjutada selle "meeleseisundit" või mustreid, mida ta järgmises vastuses kasutab. Paludes selgelt keskenduda ainult praegusele, vähendad seda riski. Hallutsinatsioonide vältimine: Mudelid võivad vahel "hallutsineerida" või püüda olla liiga "abivalmid", tuues sisse elemente, mida tegelikult pole antud. Selge juhis aitab seda ära hoida. Järjepidevus: Annab sulle kindluse, et iga analüüs algab täpselt samadelt alustelt, sõltumata sellest, mitu sarnast analüüsi oled varem teinud. Kuidas seda öelda: **Sinu ülesanne:** Keskendu AINULT ülaltoodud reeglitele ja ÄSJA esitatud kontrollitavale dokumendile. Ära arvesta ega viita ühelegi varasemale dokumendile või analüüsile. Kontrolli dokumenti reeglite suhtes. Enne reeglite kontrolli käivitamist vaadake, kas saate reguleerida keelemudeli loovust. Näiteks Google Gemini 2.5 on see võimalik ja selleks tuleb muuta temperatuuri. Mida väiksem temperatuur, seda väiksem loovus, kuid seda vähem ka hallutsioneerimist e antud juhul valepositiivseid tulemusi. Nii peaks paranema vastuste täpsus.Määrake Goole Geminis (2.5) temperatuuriks 0.2 (vaikimisi 1 asemel). Võite ka katsetada väärtustega 0 ja 0.1. Keelemudeli enda selgitus: "Madal temperatuur muudab mudeli väljundi väga fokusseerituks ja deterministlikuks. See tähendab, et mudel valib kõige tõenäolisemad järgmised sõnad/märgid, mis on reeglite järgimise ülesande puhul soovitav. See vähendab oluliselt riski, et mudel "hallutsioneerib" reeglirikkumisi, mida pole, või jätab reegleid loovalt tõlgendades tähelepanuta rikkumisi, mis on olemas. Temperatuur 0.0 võib olla liiga jäik, kuid 0.1-0.2 annab piisavalt determinismi, säilitades siiski minimaalse paindlikkuse." (Gemini 2.5) Top-P väärtuseks võiks panna 1.  Top-P muudab seda, kuidas mudel valib väljundisse sõnet (tokenit). Sõned valitakse kõige tõenäolisemast kuni kõige vähem tõenäoliseni, kuni nende tõenäosuste summa saavutab top-P väärtuse. Näiteks, kui sõnede A, B ja C tõenäosused on vastavalt 0,3, 0,2 ja 0,1 ning top-P väärtus on 0,5, siis valib mudel järgmise sõnena kas A või B, kasutades temperatuuri, ning välistab C kui võimaliku kandidaadi.  Madalama väärtuse määramine annab vähem juhuslikud vastused, kõrgema väärtuse määramine aga rohkem juhuslikud vastused. Keelemudeli enda selgitus: "Kui temperatuur on juba väga madal, on tõenäosusjaotus niigi väga terav (suurem osa tõenäosusmassist koondub vähestele tippvalikutele). Top P piirab valimit veelgi, võttes arvesse ainult kõige tõenäolisemaid valikuid, mille kumulatiivne tõenäosus ületab P lävendi. Väga madala temperatuuri korral ei ole Top P langetamisel (nt väärtusele 0.8 või 0.9) enamasti suurt lisamõju, sest vähetõenäolised valikud on juba niigi alla surutud. Top P väärtusel 1.0 lubatakse mudelil kaaluda kõiki võimalusi (kuigi madal temperatuur suunab teda ikkagi kõige tõenäolisemate poole), mis võib olla kasulik, kui õige reegli rakendamine pole absoluutselt kõige tõenäolisem, kuid siiski väga kõrge tõenäosusega variant. Top P liigne piiramine koos madala temperatuuriga võib muuta mudeli liiga piiratuks. Seega, usalda peamiselt madalat temperatuuri ja jäta Top P vaikimisi (1.0)." (Gemini 2.5) **Märksõnad:** suur keelemude, LLM, AI, TI, prompt, promptid, viip, viibad ## Küsimus: Milliseid tarkvara analüüsi ja ehitamise käigus loodavaid tehiseid on võimalik luua suurte keelemudelite abil ja milline võiks olla sellest tulenevalt andmebaasi- ja andmebaasirakenduse mudelitega juhitav arendus? **Vastus:** Järgnevates näidetes viitan visuaalsetele mudelitele järgnevalt: UCD - kasutusjuhtude diagramm ERD - olemi-suhte diagrammid STD - seisundidiagramm Keelemudelile võib neid ette anda erinevatel viisidel. eksportida modelleerimisvahendist XMI formaadis ja anda ette tekstina, teha ekraanipilt ja anda ette pildina, kui  diagrammi loomiseks kasutati PlantUMLi, siis saab diagrammi samuti anda keelemudelile ette tekstina. Tegemist ei ole ammendava nimekirjaga sellest, milliseid tulemeid saab genereerida milliste tulemite põhjal. Keelemudelitena on katsetatud Groki ja Geminit.Olen edukalt katsetanud järgmiste tulemite loomist.Analüüs: UCD + ERD + lühiformaadis kasutusjuhtude näited + reeglid lühiformaadis kasutusjuhtudele => UCD esitatud kasutusjuhtude lühiformaadis kirjeldused UCD + ERD + STD + laiendatud formaadis kasutusjuhtude näited + reeglid laiendatud formaadis kasutusjuhtudele => UCD esitatud kasutusjuhtude laiendatud formaadis kirjeldused ERD + andmebaasioperatsioonide lepingute näited + reeglid andmebaasioperatsioonidele + andmebaasioperatsioonide nimekiri => andmebaasioperatsioonide lepingud UCD + ERD => CRUD maatriks ERD => mudeli kirjeldus inimkeeles, veendumaks, et mudelis väljendatu langeb kokku sellega, mida tegelikult väljendada soovitakse Tegemist oleks alternatiiviga SELLELE lõputöö raames arendatud spetsiaaltarkvarale Ehitamine: ERD + reeglid tabelitele => Tabelite loomise laused, INSERT laused testandmete lisamiseks ERD => JSON skeem ja skeemile vastavad näiteväärtused ERD => MongoDB kollektsioonide loomise laused testandmete lisamiseks Tabelite loomise laused => INSERT laused testandmete lisamiseks ERD või tabelite loomise laused + atribuutide definitsioonid => Atribuutidele täiendavate piirangute (CHECK kitsenduste) lisamise laused Tabelite loomise laused + keerukam ärireegel => Andmebaasi trigerite loomise laused (promptis saab ka paluda lisada kommentaare, jagada õiguseid) Laiendatud formaadis kasutusjuhud + reeglid vaadetele => Vaadete loomise laused  (promptis saab ka paluda lisada kommentaare, jagada õiguseid) Andmebaasioperatsioonide lepingud + reeglid funktsioonidele => Andmebaasis loodavad funktsioonid  (promptis saab ka paluda lisada kommentaare, jagada õiguseid) Tegemist oleks alternatiiviga SELLELE lõputöö raames arendatud spetsiaaltarkvarale Laiendatud formaadis kasutusjuhud + mittefunktsionaalsed nõuded + lugemisoperatsioonidele vastavate vaadete struktuur + muumisoperatsioonidele vastavate funktsioonide signatuur => Veebipõhine andmebaasirakendus Katsetasin ka edukalt tekstilistest mudelitest UML diagrammide loomist, kusjuures diagrammid on mõeldud vaatamiseks PlanText või PlantUML keskkondades. Kasutusjuhud lühiformaadis => Kasutusjuhtude diagramm Põhiobjekti alusel leitud funktsionaalse allsüsteemi kasutusjuhud lühiformaadis => Põhiobjekti seisundidiagramm Laiendatud formaadis kasutusjuht => Kasutusjuhu poolt esitatava elementaarse äriprotsessi tegevusdiagramm Laiendatud formaadis kasutusjuht => Kasutusjuhu poolt esitatava elementaarse äriprotsessi süsteemi jadadiagramm Põhiobjekti seisundidiagramm => Seisundi üleminekutest tuletatud kasutusjuhtudega kasutusjuhtude diagramm Diagrammide loomisel oli prompti osaks ka väike diagrammi tekstilise esituse näide PlanText keskkonnas, kuid tundub, et seda pole vaja.Ülikooli hindamisskaalal võiks tulemusi hinnata hindega 4 (väga hea). See tähendab, et vaja oleks vaja teha väiksemaid parandusi.Eelnevast tulenevalt võiks andmebaasi- ja andmebaasirakenduse moodne mudelitega juhitav arendus olla midagi sellist. Genereerimise all mõeldakse genereerimist generatiivse TI poolt, kui ei ole öeldud teisiti. Leia põhiobjektid. Leia tegutsejad. Põhiobjektide alusel leia funktsionaalsed allsüsteemid ja registrid (igale põhiobjektile vastab register ja seda teenindav samanimeline funktsionaalne allsüsteem). Tegutsejate alusel leia pädevusalad (igale tegutsejale vastab pädevusala). Vali funktsionaalne allsüsteem, mida täpsemalt käsitleda. Sõnasta funktsionaalset allsüsteemi kasutatavate registrite puhul piirangud andmetele (ärireeglid). Sõnasta mittefunktsionaalsed nõuded. Loo allsüsteemide seoseid väljendav paketidiagramm. Loo põhiobjekti seisundidiagramm (väljendab paljusid vastava funktsionaalse allsüsteemi funktsionaalsuseid). Loo seisundidiagrammi alusel funktsionaalse allsüsteemi kasutusjuhtude diagramm. Esimese versiooni PlantText jaoks saaks lasta genereerida. Loo funktsionaalse allsüsteemi kasutatavate registrite olemi-suhte diagrammid (esimese versiooni loomiseks saab kasutada mustreid). Genereeri olemi-suhte diagrammide põhjal esimene versioon olemitüüpide definitsioonidest. Täienda. Genereeri olemi-suhte diagrammide + ärireeglite põhjal esimene versioon atribuutide definitsioonidest. Täienda. Koosta nimekiri funktsionaalse allsüsteemi teenindatava (teenindamine tähendab nii andmete lugemist kui muutmist) registri andmete muutmise andmebaasioperatsioonidest. Genereeri olemi-suhte diagrammide + operatsioonide nimekirja põhjal esimene versioon operatsioonide lepingutest. Täienda. Lisa viited operatsioonidele seisundidiagrammile. Genereeri olemi-suhte diagrammide + kasutusjuhtude diagrammi põhjal esimene versioon kõrgtaseme formaadis kasutusjuhtude tekstikirjeldusest. Täienda. Genereeri olemi-suhte diagrammide + kasutusjuhtude diagrammi + seisundidiagrammi põhjal esimene versioon laiendatud formaadis kasutusjuhtude tekstikirjeldusest. Täienda. Genereeri laiendatud formaadis kasutusjuhu põhjal kasutusjuhu väljendatava elementaarse äriprotsessi tegevusdiagramm PlantText jaoks. Genereeri olemi-suhte diagrammide + (kasutusjuhtude diagrammi või laiendatud formaadis kasutusjuhtude) põhjal esimene versioon CRUD maatriksist. Täienda.   ***************** Edasi valik: a) Genereeri CASE vahendis olemi-suhte diagrammidest andmebaas disaini mudel. Täienda. Genereeri andmebaasi disaini mudelist SQL laused. Täienda. Käivita SQL laused.   b) Genereeri olemi-suhte diagrammide põhjal esimene versioon tabelite loomise lausetest. Täienda. Genereeri atribuutide definitsioonide põhjal esimene versioon kitsenduste defineerimise lausetest. Täienda. Käivita SQL laused. Visualiseeri loodud tabelite struktuur (iga registri kohta eraldi diagramm) kasutades näiteks DBeaverit. *****************   Genereeri laiendatud formaadis kasutusjuhtude + tabelite loomise lausete põhjal andmebaasi vaadete loomise laused (laiendatud formaadis kasutusjuhtudes peaks olema viited lugemisoperatsioonidele). Täienda. Genereeri andmebaasioperatsioonide lepingute + tabelite loomise lausete põhjal andmebaasi funktsioonide loomise laused. Täienda. Genereeri laiendatud formaadis kasutusjuhtude + mittefunktsionaalsete nõuete + vaadete ja funktsioonide põhjal andmebaasirakendus. Täienda.   **Märksõnad:** prompt, viip, suur keelemudel, llm, genereeriv TI, tehisintellekt, AI, mudelid, modelleerimine, model driven development ## Küsimus: Milliseid tehisintellekti vahendeid soovitate efektiivseks õppimiseks? **Vastus:** Oleks hea, kui õppeaines saab kasutada õppeaine materjalide alusel treenitud juturobotit, mis põhineb mõnel suurel keelemudelil. Kasutaja esitab küsimuse ja materjalide põhjal treenitud tarkvara annab vastuse. Selline robot aga vajab treenimiseks teksti, palju teksti. Sellel teemal on juba kaitstud ka lõputöid (see ja see). Sellise roboti ülespanek ja ülalhoid nõuab üksjagu pingutust. Samas areneb valdkond nii kiiresti, et on tekkinud pilveteenused, mis sisuliselt võimaldavad saavutada sama asja.Soovitan kindlasti proovida Google NotebookLM veebikeskkonda, mis on märkmete tegemise keskkond, mida toetab Google'i tehisintellekt. Keskkonda saab üles laadida õppematerjale ja nendega kasulikke asju teha. Erinevate ülesannete jaoks saab teha ja salvestada eraldi märkmikud. Kui laadite märkmikku üles oma aineprojekti pdf faili ning projekti kontrollimiseks väljapakutud viiba (tekstifaili) ning ütlete vestluses "Kontrolli dokumenti prompti alusel", siis saate kontrolli tulemuse, millel on juures viited: kohale dokumendis, kus on väidetavalt viga, reegli sõnastusele, mille alusel see viga tuvastati Kui viite peale klõpsate, siis võetakse kohe vastav koht sisenddokumentides lahti. Nii peaks olema kiirem ja mugavam üle vaadata, kus on tegelikud vead ja kus on viga vaid keelemudeli ettekujutuse vili. Kontrolli tulemused saab salvestada märkmetesse, et neid ka edaspidi vaadata. Väidetavalt hallutsioneerib (mõtleb välja asju, mis pole tõsi) NotebookLM vähem võrreldes sellega kui küsida sama asja otse Gemini käest. Teisalt on sellel vahendil selle võrra ka vähem loovust. Seega, kui tahate võimalikult täpseid vastuseid olemasolevate materjalide pealt, siis kasutage NotebookLM-i ning kui tahate loomingulisemaid tulemusi, siis küsige otse keelemudelilt (nt Gemini). NB! NotebookLM kasutamise puuduseks on, et see ei oska lugeda pdf failis olevaid jooniseid, mida jällegi Gemini läbi AI stuudio oskab. Seega ei saa NotebookLM kontrollida koondviiba reegleid skeemide kohta. See näitab, et parima tulemuse jaoks tuleks kasutada erinevate programmide kombinatsiooni.NB! Kasutades projekti kontrollimiseks Gemini AI stuudiot määrake temperatuuriks 0,2. See on midagi, mida NotebookLM keskkonnas ei saa teha. Üleslaaditud materjalide alusel saab lasta genereerida helilisi kokkuvõtteid - ka eesti keeles. Kokkuvõte on esitatud dialoogi vormis ja küllaltki kaasahaaraval viisil. Siin on katsetusena genereeritud ülevaade töövihiku sammudest 2-7 (põhiobjektide, tegutsejate, allsüsteemide leidmine), sammust 14 (kontseptuaalse andmemudeli koostamine) ja kontseptuaalsest andmemudelist. Need on tõstetud Sharepoint keskkonda, sest (vähemalt tasuta versioonis) saab märkmikus olla ainult kuni üks heliülevaade.  Kui valida "Loo", siis genereeritakse kokkuvõte kõigi märkmikus olevate materjalide põhjal. Kui valida "Kohandamine", siis saab esitada täpsema küsimuse (näiteks viidata mõne dokumendi konkreetsetele alajaotustele), mille alusel kokkuvõte genereerida. Tasuta versioonis saab päeva jooksul genereerida piiratud arvu (vastuse kirjutamise ajal kolm) kokkuvõtteid. Materjalideks saavad olla ka veebilehed või Youtube'i videod. Üleslaetud materjalide kohta saab esitada küsimusi ja tekitada niimoodi nagu oma kohandatud keelemudeli. Kõik materjalide põhjal keelemudeli poolt antud vastused saab märkmetena salvestada. Lisatud materjalidest saab genereerida (vaata lisatud faili): kokkuvõtte, õppematerjali, korduma kippuvad küsimused, mõttekaardi (vaata lisatud faili), ajaskaala. Kasutage linki https://maurus.ttu.ee/kysimused_markdown.php?aine=388, et lisada märkmikku kõik selle õppeaine avalikud küsimused. Seal on need esitatud markdown formaadis, mis on TI vahenditele kasutamiseks meelepärane formaat.Võtke mistahes selle (või mõne muu õppeaine) õppematerjal ja proovige järgi! SEE on vaid üks video paljudest, kus selle vahendi võimalusi tutvustatakse. Proovige katsetusena sellest endale kokkuvõte genereerida. Proovisin ise järgi - teeb eestikeelse kokkuvõtte, mis on vürtsitatud ingliskeelsete tsitaatidega. Oluline hoiatus sellest videost/kokkuvõttest: "Google on tuntud oma teenuste katkestamise poolest. Seepärast soovitatakse kasutajatel mitte salvestada kogu olulist teavet ainult NotebookLM-i, vaid see ka alla laadida ja mujale salvestada." Samas on oht, et selline liigne lootmine otsingusüsteemidele ja suurtele keelemudelitele viib mõttelaiskuseni, pealiskaudsuseni ja oma võimete ning teadmiste ülehindamiseni. ## Küsimus: Millist töövahendit saaks kasutada PostgreSQL andmebaasi tabelitest graafilise kujutise (kas HTML, pildifail või midagi taolist) loomiseks? Tööriist võiks olla vabavaraline, joosta Linuxi masinal ning ideaalis olla kasutatav käsurealt (et saaks kasutada ka skriptide sees). **Vastus:** Kui Teil on andmete modelleerimise CASE vahend, siis see võib toetada pöördprojekteerimist (reverse engineering) olemasolevast andmebaasist.Leidub ka eraldi andmebaaside haldusvahendeid, mis sellist funktsionaalsust pakuvad. Tõstan esile: DBVisualizer DBeaver Mõlema puhul on probleemiks, et visualiseerimise tulemuses ei näidata UNIQUE kitsendusi, CHECK kitsendusi, indekseid, kitsenduste ja indeksite nimesid.DBVisualizeris ei näe lisaks ka NOT NULL kitsendusi. Samuti ei saa seal teha eraldi diagramme andmebaaside erinevate alamosade kohta. DBeaveris on eraldi diagrammide loomine võimalik (Project => ER Diagrams). Looge kõigepealt tühi diagramm ja lohistage (drag and drop) seejärel sinna valik tabelitest. Täpselt nagu kontseptuaalse andmemudeli puhul võiks iga registri kohta luua eraldi diagrammid.DBeaveris on võimalik peita diagrammil osade, kuid mitte kõikide tabelite veerud. Selleks tuleb valida tabelit esitav kast ja parempoolse hiireklahvi alt avanevast menüüst valida Show Attributes => Selected Entity => None. Nii saate registri kohta käival diagrammil peita registrisse mittekuuluvate tabelite seosed, näidates samas registrisse kuuluvate tabelite seoseid teiste registrite tabelitega. ## Küsimus: Mul on arvutiks Mac / minu arvutil on Linux operatsioonisüsteem. Millist tarkvara soovitate kasutada? **Vastus:** Jutt on tarkvarast, mis on seotud kahe põhilise selle aine tegevuste plokiga. SQLi õppimine.  SQLi õppida, harjutada, teha põhitööd ja järeltööd on võimalik kasutades PostgreSQLi läbi veebipõhise keskkonna - siis pole Windowsi vaja. SQLi õppida, harjutada ja teha järeltööd on võimalik kasutades LibreOffice Base'i - siis pole samuti Windowsi vaja. LibreOffice Base kuulub avatud lähtekoodiga LibreOffice kontoripaketi koosseisu, mille allalaadimise koht on SIIN. SQLi õppimiseks, harjutamiseks, visuaalsel viisil põhitöö ülesannete lahenduste koostamiseks ja järeltöö tegemiseks saab kasutada MS Accessi. MS Access vajab Windowsi. Iseseisva töö projekti tegemine. Modelleerimiseks kasutame vaikimisi Enterprise Architect (12) või Rational Rose tarkvara. See tarkvara vajab Windowsi. EA14 näitel näen, et seda saab installeerida ka Maci, kuid see nõuab üsna palju lisatööd. Litsentsi taotlemine (bat failiga) on mõeldud just EA12 jaoks, st seda ei saa kasutada näiteks EA kodulehelt allalaaditud kõige viimasele EA versioonile litsentsi taotlemiseks. Andmebaasi ja andmebaasirakenduse prototüübi võib teha kasutades serveri andmebaasisüsteemi (nt PostgreSQL) ja luues veebirakenduse - siis pole Windowsi vaja. Andmebaasi ja andmebaasirakenduse prototüübi võib teha kasutades MS Accessi - siis on vaja Windowsi. Variant 1 - kasutada arvutiklasside Windows arvuteid kaugkasutuse korras Juhendi leiab SIIT.   Variant 2 - kasutada alternatiivset tarkvaraIseseisev tööKui tahate teha iseseisvat tööd töövihiku järgi, siis alternatiivse CASE tarkvara kasutamisel tuleb arvestada sellega, et Te ei saa kasutada etteantud diagrammi põhju, vaid need tuleb käsitsi nullist ise teha.Andmete modelleerimiseks soovitan kindlasti kasutada CASE vahendit, mis toetab andmete modelleerimist, mitte joonistusvahendit või andmete modelleerimise toeta CASE vahendit (nt ArgoUML).Andmete modelleerimist toetava CASE vahendi eelis on, et see suudab genereerida andmemudelist SQL koodi ja nii oluliselt suurendada Teie töö kvaliteeti ja tulemuslikkust.  SIIN on nimekiri mõnedest kasutaja arvutisse installeeritavatest tasuta CASE vahenditest ja SIIN on nimekiri mõnedest veebipõhistest tasuta CASE vahenditest.Iseseisva töö prototüüpi ei pea tegema MS Accessis nii et sellega muret ei ole. Saate näiteks kasutada PostgreSQLi, MySQLi, LibreOffice Base'i jne. PostgreSQL (17) on serveris apex2.taltech.ee, millele juurdepääsu küsimise kohta on info SIIN.Programmeerijatele, sh SQL lausete kirjutajatele mõeldud tekstiredaktorid: Notepad++ on saadaval Linuxile ja SciTe on saadaval nii Macile kui Linuxile.Andmebaasidega (sh PostgreSQL andmebaasidega) töötamiseks graafilist kasutajaliidest pakkuv DBeaver vahend on saadaval nii Macile kui Linuxile. Selliseid universaalseid programme on veel teisigi - vaata neid SIIT.Variant 3 - üritada tööle saada WindowsInternetist leiab juhiseid. Panin siia stiilinäiteks ühe juhise Maci ja ühe Linuxi kohta. Azure Dev Tools for Teaching keskkonnast on võimalik saada Windows Server operatsioonisüsteem.Variant 4 - veel võimalusiJuhend, kuidas installeerida Enterprise Architect (EA) 12 arvutisse, kus on macOS, kasutades ühilduvuskihti Wine.Installeerida EA12 oma Windowsi lauaarvutisse (tööl või kodus) ning taotleda litsentsi üle FortiClient VPNi. Tehes projekti rühmatööna saate tööd jaotada nii, et visuaalsete mudelite (diagrammide) loomisega tegelevad need projekti osalised, kellel on oma arvutis vajalik tarkvara.Kuna projekti tegemisel on võimalik kasutada töövihiku lahendust, kus suur osa diagrammidest on ette valmis tehtud, siis nende täiendamine ei võta liiga palju aega ja seda jõuab teha arvutiklassis. Arvutiklasse saab kasutada aine praktikumide ajal ja ka siis, kui klassi parajasti õppetööks ei kasutata (info selle kohta on klassi uksel). **Märksõnad:** kaugkasutus, MSAccess, vpn, kaug, kaugtöö, arvutiklass, kaugligipääs, kaugtöölaud, remote desktop ## Küsimus: PostgreSQL EXCLUDE kitsendus: millal seda kasutada ning miks ilmub see kõikides näidetes fraasi "EXCLUDE USING gist" kujul? **Vastus:** EXCLUDE on PostgreSQLi laiendus - SQL standard seda ette ei näe ja teised andmebaasisüsteemid seda ei paku. Kuid see on väga kasulik laiendus. See on UNIQUE kitsenduse üldistus selles mõttes, et unikaalsuse kontrollimisele saab kasutada väärtuste võrdlemiseks ka muid operaatoreid kui =. Näiteks saab selle abil andmebaasi tasemel deklaratiivsel viisil tagada, et tabelis esitatud ajaliste väärtuste perioodid ei oleks osaliselt ega täielikult kattuvad. Näiteks, kui isikule X on määratud roll Y ajaperioodiks 1. jaanuar 2021 kuni 31. detsember 2021, siis ei saa talle seda sama rolli määrata ajaperioodiks 1. märts 2021 kuni 1. juuni 2021 või 1. märts 2021 kuni 31. detsember 2022.  See on "kangem" unikaalsuse kontroll kui UNIQUE (isik_id, rolli_kood, alguse_aeg). EXCLUDE abil saaks kontrollida ka tavalist unikaalsust, kuid kontrolli töökiiruse (aeglasem kui tavalise UNIQUE kontroll) ja porditavuse (teistesse süsteemide ülekandmise) mõttes pole see hea lahendus. EXCLUDE kitsenduse abil saab realiseerida ka kontrolle, mida muidu tuleks teha (osaliselt) unikaalse indeksiga. Tõstutundetu unikaalsus. Näiteks kui tabeli Isik veerus e_meil on juba mingis väljas aadress 'kask@hot.ee', siis ei saa sinna tabelisse lisada aadressi 'Kask@hot.ee'. Osaline unikaalsus. Näiteks, aktiivses seisundis kaupade nimetused peavad olema unikaalsed. Kui kaup ei ole aktiivses seisundis, siis selle nimetus ei pea olema unikaalne. Unikaalsuse kitsenduse kontrollimise toetuseks loob PostgreSQL automaatselt B+ puu tüüpi indeksi (indeksitüübi nimeks on küll B-puu, kuid realisatsioon vastab B+ puule, sest viited ridadele on ainult puu lehtedes). Kujutage ette, mis juhtuks ilma indeksita - tabelis on miljon rida, tabelisse lisati uus rida, reas oleva väärtuse unikaalsuse kontrollimiseks tuleks süsteemil kõik need read läbi vaadata. Mida rohkem oleks tabelis ridu, seda rohkem tuleks kontrollimiseks tööd teha (andmeid lugeda) ja seda aeglasemaks muutuks kontrollimine. See, kui süsteemi töökiirus langeb, mida rohkem süsteemi kasutatakse, vastab töökiiruse antimustrile hüppelaud (ramp).Ka EXCLUDE kitsenduse toetuseks vajab andmebaasisüsteem indeksit. Arvestades võrdluseid, mida süsteem peab EXCLUDE kitsenduse täidetuse kontrollimiseks läbi viima, ei sobi B+ puu tüüpi indeks, vaid sobib indeks tüüpi GIST. SIIN on EXCLUDE kitsenduse kasutamise koodinäiteid. ## Küsimus: Saan MS Teamsi avamisel teate "Me ei saanud ühendust luua. Logi sisse ja proovime uuesti". Uuesti proovimine ei aita. Mida teha? **Vastus:** SIIN on tegevusjuhend, mida tasub proovida sellisest veast vabanemiseks. Credential manager = Mandaadihaldur. Sulgege Teams. Avage tegumihaldur (Ctrl+Alt+Del) ja lõpetage kõik MS Teamsi tegumid.%appdata%\Microsoft\teams saab kirjutada Windowsi otsingusse ja kataloog avatakse automaatselt. Peale kataloogi sisu kustutamist ja enne Teamsi uuesti sisselogimist võiks teha arvuti taaskäivituse. **Märksõnad:** MS Teams, kaug, kaugtöö --- # Teema: Õppekeskkond ## Küsimus: Kas ainel on koduleht ka Moodles? **Vastus:** Jah on.Kodulehe versioon Moodles: https://moodle.taltech.ee/course/view.php?id=34766Registreerumise võti: ITI0206_K2025Moodle lehele registreerijad näevad kursuse põhisündmuseid oma Moodle kalendris. Materjalid on Mauruse keskkonnas, kuid Moodle pakub ühe võimaliku juurdepääsutee nendele materjalidele ja soovi korral võib Moodle olla ÜKS JA AINUS koht, mille kaudu materjalideni liikumist alustate. Siiski peab ennast ka Mauruses registreerima, et materjalidele ligi pääseda. Mauruse konto on vajalik ka selleks, et pääseda ligi SQL Lahendaja ning testide tegemise keskkondadele. ## Küsimus: Kas iseseisva töö juhendis ja näiteprojektis on võimalik mugavalt erinevate alamosade vahel liikuda? **Vastus:** Jah on.Nendes pdf failides on järjehoidjad (bookmarks), mis võimaldavad dokumendis erinevate alamosade vahel hõlpsasti navigeerida. Kahjuks, sõltuvalt kasutatavast veebilehitsejast, ei ole see alati automaatselt esile tõstetud. Kui vaatate neid faile Firefoxi veebilehitsejas, siis on need järjehoidjad lehe vasakus servas kohe näha.Kui vaatate neid faile Chrome veebilehitsejas, siis tuleb lehe vasakust servast valida jaotis Dokumendi liigendus.Kui vaatate neid faile Edge veebilehitsejas, siis tuleb lehe vasakust ülaservast valida Sisukord.Kui vaatate neid faile Opera veebilehitsejas, siis tuleb lehe vasakust servast valida jaotis Document outline.Chrome, Edge ja Opera puhul tuleb kõige kõrgema taseme pealkirjale klõpsata, et näha selle all olevaid alampealkirju.Vastusele on lisatud illustreerivad pildid. **Märksõnad:** navigeerimine, järjehoidja ## Küsimus: Kuidas ennast kodulehele registreerida? **Vastus:** Lehele ligipääsemiseks tuleb ennast registreerida.Palun kasutage konto juures sellist meiliaadressi, millele saabuvaid kirju Te igapäevaselt jälgite. Sellele aadressile hakkab saabuma aine korralduslik ja muu info. Seda võib vaja minna õppejõul, et Teiega ühendust võtta. Kui kasutate https://maurus.ttu.ee keskkonda esmakordselt, siis valige õppeaine lehelt menüüst Üldist=> Lehele registreerumine. Täitke vorm ja vajutage nupule "Registreeri". Kui juba olete õpikeskkonnas mingile lehele registreerunud (vahet pole, kas üks või kümme aastat tagasi), siis valige Mauruse esilehel menüüst Üldist=>Minu konto ja lisage enda aktiivsete lehtede hulka: "Andmebaasid I (ITI0206) (kevad 2025)" Ärge unustage vajutada "registreeri". Kui olete unustanud parooli, siis SIIN saab seda nullida. Kui Te ei mäleta kasutajanime/meiliaadressi, siis pöörduge õppejõu poole! Vajadusel muutke meiliaadressi, et see oleks selline, millele saabuvaid kirju Te igapäevaselt jälgite. Registreerumise järel peate ootama kuni õppejõud Teie juurdepääsu õiguse kinnitab. Kinnitamise kohta saadab süsteem automaatselt meili.   ## Küsimus: Kuidas näha siin kodulehel õppeaine materjale nagu need oleks Moodles? **Vastus:** Valige Kiirvalik=> Nagu MoodleKui meeldib, siis märkige see järjehoidjas õppeaine koduleheks. **Märksõnad:** Moodle, alternatiivne esitus ## Küsimus: Kus on kodulehel jooksvad tulemused? **Vastus:** Klõpsake Kiirvalik=>Hinneteleht (link on nähtav ainult siis, kui on avaldatavaid tulemusi). **Märksõnad:** punktid, lisapunktid, vahetest, vahetestid ## Küsimus: Kus on kodulehel loengute lindistused? **Vastus:** Valige menüüst Videod=>Loengud **Märksõnad:** loengud, loeng, lindistus, lindistused, salvestus, salvestused, video, videod ## Küsimus: Materjale on liiga palju! Kuidas tulla toime suure materjalide hulgaga? **Vastus:** Kõige esimese asjana peaksite tegema aine kohta Google NotebookLM märkmiku, kuhu saate üles laadida kõik aine materjalid ja mis pakub Teile sisuliselt ainepõhise juturoboti, mis võimaldab üle aine materjalide küsimusi esitada ja kokkuvõtteid genereerida. SEE on vaid üks paljudest headest videotest selle vahendi kohta.Kõiki materjale ei pea sugugi lugema. Te saate valida kolme materjalide kasutamise taseme (õpiraja) vahel. Valige tase vastavalt oma huvidele ja eesmärkidele.Tase 1 Neile, kellele piisab "läbi saamisest". Loe ainult materjale: Kiirvalik => Kohustuslikud materjalid Materjalid korralduse ja projekti kohta. SQL andmebaasikeele ning teooria kohta leiab materjali väga paljudest allikatest. Teooria testideks saab valmistuda harjutuskeskkonnas harjutades. Tase 2 Neile, kes soovivad õpiväljundid heatasemeliselt saavutada. Loe igal nädalal materjale:  Kiirvalik=>Nagu Moodle VÕI Kiirvalik=>Nädalad (samad materjalid, erinevalt esitatud) Igal nädalala jaoks kõige olulisemad materjalid. Pööra tähelepanu ka materjalide juures olevatele seotud dokumentidele. Lisaks on iga nädala kohta välja toodud soovitavad tegevused seoses ainega (nädalate peale kokku moodustab õppimise tegevuskava). Tase 3 Neile, kes soovivad süveneda ja saada põhjalikke teadmisi. Lisaks nädala materjalidele lugege ka muid materjale (alajaotis Materjalid) ning kasutajatoe küsimusi ja vastuseid (Abi ja tugi => Kasutajatugi). Nädala materjalide juures on viited seotud dokumentidele ja lähedastele materjalidele. Kasutage otsingut! **Märksõnad:** Maurus, materjalid, kuidas õppida, õpirada, fail, failid ## Küsimus: Mida saab teha Mauruses, mida Moodles ei saa? **Vastus:** Järgmised võimalused on Mauruses, kuid puuduvad Moodles. Loodetavasti kiirem reageerimine funktsionaalsuse või kasutajaliidese muutmise soovidele. Kasutajaliidese uus versioon valmis Groki ja Gemini TI vahendite abil päevadega. Üliõpilastele säilib juurdepääs õppeaine kodulehele ning seal olevatele materjalidele ka peale ülikoolist lahkumist. Isegi kui koduleht on Mauruse pealehelt eemaldatud, pääseb sellele endiselt ligi kas otseviitega või läbi pealehelt avaneva Minu konto alajaotuse. Hakates uuel semestril õppeainet uuesti õpetama loon Mauruses uue kodulehe (vana säilib) ning saan sinna enda valikul vanalt kodulehelt informatsiooni kopeerida. Ka Moodles luuakse uuel semestril uus lehekülg ning vanale säilib juurdepääs, kuid see juurdepääs on vaid senikaua kuni saate kasutada UniID-d Ka Mauruses saab õppijatelt võtta juurdepääsu õppeaine kodulehele, kuid see on õppejõu otsus, mitte keskkonnast tulenev paratamatus. Mauruses saab õppija igal ajal ise kustutada oma registreerimise õppeaine lehele või ka kogu konto (kustutatakse tema registreerimised kõikidele õppeaine lehtedele). Kustutatakse kõik andmed, sh kasutaja üleslaetud failid ja kasutaja tegevuste logi. Materjale saab kasutaja jaoks grupeerida mitmel erineval viisil. Selleks on kataloogide hierarhias paiknevatele. materjalidele pealisehitusena lisatud vaadete mehhanism (vt menüüd Vaated materjalidele), mis võimaldab materjale kasutaja jaoks erineval viisil grupeerida. Vaade Kiirvalik=>Nädalad võimaldab välja tuua konkreetsel õppenädalal kõige olulisemad materjalid. Sisuliselt on nädala vaade selle nädala tegevuskava. Üks ja sama materjal võib olla seotud mitme nädalaga. Arendajatel on lihtne vajadusel uusi vaateid lisada. Analoogia: Kui materjalide all olev kataloogide hierarhia on nagu hierarhiline dokument dokumendipõhises andmebaasis (nt MongoDB abil loodud), siis vaated materjalidele on nagu selle dokumendi põhjal loodud (mitte-materialiseeritud) vaated. MongoDB toetab selliste vaadete loomist alates versioonist 3.4. Üks vaade materjalidele on nende esitus nagu see oleks Moodles (Kiirvalik=>Nagu Moodle) - kursuse materjalid ja ka muu oluline info on ühel suurel lehel nädalate kaupa välja toodud. Üliõpilane saab tähistada materjale (märkida need lemmikuks) nii, et sellised materjalid on pärast kõik ühest kohast leitavad. Õppejõud saab esile tõsta, millised materjalid on kohustuslikud (peaks igal juhul lugema) ja milliseid võib aja või huvipuudusel lugemata jätta. Kohustuslikud materjalid on erinevates vaadetes ühtemoodi esile tõstetud ja on lisaks koondatud vaatesse Kiirvalik=>Kohustuslikud materjalid Vaadete kasutamise eelis seisneb ka selles, et materjale ei ole vaja dubleerida. Sama materjal võib olla erinevates vaadetes. Miks see on õppija jaoks tähtis? Kui materjale on vaja täiendada/täiustada, siis õppejõud peab seda tegema ühes kohas. Sellega: tagatakse muudatuste võimalikult kiire tegemine (lugejani jõuab kõige viimane ja kõige täpsem info võimalikult kiitesti), välditakse olukorda, kus samast materjalidest on õppekeskkonna erinevates osades mittekooskõlalised koopiad. Näiteks moodulis 1 on materjal, mis ütleb, et testiks tuleb lugeda A ja B kuid moodulis 2 on materjal, mis ütleb, et testiks tuleb lugeda A, B, C ja D. NB! Samad eelised on vaadetel ja andmete dubleerimise vältimisel ka andmebaaside maailmas. Kasutaja saab vaadata (alajaotus Isiklik) enda kõige viimati vaadatud faile või enda kõige rohkem vaadatud faile ja niimoodi leida kiiresti üles materjali, mida ta kunagi on juba vaadanud. Kasutajatel on võimalus teha otsing üle aine sisu kirjelduse, materjalide metaandmete, tegevuskava, teadete (v.a isiklikud teated), kasutajatoe küsimuste/vastuste, mõistete, viidete, tähaegade, ülesannete (kuid mitte nende vastused) ja vastuvõtuaegade. Näen, et otsingut kasutatakse palju. Võimalus vaadata ilma sisse logimata kõiki kasutajatoe avalikke ja vastatud küsimusi markdown formaadis ja anda see lehekülg sisendiks TI vahendile (nt Google NotebookLM), mis võimaldab selle info põhjal küsimusi küsida. Süsteemis kogutud info tehtud otsingute kohta annab õppejõule võimaluse materjalide annotatsioone täiendada, et samasuguse otsingu tulemused oleksid edaspidi täpsemad. Materjalidele ja kasutajatoe küsimustele/vastustele saab lisada põhjaliku annotatsiooni, mida kasutaja vaikimisi ei näe, kuid mida kasutatakse eelmises punktis nimetatud otsingus. Võimalus panna välja suurel hulgal individuaalseid projektide ettenäitamise aegu (st üliõpilased ei pea tulema kaitsmise sessiooni alguseks kohale ja seal elavas järjekorras ootama). Võimalus tagada, et projekti mitmekesi tegijad, ei saaks broneerida mitu ettenäitamise aega ja välistada sellest tulenev ebaõiglus nende suhtes, kes teevad projekti üksinda. Kasutajatugi ning võimalus seal olevaid korduvaid küsimusi avalehele kinnitada ning küsimusi/vastuseid kõigile üliõpilastele meilile saata (sh korduvalt). Võimalus muuta avalehel näidatavate korduvate küsimuste järjekorda ning hulka. Võimalus neid küsimusi esile tõsta. Võimalus valida, millised teated saadetakse üliõpilasele meilile ja milliseid mitte (vähem ebaolulisi meile). Võimalus valida, milliste kalendri sündmuste meeldetuletused ainele registreerunute meilile saata ja millised mitte. Nii üliõpilasel kui õppejõul on võimalik saada kiiresti ülevaade, millisele teadmiste kontrollile on veel vabu kohti ja millisele mitte. See on väga oluline olukorras, kus on väljas näiteks 50-100 projekti näitamise aega. Üliõpilane ei saa sama tüüpi teadmiste kontrollile olla samaaegselt mitmekordselt registreeritud. See aitab tagada, et vabu kohti ei hõivataks ilmaasjata ning et neid jätkuks suuremale hulgale soovijatele. Õppejõul on võimalus saata meeldetuletus kõigile üliõpilastele, kes mingit tüüpi teadmiste kontrollile ei ole veel registreerunud (on selle unustanud või mäletavad ekslikult, et registreerisid, kuid tegelikult ei teinud seda). Kui projekt on arvestatud ja üliõpilane paneb ennast uuesti projekti näitamisele kirja või unustab varem tehtud registreerimise tühistada, siis saan päringuga selle üles leida ja operatiivselt sellise registreerimise tühistada. Vabad ettenäitamise ajad on oluline ning projektide näitamiste tippajal paljudele huvi pakkuv ressurss. Saab teha nii, et lingi alusel materjali (faili) allalaadides ei pea kasutaja ennast tuvastama - teiste sõnadega materjali saavad kasutada kõik, kes teavad linki. Võimalik loengu otseülekande toimumise ajal seda kodulehe avalehel automaatselt esile tõsta. Eesti- ja ingliskeelse terminoloogiaga mõistete sõnastik, mis on integreeritud materjalidega ja pakub täiendavaid märksõnu mille alusel otsing leiab üles olulisi/vajalikke materjale. Üliõpilane saab vaadata sõnapilve materjalide juures kasutatud märksõnadest, mis pakub kõrgtaseme ülevaate materjalide temaatikast. Üliõpilased ja õppejõud näevad, millised materjalid on lugemata ja kuidas edeneb üliõpilastel materjalidega tutvumine võrreldes teiste üliõpilastega. Üliõpilane saab hinnata (skaalal 1-5) abiinfo keskkonnas esitatud küsimuste vastuseid. Kui õppejõud näeb, et mõnda vastust on halvasti hinnatud, siis ta saab seda parandada. Integratsioon Mauruse testide tegemise keskkonnaga, mis võimaldab testide harjutamise juures näidata harjutajatele valesti vastatud testiküsimuse juures viidet materjalidele, kust saab infot küsimuse valdkonna ja õige vastuse kohta. Õppejõud saab kasutajate jaoks materjale ja katalooge esile tõsta nii, et tulemus tõepooles ülejäänud materjalidest ja kataloogidest visuaalselt eristub. **Märksõnad:** Moodle, e-õpe, e-tugi,e-kursus ## Küsimus: Miks on nii, et Mauruse testikeskkond näitab, et vastamise lõpetamiseni on veel aega, kuid tegelikult on aeg täis? **Vastus:** Arvuti kell jääb maha. Siin kirjeldatakse selle mõningaid põhjuseid Windowsi korral. Sarnane probleem esineb ka Mac arvutites. ## Küsimus: Millisel viisil saab esitada soove selle kohta, kuidas muuta andmebaaside õppeaine kodulehed Moodles ja Mauruses paremini kasutatavaks ja materjalid kergemini ülesleitavaks? **Vastus:** Soovid saab kirja panna SIIA (anonüümselt). Ma olen sealt saanud häid ideid, mille alusel olen kodulehti ja materjale parandanud. Tänan juba ette konstruktiivsete ettepanekute eest! **Märksõnad:** tagasiside, Maurus, anonüümne, kasutatavus, funktsionaalsus, Moodle ## Küsimus: Mulle ei meeldi üldse, kuidas õppejõud Mauruse keskkonnas minu tegemisi jälgib. Kuida kommenteerite? **Vastus:** Ajastu vaim ongi selline, et inimene jätab igal sammul ennast maha jälgi andmetena ning keegi kuskil kogub ja otsustab midagi nende andmete põhjal.Õpingutest rääkides, siis ülikool on väga huvitatud üliõpilaste edukast ja õigeaegsest lõpetamisest, sest sellest sõltub riigi poolne rahastus. Õpianalüütika on maailmas oluline uurimus- ning arendusteema (vt näitena doktoritööd) ning sellel teemal on ka meie ülikoolis kaitstud mitmeid lõputöid (nt SEE, SEE ja SEE). Selles vallas teeb suurt tööd Ago Luberg ja tema juhendamisel arendatavad süsteemid on seotud Moodlega ning võimaldavad Moodlesse kogutud andmeid paremini esitada ja analüüsida. Ka Moodles on õppejõul ülevaade sellest, mida iga konkreetne kasutaja (õppija) on materjalidega seoses teinud (vt lisatud pilti).Kindlasti ei jälgi ma materjalide kasutust igapäevaselt ning materjalide kasutamine pole hindamiskriteerium. Aines kohustuslikke materjale on võrreldes kodulehel oleva üldiste materjalide hulgaga väikene osa ja need materjalid puudutavad korraldust ning projekti tegemist. Siiski, kui märkan, et pikema perioodi jooksul pole üliõpilane kodulehte kasutatud, siis tunnen huvi, kas tal on õppimisel mingid takistused/probleemid ja kuidas saaksin aidata neid lahendada.Mauruses saate vaadata infot enda tegemiste kohta kodulehelt SIIT. Kui kustutate peale semestri lõppu oma registreerimise kodulehele, siis kustutatakse ka need andmed. ## Küsimus: Soovin Teamsis vaadata praktikumi lindistust, kuid saan teate 404 NOT FOUND. Kuidas ma saan vaadata praktikumide lindistusi? **Vastus:** Teamsi lindistused lähevad meeskonnaga seotud kataloogi alamkataloogi Recordings. Peale lindistamist muudan faili nime arusaadavamaks ning lisan annotatsiooni. Kuna faili nimi muutub, siis Teamsi kanalis olev link enam ei tööta.Praktikumide lindistuste vaatamiseks tuleb valida õppeaine kodulehelt:Kiirvalik=> Praktikumide lindistusSee viib õigesse kataloogi. Kataloogi minnes on iga lindistuse faili juures näha ka annotatsioon (märksõnad selle kohta, millest räägiti). **Märksõnad:** Teams, Sharepoint, lindistus, salvestus, lindistused, salvestused