15/1/2009 Úvod do databáz, skúškový test, max 25 bodov, 90 min 0. Súhlasím so zverejnením výsledku môjho testu vo forme [Meno, Výsledok] na webstránke prednášky. ÁNO (1), NIE (0). ÁNO 1. Daná je databáza: capuje(krcma, Alkohol, Cena), navstivil(idn, Pijan, Krcma), lubi(pijan, Alkohol), vypil(idn, Alkohol, Mnozstvo). a) Sformulujte nasledujúci dotaz v Datalogu (2) a v SQL (2): Nájdite pijanov, ktorí každý akt vypitia alkoholu urobili v tej krčme (resp. v jednej z krčiem), v ktorej je ten alkohol najlacnejší. (Inak povedané: O každom z hľadaných pijanov platí, že kedykoľvek ten pijan nejaký alkohol vypil, tak ho vypil v krčme, ktorá ten alkohol čapuje najlacnejšie zo všetkých krčiem.) Abstinenti nemajú byť vo výsledku. Datalog: answer(p) navstivil(i, P, _), vypil(i, _, _), /* toto vylučuje abstinentov */ not frajer(p). frajer(p) /* Stačí keď ten pijan niekedy nejaký alkohol vypil, pričom mal lacnejšiu možnosť. Nepotrebujeme poznať minimálnu cenu toho alkoholu. */ navstivil(i, P, K), vypil(i, A, _), capuje(k, A, C1), capuje(k2, A, C2), C1 > C2.
Alternatívne riešenie (tu sa naozaj počíta minimálne ceny alkoholov, ktoré pijan vypil): answer(p) navstivil(i, P, _), vypil(i, _, _), /* toto vylučuje abstinentov */ not frajer(p). frajer(p) navstivil(i, P, K), vypil(i, A, _), capuje(k, A, C), min_cena(a, Cmin), C > Cmin. min_cena(a, Cmin) capuje(_, A, _), subtotal(capuje(_, A, C), [A], [min(c, Cmin)]). SQL: create temporary table frajer as from navtivil N, vypil V, capuje C1, capuje C2 where N.idn = V.idn and N.krcma = C1.krcma and V.alkohol = C1.alkohol and V.alkohol = C2.alkohol and C1.cena > C2.cena from navstivil N, vypil V where N.idn = V.idn and not exists ( select * from frajer F where N.pijan = F.pijan)
Alebo (bez create temporary table): from navstivil N, vypil V where N.pijan not in ( from navtivil N, vypil V, capuje C1, capuje C2 where N.idn = V.idn and N.krcma = C1.krcma and V.alkohol = C1.alkohol and V.alkohol = C2.alkohol and C1.cena > C2.cena) b) Sformulujte nasledujúci dotaz v relačnom kalkule (2), Datalogu (2), SQL (2) a relačnej algebre (2): Nájdite dvojice [Pijan, Suma], ktoré hovoria, koľko peňazí ten pijan celkovo prepil v krčmách, ktoré čapujú len alkoholy, ktoré ten pijan neľúbi. Dvojice s nulovou sumou nemajú byť vo výsledku. Relačný kalkul: {[P, T]: ( I K navstivil(i, P, K)) I, A, T=sum(S) ( K C M capuje(k, A, C) navstivil(i, P, K) vypil(i, A, M) S = C * M ( A C capuje(k, A, C) lubi(p, A)))} Datalog: answer(p, T) navstivil(_, P, _), subtotal(vypil_nelubi_nic(_, _, P, S), [P], [sum(s, T)]). vypil_nelubi_nic(i, A, P, S) capuje(k, A, C), navstivil(i, P, K), vypil(i, A, M), S is C * M, /* to is vyžaduje Prolog, S = C * M je OK */ not lubi_nieco(p, K). lubi_nieco(p, K) capuje(k, A, _), lubi(p, A).
SQL: create temporary table lubi_nieco as select L.pijan, C.krcma from lubi L, capuje C where C.alkohol = L.alkohol create temporary table vypil_nelubi_nic as, C.cena * V.mnozstvo as suma from capuje C, navstivil N, vypil V where C.krcma = N.krcma and C.alkohol = V.alkohol and N.idn = V.idn and not exists ( select * from lubi_nieco LN where N.pijan = LN.pijan and N.krcma = LN.krcma) /* main */ select VNN.pijan, sum(vnn.suma) as total from vypil_nelubi_nic VNN group by VNN.pijan Relačná algebra: Γ pijan, sum(cena * mnozstvo) (capuje ( Π pijan, krcma (navstivil) - Π pijan, krcma (lubi capuje)) (navstivil vypil)) To distinct ( ) nie je v skutočnosti nutné. Množinové operácie (rozdiel, prienik, zjednotenie) sa totiž v relačnej algebre chovajú tak ako v SQL, t.j. operátor sa pred operandy pridá automaticky. (Ak by sme uvažovali multimnožinový rozdiel, bolo by tak je operátor distinct,, skutočne potrebný.) Alebo: Γ pijan, sum(cena * mnozstvo) ((capuje navstivil vypil) Π pijan, krcma (lubi capuje)) Operátoru sa hovorí antijoin a je definovaný takto: r(a, B) s(a, C) = r(a, B) (Π A (s) x Π B (r))
2. Dané sú relácie r(x, Y) a s(x, Y), žiadna z relácií neobsahuje hodnotu NULL. a) Zapíšte oba dotazy Q1 a Q2 v Datalogu (2): Q1: select distinct R2.X from r R1, r R2, s S where R1.X = R2.Y or R1.X = S.X Q2: select distinct R1.X from r R1, r R2 where R1.Y = R2.X q1(x) r(z, _), r(x, Z), s(_, _). q1(x) r(z, _), r(x, _), s(z, _). q2(x) r(x, Z), r(z, _). b) Rozhodnite, či sú dotazy Q1 a Q2 z úlohy a) ekvivalentné. Ak sú, dokážte. Ak nie sú, uveďte kontrapríklad a vysvetlite, za akých podmienok ekvivalencia platí. (3) Vo všeobecnosti Q1 a Q2 ekvivalentné nie sú. Napríklad pre relácie r(x, Y)={[1,1]} a s(x, Y)= je výsledkom dotazu Q1 prázdna množina, zatiaľ čo výsledkom dotazu Q2 je dvojica [1, 1]. Ak je relácia r prázdna, tak Q1 a Q2 sú zjavne ekvivalentné. Ak neuvažujeme to druhé pravidlo pre q1(x), tak Q1 a Q2 sú ekvivalentné za predpokladu, že s(x, Y) je neprázdna relácia. Ak množiny hodnôt prvých atribútov r a s sú disjunktné, tak to druhé pravidlo do výsledku Q1 nič nové nepridá. Ak sa niektoré r.x a s.x zhodujú, tak to druhé pravidlo pre q1(x) pridá do výsledku Q1 množinu hodnôt prvého atribútu r. Do výsledku Q2 sa pridá to isté práve vtedy, ak množina hodnôt prvého atribútu r je podmnožinou hodnôt druhého atribútu r. V jazyku relačného kalkulu: Q1 a Q2 sú ekvivalentné práve vtedy, ak pre relácie r a s platí ( X Y r(x, Y)) (( X Y s(x, Y)) ( ( X Y1 Y2 r(x, Y1) s(x, Y2)) (( X Y r(x, Y)) ( Z r(z, X))) ) ) ( X Y r(x, Y)) (( X Y s(x, Y)) ( X1 X2 Y1 Y2 ((r(x1, Y1) s(x2, Y2)) X1 X2)) ( X Y Z (r(x, Y) r(z, X))) ).
V jazyku relačnej algebry: Q1 a Q2 sú ekvivalentné práve vtedy, ak platí r = (s ( X s X r = X r X s)). 3. a) Vysvetlite čo je motiváciou checkpointingu. (1) Popíšte čo najpresnejšie, aké akcie (a v akom poradí) systém vykoná, keď sa rozhodne urobiť checkpoint. (1) Motiváciou checkpointingu je skrátenie log-file a skrátenie času obnovy po výpadku. Keď sa systém rozhodne vykonať checkpoint, tak urobí toto: 1.Prestane vykonávať transakčné operácie. 2.Zapíše všetky dosiaľ nezapísané log záznamy na disk. 3.Zapíše všetky dosiaľ nezapísané dáta na disk. 4.Pridá do log-file záznam <CHECKPOINT> (spolu so zoznamom aktívnych transakcií). Po zapísaní tohto záznamu na disk môže systém skrátiť log-file. 5.Obnoví normálnu prevádzku. Keďže kroky 2 a 3 môžu byť časovo náročné, v implementácii je rozumnejšie použiť techniku fuzzy checkpoints (ale tá bola v prednáške len načrtnutá). b) Databázový systém spadol. Pri opätovnom štarte obsahuje log-file nasledujúce záznamy: <T1, start>, <T1, X, 1, 2>, <T2 start>, <T1, Y, 4, 3>, <T2, Z, 0, 5>, <T1, commit>, <T3, start>, <T3, X, 2, 7>. Popíšte čo najpresnejšie všeobecný algoritmus obnovy (1) a uveďte sekvenciu zápisov do databázy, ktoré systém vykoná počas obnovy v tomto konkrétnom prípade. (1) Všeobecný algoritmus obnovy prechádza log-file najskôr zostupne. Počas tohto prechodu vytvára zoznamy redo_list a undo_list a zároveň robí UNDO pre transakcie z undo_list. Keď príde na začiatok log-file, začne vzostupný prechod, pri ktorom vykonáva REDO pre transakcie z redo_list. Keď príde na koniec log-file, začne systém normálnu prevádzku. Pre daný log-file vykoná systém nasledujúcu sekvenciu zápisov: X = 2 (undo T3) Z = 0 (undo T2) X = 2 (redo T1) Y = 3 (redo T1)
4. V systéme beží naraz viacero inštancií tej istej transakcie T (a žiadne iné). Transakcia T je deterministická (t.j. pri každom spustení generuje rovnakú sekvenciu transakčných operácií nad rovnakými dátami) a vnútorne neobsahuje nekonečný cyklus (t.j. ak v systéme beží len jedna inštancia T a nič iné, tak T skončí). Systém používa striktné dvojfázové zamykanie. Rozhodnite a zdôvodnite, či môžu transakcie skončiť v deadlocku, ak sa systém deadlockom nevyhýba. (Ak nemôžu, dokážte. Ak môžu, uveďte konkrétny príklad deadlocku.) (3) Nemôžu skončiť v deadlocku. Dôkaz: Ak T neobsahuje žiadnu operáciu write, tak deadlock zrejme nastať nemôže. Predpokladajme, že T obsahuje aspoň jednu operáciu write. Všimnime si prvý writelock v transakcii T. Nech transakcia T1 získa tento write-lock ako prvá. Potom žiadna iná transakcia jej už nezabráni, aby skončila. Ak by totiž T1 mala čakať, kým nejaká iná transakcia T2 uvoľní zámok o ktorý T1 v tej chvíli žiada, musela by T2 ten konfliktný zámok vlastniť. Ten konfliktný zámok musí byť write-lock (keďže T1 a T2 sú inštancie rovnakej transakcie, len write-lock môže spôsobiť konflikt). To však znamená, že T2 by musela vlastniť aj ten prvý write-lock ale to nemôže, lebo ten vlastní T1. Keď transakcia T1 skončí, tá istá argumentácia platí pre nasledujúcu transakciu, ktorá získa prvý ten write-lock ako prvá.