Kodulehed
[386] - Andmebaasid I (ITI0206) (kevad 2024)
Esiletöstetud Kiirvalik
Lisainfo Kõige olulisemate tegevuste kiirvalik. Failide saatmiseks valige Vastamine alt sobiv ülesanne.
Üldist
Materjalid
LisainfoMaterjalide kataloogid
Isiklik
Lisainfo Info ainult Sulle - teised kasutajad seda ei näe
Abi
Lisainfo Võimalus küsida õppejõult abi (nagu foorum, kus saab küsida küsimusi ja kommenteerida vastuseid)
Mitmesugust
Abi / Kasutajatugi / Andmebaasi kavandamise sisulised küsimused

Avalikud küsimused ja vastused:

Küsimuste teemade nimekiri

Erki Eessaar (16.02.2023 15:30):
Miks on halb mõte kasutada erinevates tabelites ühesuguse nimega (id, kood või code) primaarvõtme veergu?
Vastus (06.02.2024 20:57): 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äring

SELECT Mark.id AS mark_id, nimetus, Auto.id AS auto_id, registri_nr
FROM 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_nr
FROM 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_nimetus
FROM Klient INNER JOIN Tellimus ON Klient.id=Tellimus.klient_id
INNER JOIN Tellimuse_rida ON Tellimus.id=Tellimuse_rida.tellimus_id
INNER 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_nimetus
FROM 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.

Hinda vastust:

Keskmine hinne : 5.0