Skip to content

Commit

Permalink
WS2021/22 release
Browse files Browse the repository at this point in the history
  • Loading branch information
Johannes Schildgen committed Feb 28, 2022
1 parent bc45cf8 commit d730d25
Show file tree
Hide file tree
Showing 26 changed files with 389 additions and 9,268 deletions.
31 changes: 16 additions & 15 deletions 6.html
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,12 @@ <h2>Funktionen</h2>
<pre><code class="sql dont_execute_sql" contenteditable>CREATE OR REPLACE FUNCTION addieren(int, int) RETURNS INT AS
$$ BEGIN RETURN $1+$2; END $$ LANGUAGE plpgsql;</code></pre>

<div class="poll fragment fade-in-then-out" style="bottom:-260px">

<div class="fragment" data-fragment-index="2"><pre><code class="sql dont_execute_sql" contenteditable>SELECT addieren(5,4);</code></pre></div>

<div class="fragment" data-fragment-index="3"><pre><code class="sql dont_execute_sql" contenteditable>SELECT *, addieren(sterne, 1) FROM bewertungen;</code></pre></div>

<div class="poll fragment fade-in-then-out" style="bottom:-260px" data-fragment-index="1">
<h1>Wie lässt sich diese UDF aufrufen?</h1>
<ul>
<li>EXECUTE addieren(5,4);</li>
Expand All @@ -405,12 +410,6 @@ <h1>Wie lässt sich diese UDF aufrufen?</h1>
<h2>https://fraage.de</h2>
</div>

<pre class="fragment"><code class="sql dont_execute_sql" contenteditable>SELECT addieren(5,4);</code></pre>

<pre class="fragment"><code class="sql dont_execute_sql" contenteditable>SELECT *, addieren(sterne, 1) FROM bewertungen;</code></pre>



<aside class="notes">Funktionen haben beliebig viele Eingabeparameter und liefern genau einen Rückgabewert zurück. Der Datentyp des Rückgabewerts steht oben hinter <code>RETURNS</code>. Mit einem <code>RETURN</code>-Kommando terminiert die Funktion und erzeugt die Rückgabe. Man kann die Funktion genau wie eingebaute SQL-Funktionen (UPPER, MD5, ...) in SELECT-Anfragen mit und ohne FROM-Klausel verwenden, aber auch in INSERT, UPDATE, etc. Die hier dargestellte Funktion addiert zwei Zahlen. Die Eingabeparameternamen kann man wie hier gezeigt einfach weggelassen, wenn man auf sie lediglich mittels <code>$1</code> etc. zugreift.</aside>
</section>

Expand Down Expand Up @@ -478,7 +477,9 @@ <h2>Tabellenfunktionen</h2>
$$ LANGUAGE sql;
</code></pre>

<div class="poll fragment fade-in-then-out" style="bottom:-280px">
<div class="fragment" data-fragment-index="2"><pre><code class="sql dont_execute_sql" contenteditable>SELECT * FROM produkte_von('Calgonte');</code></pre></div>

<div class="poll fragment fade-in-then-out" style="bottom:-280px" data-fragment-index="1">
<h1>Wie lässt sich diese Tabellenfunktion aufrufen?</h1>
<ul>
<li>EXECUTE produkte_von('Calgonte');</li>
Expand All @@ -489,7 +490,7 @@ <h1>Wie lässt sich diese Tabellenfunktion aufrufen?</h1>
<h2>https://fraage.de</h2>
</div>

<pre class="fragment"><code class="sql dont_execute_sql" contenteditable>SELECT * FROM produkte_von('Calgonte');</code></pre>


<aside class="notes">Tabellenfunktionen liefert eine Tabelle zurück mit beliebig vielen Zeilen. Die Spalten und deren Typen werden im <code>CREATE FUNCTION</code>-Kommando im <code>RETURNS TABLE</code>-Teil definiert. Genau wie eine View wird eine Tabellenfunktion in der <code>FROM</code>-Klausel einer SELECT-Anfrage aufgerufen. Eine Tabellenfunktion ist quasi eine View mit Parametern.</aside>
</section>
Expand Down Expand Up @@ -585,11 +586,11 @@ <h3>AFTER INSERT</h3>
<li>oder das Fremdschlüssel-Constraint auf <code>DEFERRED</code> setzen:</li>
</ul>

<pre class="fragment" data-fragment-index="2"><code class="sql dont_execute_sql" contenteditable data-trim>
<div class="fragment" data-fragment-index="2"><pre><code class="sql dont_execute_sql" contenteditable data-trim>
ALTER TABLE webshop.produkte ADD CONSTRAINT
produkte_hersteller_fkey FOREIGN KEY (hersteller)
REFERENCES hersteller(firma) ON UPDATE CASCADE
INITIALLY DEFERRED;</code></pre>
INITIALLY DEFERRED;</code></pre></div>

<aside class="notes">Ändern wir den Trigger auf <code>BEFORE INSERT</code>, wird die Prozedur, die den Hersteller einfügt, ausgeführt, bevor die neue Zeile in die Produkttabelle eingefügt wird. Der Hersteller ist hier der Parent-Record und das Produkt der Child-Record. Der Parent muss vorher existieren, bevor der Child-Record existiert.<br>
Als Alternative kann die Überprüfung des Fremdschlüssel-Constraints auch auf <code>DEFERRED</code> (verzögert) setzen. Der Standard ist <code>IMMEDIATE</code> - eine sofortige Überprüfung. Bei <code>DEFERRED</code> wird das Constraint erst zum Ende der Transaktion überprüft. In unserem Fall führt dies zum Erfolg, da zum Ende der Transaktion der zuvor nicht existierende Hersteller zwischenzeitlich durch den Trigger eingefügt wurde.</aside>
Expand Down Expand Up @@ -674,10 +675,10 @@ <h3>INSTEAD OF-Trigger</h3>
<li>Mittels einer <code>CHECK OPTION</code> kann überprüft werden, dass das Tupel auch das WHERE-Prädikat der View erfüllt.</li>
<li><code>INSTEAD OF</code>-Trigger ermöglichen INSERT/UPDATE/DELETE auf jeder View.</li>
</ul>
<pre class="fragment"><code class="sql dont_execute_sql" contenteditable data-trim>
<div class="fragment"><pre><code class="sql dont_execute_sql" contenteditable data-trim>
CREATE TRIGGER meine_view_trigger INSTEAD OF INSERT ON meine_view
FOR EACH ROW EXECUTE PROCEDURE meine_view_trigger();
</code></pre>
</code></pre></div>

<aside class="notes"><code>INSTEAD OF</code>-Trigger sind nur für Sichten gedacht. Jedes mal, wenn jemand ein INSERT / UPDATE / DELETE auf eine Sicht macht, soll stattdessen die Trigger-Aktion ausgelöst werden.</aside>
</section>
Expand All @@ -690,7 +691,7 @@ <h3>INSTEAD OF-Trigger</h3>
FROM produkte p JOIN hersteller h ON p.hersteller=h.firma;
</code></pre>

<pre class="fragment" style="width: 95%;"><code class="sql dont_execute_sql" contenteditable data-trim>
<div class="fragment"><pre style="width: 95%;"><code class="sql dont_execute_sql" contenteditable data-trim>
CREATE OR REPLACE FUNCTION meine_view_trigger()
RETURNS TRIGGER AS $$
BEGIN
Expand All @@ -700,7 +701,7 @@ <h3>INSTEAD OF-Trigger</h3>
INSERT INTO produkte (produktnr, bezeichnung, preis, hersteller)
VALUES (NEW.produktnr, NEW.bezeichnung, NEW.preis, NEW.hersteller);
RETURN NEW;
END; $$ LANGUAGE plpgsql;</code></pre>
END; $$ LANGUAGE plpgsql;</code></pre></div>

<aside class="notes">Die gezeigte View führt eine Denormalisierung der beiden Tabellen Produkte und Hersteller aus, also einen Join. Der Trigger sorgt dafür, dass ein INSERT in diese View aufgeteilt wird in zwei INSERT-Kommandos. Zunächst wird der Hersteller eingefügt. Falls es ihn schon gibt, wird sein Land angepasst. Im Anschluss erfolgt das Einfügen des Produktes.</aside>
</section>
Expand Down
79 changes: 0 additions & 79 deletions exercises/ex10_.html

This file was deleted.

123 changes: 83 additions & 40 deletions exercises/ex11.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,55 +19,98 @@
<header>
<div>
<div>
<b>Datenbanken - SS 2021</b><br>
Prof. Dr.-Ing. Johannes Schildgen<br>
[email protected]<br>
<b>Übungsblatt 10 vom 29./30.06.2021</b>
<b>Datenbanken - WS 2021/22</b><br>
Prof. Dr.-Ing. Johannes Schildgen<br>
[email protected]<br>
<b>Übungsblatt 11 vom 7./12.01.2022</b>
</div>
<div><img src="../img/oth.png" style="border:0; height:50px"></div>
</div>
<hr>
</header>

<section style="padding-top: 2.5cm">
<h1>Aufgabe 1: User-Defined Functions (10P)</h1>
<p>Abgabe-Deadline: 29.06.2021 14:00 im Moodle</p>
<ol>
<li>Entwickeln Sie in Ihrer PostgreSQL-Datenbank eine UDF namens <code>fakultaet(INT)</code>, die eine Integer-Zahl entgegennimmt und einen Integer ausgibt: die Fakultät der übergebenen Zahl.</li>
<li>Was ist die größte Zahl, deren Fakultät Sie mit Ihrer Funktion berechnen können?</li>
</section>
<h1>Aufgabe 1: Rechtemanagement, Transaktionen (10P)</h1>
<p>Abgabe-Deadline: 07.01.2021 9:00 im GRIPS</p>
<h4>a) (6P)</h4>
<p>Welche der folgenden Aussagen sind wahr? Jede richtige Antwort gibt 1 Punkt, falsche Antworten geben keine Punktabzüge.</p>
<table border="0" style="width: 100%; margin-top: -5mm;">
<tr>
<td style="width:10mm">&nbsp;</td>
<td>&nbsp;</td>
<td style="text-align: center; width:15mm">Richtig</td>
<td style="text-align: center; width:15mm">Falsch</td>
</tr>
<tr>
<td>1.</td><td>Wenn ich GRANT rolle TO benutzer ausführe, hat der angegebene Benutzer alle Berechtigungen der spezifizierten Rolle.</td>
<td style="text-align: center"><i class="far fa-square"></i></td>
<td style="text-align: center"><i class="far fa-square"></i></td>
</tr>
<tr>
<td>2.</td><td>Mit REVOKE ... RESTRICT verbiete ich, ein Recht weiterzugeben.</td>
<td style="text-align: center"><i class="far fa-square"></i></td>
<td style="text-align: center"><i class="far fa-square"></i></td>
</tr>
<tr>
<td>3.</td><td>Wenn eine Transaktion Daten schreibt und sie diese selbst wieder liest, nennt man dies ein Dirty Read.</td>
<td style="text-align: center"><i class="far fa-square"></i></td>
<td style="text-align: center"><i class="far fa-square"></i></td>
</tr>
<tr>
<td>4.</td><td>Es laufen zwei Transaktionen parallel. Eine schreibt in x und die andere liest x gleichzeitig. Hier kann ein Lost Update auftreten.</td>
<td style="text-align: center"><i class="far fa-square"></i></td>
<td style="text-align: center"><i class="far fa-square"></i></td>
</tr>
<tr>
<td>5.</td><td>Das Phantomproblem kann auftreten, wenn zwischen zwei Leseoperationen eine andere Transaktion Datensätze löscht.</td>
<td style="text-align: center"><i class="far fa-square"></i></td>
<td style="text-align: center"><i class="far fa-square"></i></td>
</tr><!--
<tr>
<td>6.</td><td>Die Redo-Info im Transaktionslog wird verwendet, um noch nicht auf die Festplatte geschriebene Aktionen von Gewinner-Transaktionen auszuführen.</td>
<td style="text-align: center"><i class="far fa-square"></i></td>
<td style="text-align: center"><i class="far fa-square"></i></td>
</tr>-->
</table>

<section>
<h1>Aufgabe 2: Stored Procedures</h1>
<p>Entwickeln Sie in Ihrer PostgreSQL-Datenbank eine Prozedur namens <code>kontakte_vorbereiten(anzahl INT)</code>, die eine Tabelle erstellt und diese mit Testdaten füllt.</p>
<ol>
<li>Die Prozedur soll die Tabelle <code>kontakte</code> droppen, falls Sie schon existiert: <code>DROP TABLE IF EXISTS kontakte;</code></li>
<li>Nun soll die Prozedur die <code>kontakte</code>-Tabelle anlegen. Die Spalten sind wie im letzten Übungsblatt <code>name VARCHAR(200) PRIMARY KEY, handynummer VARCHAR(20), gesucht INT NOT NULL DEFAULT 0</code>.</li>
<li>Der Parameterwert, der der Prozedur übergeben wird, bestimmt die Anzahl der Zeilen, die eingefügt werden. Erzeugen Sie entsprechend viele Dummy-Datensätze, z. B. ('Peter1', '0151-1'), ('Peter2', '0151-2'), usw.</li>
<li>Wenn eine negative Zahl übergeben wird, soll die Prozedur eine Exception &quot;Ungültige Anzahl&quot; werfen.</li>
<li>Rufen Sie die Prozedur auf, um hunderttausend Kontakte zu generieren.</li>
</ol>
<p>Hinweis: Die in einer For-Schleife <code>FOR _variablenname IN _von .. _bis LOOP ... END LOOP;</code> verwendeten Variablen müssen Sie in der <code>DECLARE</code>-Section definieren (oder sie sind Parameter).</p>
</section>
<!--
<section>
<h1>Aufgabe 2: Trigger</h1>
<ol>
<li>Erstellen Sie für ein soziales Netzwerk eine Tabelle <code>freundschaften</code> mit den Spalten <code>person1</code> und <code>person2</code>.</li>
<li>Erstellen Sie eine Triggerfunktion und einen Trigger, der bewirkt, dass beim Einfügen einer Freundschaft (A, B) auch eine Freundschaft in die umgekehrte Richtung (B, A) eingefügt wird.</li>
<li>Testen Sie Ihren Trigger.</li>
</ol>
</section>
<h4>b) (3P)</h4>
<p>Zeichnen Sie den Serialisierbarkeitsgraphen für die folgende Historie:</p>
<p style="font-size:larger;">w<sub>1</sub>(x), w<sub>2</sub>(x), r<sub>2</sub>(y), r<sub>1</sub>(y), w<sub>3</sub>(y), c<sub>1</sub>, c<sub>2</sub>, c<sub>3</sub></p>

<section>
<h1>Aufgabe 3: B+-Bäume</h1>
<p>Betrachten Sie folgenden B+-Baum der Klasse (k=1, k*=1):</p>
<img src="img/ex6_tree.png" alt="B+-Baum" style="height:3cm">
<ol>
<li>Lösen Sie mit Stift und Papier:<br>Fügen Sie Leo und anschließend Zoe in den Baum ein. Zeichnen Sie den kompletten Baum, so wie er nach den beiden Einfügungen aussieht.</li>
<li>Lösen Sie mit dem B+-Baum-Simulations-Tool auf <a href="https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html" target="_blank">https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html</a>:<br>Fügen Sie 20 Zahlen so in einen B+-Baum der Klasse (k=2, k*=2, also Max. Degree=5) ein, sodass dieser die Höhe 2 hat.</li>
</ol>
</section>-->
<table border="0" style="width: 100%; margin-top: -5mm;">
<tr>
<td style="width:10mm">&nbsp;</td>
<td>&nbsp;</td>
<td style="text-align: center; width:15mm">Richtig</td>
<td style="text-align: center; width:15mm">Falsch</td>
</tr>
<tr>
<td>7.</td><td>Es gibt einen Zyklus im Serialisierbarkeitsgraphen.</td>
<td style="text-align: center"><i class="far fa-square"></i></td>
<td style="text-align: center"><i class="far fa-square"></i></td>
</tr>
</table>

<h4>c) (2P)</h4>
<p>Skizzieren Sie den Ablauf des SX-Sperrverfahrens für die Historie aus Aufgabenteil b).</p>

<table border="0" style="width: 100%; margin-top: -5mm;">
<tr>
<td style="width:10mm">&nbsp;</td>
<td>&nbsp;</td>
<td style="text-align: center; width:15mm">Richtig</td>
<td style="text-align: center; width:15mm">Falsch</td>
</tr>
<tr>
<td>8.</td><td>Wird bei der Historie aus der vorherigen Frage das SX-Sperrverfahren eingesetzt, muss TA<sub>2</sub> warten, bevor sie in x schreiben darf.</td>
<td style="text-align: center"><i class="far fa-square"></i></td>
<td style="text-align: center"><i class="far fa-square"></i></td>
</tr>
</table>

<p>Ihre Lösungen zu Teil b) und c) (Serialisierbarkeitsgraph und SX-Sperrverfahren) werden in den Zoom-Sessions besprochen.</p>

</section>

<script src="../lib/jquery.js"></script>
<script src="../lib/lodash.js"></script>
Expand Down
Loading

0 comments on commit d730d25

Please sign in to comment.