· 6 years ago · Sep 04, 2019, 09:28 AM
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2<html xmlns="http://www.w3.org/1999/xhtml">
3<head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <meta http-equiv="Content-Style-Type" content="text/css" />
6 <meta name="generator" content="pandoc" />
7 <meta name="author" content="2019-06-23" />
8 <title>Datenbanken</title>
9 <style type="text/css">code{white-space: pre;}</style>
10 <style type="text/css">
11div.sourceCode { overflow-x: auto; }
12table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
13 margin: 0; padding: 0; vertical-align: baseline; border: none; }
14table.sourceCode { width: 100%; line-height: 100%; }
15td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
16td.sourceCode { padding-left: 5px; }
17code > span.kw { color: #0000ff; } /* Keyword */
18code > span.ch { color: #008080; } /* Char */
19code > span.st { color: #008080; } /* String */
20code > span.co { color: #008000; } /* Comment */
21code > span.ot { color: #ff4000; } /* Other */
22code > span.al { color: #ff0000; } /* Alert */
23code > span.er { color: #ff0000; font-weight: bold; } /* Error */
24code > span.wa { color: #008000; font-weight: bold; } /* Warning */
25code > span.cn { } /* Constant */
26code > span.sc { color: #008080; } /* SpecialChar */
27code > span.vs { color: #008080; } /* VerbatimString */
28code > span.ss { color: #008080; } /* SpecialString */
29code > span.im { } /* Import */
30code > span.va { } /* Variable */
31code > span.cf { color: #0000ff; } /* ControlFlow */
32code > span.op { } /* Operator */
33code > span.bu { } /* BuiltIn */
34code > span.ex { } /* Extension */
35code > span.pp { color: #ff4000; } /* Preprocessor */
36code > span.do { color: #008000; } /* Documentation */
37code > span.an { color: #008000; } /* Annotation */
38code > span.cv { color: #008000; } /* CommentVar */
39code > span.at { } /* Attribute */
40code > span.in { color: #008000; } /* Information */
41 </style>
42</head>
43<body>
44<div id="header">
45<h1 class="title">Datenbanken</h1>
46<h2 class="author">2019-06-23</h2>
47</div>
48<div id="TOC">
49<ul>
50<li><a href="#a.-eigenschaften-und-architekturen-von-datenbanksystemen-..."><span class="toc-section-number">1</span> A. Eigenschaften und Architekturen von Datenbanksystemen <a href="#TOC">...</a></a><ul>
51<li><a href="#big-data-cap-theorem-..."><span class="toc-section-number">1.1</span> Big-Data, CAP-Theorem <a href="#TOC">...</a></a></li>
52<li><a href="#acid-vs.-base-..."><span class="toc-section-number">1.2</span> ACID vs. BASE <a href="#TOC">...</a></a></li>
53</ul></li>
54<li><a href="#b.-grundlagen-datenmodelle-..."><span class="toc-section-number">2</span> B. Grundlagen Datenmodelle <a href="#TOC">...</a></a><ul>
55<li><a href="#attributwerte-schlüssel-..."><span class="toc-section-number">2.1</span> Attributwerte, Schlüssel <a href="#TOC">...</a></a></li>
56<li><a href="#datentypen-..."><span class="toc-section-number">2.2</span> Datentypen <a href="#TOC">...</a></a></li>
57<li><a href="#normalformen-..."><span class="toc-section-number">2.3</span> Normalformen <a href="#TOC">...</a></a></li>
58</ul></li>
59<li><a href="#c.-datenmodellierung-systemanalyse-..."><span class="toc-section-number">3</span> C. Datenmodellierung / Systemanalyse <a href="#TOC">...</a></a><ul>
60<li><a href="#assoziationen-..."><span class="toc-section-number">3.1</span> Assoziationen <a href="#TOC">...</a></a></li>
61<li><a href="#vererbung-attribute-..."><span class="toc-section-number">3.2</span> Vererbung, Attribute <a href="#TOC">...</a></a></li>
62</ul></li>
63<li><a href="#d.-datenbankabfrage-sql-..."><span class="toc-section-number">4</span> D. Datenbankabfrage (SQL) <a href="#TOC">...</a></a><ul>
64<li><a href="#joins-..."><span class="toc-section-number">4.1</span> Joins <a href="#TOC">...</a></a></li>
65<li><a href="#index-..."><span class="toc-section-number">4.2</span> Index <a href="#TOC">...</a></a></li>
66<li><a href="#aufgaben-..."><span class="toc-section-number">4.3</span> Aufgaben <a href="#TOC">...</a></a></li>
67</ul></li>
68<li><a href="#e.-datenbankdefinition-ddl-..."><span class="toc-section-number">5</span> E. Datenbankdefinition (DDL) <a href="#TOC">...</a></a><ul>
69<li><a href="#constraints-..."><span class="toc-section-number">5.1</span> Constraints <a href="#TOC">...</a></a></li>
70<li><a href="#views-collections-..."><span class="toc-section-number">5.2</span> Views, Collections <a href="#TOC">...</a></a></li>
71</ul></li>
72<li><a href="#f.-datenbankmanipulation-dml-..."><span class="toc-section-number">6</span> F. Datenbankmanipulation (DML) <a href="#TOC">...</a></a><ul>
73<li><a href="#grundlagen-..."><span class="toc-section-number">6.1</span> Grundlagen <a href="#TOC">...</a></a></li>
74<li><a href="#dml-mongodb-..."><span class="toc-section-number">6.2</span> DML MongoDB <a href="#TOC">...</a></a></li>
75<li><a href="#dml-mongodb2-..."><span class="toc-section-number">6.3</span> DML MongoDB2 <a href="#TOC">...</a></a></li>
76</ul></li>
77<li><a href="#g.-datenbankanwendungen-..."><span class="toc-section-number">7</span> G. Datenbankanwendungen <a href="#TOC">...</a></a><ul>
78<li><a href="#trigger-..."><span class="toc-section-number">7.1</span> Trigger <a href="#TOC">...</a></a></li>
79<li><a href="#skriptsprachen-..."><span class="toc-section-number">7.2</span> Skriptsprachen <a href="#TOC">...</a></a></li>
80</ul></li>
81<li><a href="#h.-administration-von-datenbanksystemen-..."><span class="toc-section-number">8</span> H. Administration von Datenbanksystemen <a href="#TOC">...</a></a><ul>
82<li><a href="#installation-konfiguration-..."><span class="toc-section-number">8.1</span> Installation, Konfiguration <a href="#TOC">...</a></a></li>
83<li><a href="#export-backup-..."><span class="toc-section-number">8.2</span> Export, Backup <a href="#TOC">...</a></a></li>
84</ul></li>
85</ul>
86</div>
87<h1 id="a.-eigenschaften-und-architekturen-von-datenbanksystemen-..."><span class="header-section-number">1</span> A. Eigenschaften und Architekturen von Datenbanksystemen <a href="#TOC">...</a></h1>
88<h2 id="big-data-cap-theorem-..."><span class="header-section-number">1.1</span> Big-Data, CAP-Theorem <a href="#TOC">...</a></h2>
89<p>Ein technischer Berater möchte seinem Kunden die wesentlichen Merkmale von NoSQL-Datenbanken präsentieren.</p>
90<ol class="example" style="list-style-type: decimal">
91<li>Nennen und beschreiben Sie die grundlegenden technischen Herausforderungen im Big-Data-Umfeld.</li>
92</ol>
93<hr />
94<ul>
95<li>Volume</li>
96<li>Velocity</li>
97<li>Variety</li>
98</ul>
99<p>Bei <em>Volume</em> geht es um die schiere Menge an Daten, die pro Zeiteinheit gespeichert werden muss.</p>
100<p><em>Velocity</em> adressiert die Geschwindigkeit, mit der die Daten gespeichert, aber auch verarbeitet werden.</p>
101<p>Der Aspekt <em>Variety</em> bezieht sich auf die unterschiedlichen Grade von Strukturiertheit der Daten, das reicht von völlig unstrukturiert über semistrukturiert bis hin zu stark strukturiert.</p>
102<p>Daneben machen zwei weitere Dinge den Begriff Big Data aus:</p>
103<ul>
104<li>Kostenersparnis durch elastische Skalierung und die</li>
105<li>Gewinnung neuer Informationen aus den Daten.</li>
106</ul>
107<hr />
108<hr />
109<ol start="2" class="example" style="list-style-type: decimal">
110<li>Begründen Sie den Einsatz von NoSQL-Datenbanken.</li>
111</ol>
112<hr />
113<ul>
114<li>Der Begriff NoSQL leitet sich ab von <em>not only SQL</em>, wobei SQL als Synonym für relationale Datenbankensysteme verwendet wird.</li>
115<li>Die Grundidee ist die, dass man sich beim Umsetzen seiner konkreten Anforderungen (ob nun Big Data oder nicht) nicht im Vorhinein auf relationale Datenbanksysteme (RDBMS) beschränkt.</li>
116<li>Entstanden sind die NoSQL-Datenbanken in der <strong>Web-2.0-Welt</strong>. Soziale Netzwerke wie Facebook, Twitter und Co. haben mit vielen Millionen, über den ganzen Globus verteilten Benutzern ganz andere Anforderungen an die Datenhaltung als das Bestandsführungssystem eines Versicherungsunternehmens. Es müssen sehr viele Daten sehr schnell gespeichert und abgerufen können. Dabei stoßen relationale Datenbanksysteme durchaus an ihre Grenzen.</li>
117</ul>
118<hr />
119<hr />
120<ol start="3" class="example" style="list-style-type: decimal">
121<li>Nennen und beschreiben Sie die wichtigsten Kategorien von NoSQL-Datenbanken.</li>
122</ol>
123<hr />
124<ul>
125<li><em>Key-Value</em>-Datenbanken verwalten Tupel bestehend aus einem Schlüssel und einem Wert. Abfragen sind nur über den einen Schlüssel möglich. Der Wert des Datensatzes ist in der Regel ein Byte-Array, ist also im Sinne des Variety-Aspekts völlig unstrukturiert.</li>
126<li><em>Spaltenorientierte</em> Datenbanken, im Englischen <em>Wide Column Stores</em>, verwenden Tabellen, bei denen ein Datensatz allerdings eine dynamische Anzahl an Spalten haben kann. Indizes sind frei definierbar und ermöglichen die Abfrage über beliebige Spalten.</li>
127<li><em>Graphen</em>-Datenbanken spezialisieren sich auf die Verwaltung von Knoten und Kanten zwischen diesen Knoten.</li>
128<li><em>Dokumentenorientierte</em> Datenbanken</li>
129</ul>
130<dl>
131<dt>.</dt>
132<dd><img src="/home/user/acha/www-img/mongodb/f01-01.jpg" />
133</dd>
134</dl>
135<hr />
136<hr />
137<ol start="4" class="example" style="list-style-type: decimal">
138<li>Nennen und beschreiben Sie die wesentlichsten Eigenschaften von MongoDB.</li>
139</ol>
140<hr />
141<ul>
142<li>MongoDB gehört zur Kategorie der sogenannten dokumentenorientierten Datenbanken.</li>
143<li>Der Begriff <em>Mongo</em> leitet sich vom Englischen <em>hu<strong>mongo</strong>us</em> ab, was so viel wie <em>gigantisch</em> oder <em>wahnsinnig groß</em> bedeutet, was dann zu einem versteckten Hinweis auf den <em>Volume</em>-Aspekt von Big Data interpretiert werden kann.</li>
144<li>MongoDB ist Open Source (Gnu AGPL), es gibt allerdings auch kommerziellen Support von der Firma <em>MongoDB Inc</em>.</li>
145<li>Auch für Volume und Velocity bietet MongoDB Lösungen an: Den Big-Data-Aspekten <em>Volume</em> und <em>Velocity</em> ist in der Regel nur mit dem Einsatz von verteilten Systemen zu begegnen, in denen die Last und die Daten auf viele einzelne Rechnerknoten verteilt werden.</li>
146</ul>
147<hr />
148<hr />
149<ol start="5" class="example" style="list-style-type: decimal">
150<li>Beschreiben Sie das CAP-Theorem.</li>
151</ol>
152<hr />
153<p>Bei der Implementierung eines verteilten (Datenbank-)Systems können nicht alle Anforderungen an Konsistenz, Verfügbarkeit und Toleranz gegenüber Ausfällen gleichzeitig in vollem Maße erreichen kann.</p>
154<p>Das <em>CAP-Theorem</em> besagt, dass in verteilten Systemen maximal zwei der drei folgenden Eigenschaften gleichzeitig gelten können:</p>
155<ul>
156<li><p>Consistency (C):</p>
157<p>Alle Knoten haben jederzeit den gleichen Datenbestand.</p></li>
158<li><p>Availability (A):</p>
159<p>Das System steht für Lese- und Schreibzugriffe zur Verfügung.</p></li>
160<li><p>Partition Tolerance (P):</p>
161<p>Toleranz gegenüber dem Ausfall einzelner Knoten und/oder Netzwerkstrecken.</p></li>
162</ul>
163<p>Die Eigenschaften sind dabei als graduelle Größen zu verstehen, d. h., sie können irgendwo zwischen gar nicht und voll erfüllt liegen.</p>
164<hr />
165<hr />
166<ol start="6" class="example" style="list-style-type: decimal">
167<li><p>Erörtern Sie das CAP-Theorem mit einem System, das aus zwei Knoten besteht.</p>
168<p>Das Netzwerk zwischen diesen Knoten soll gestört sein, sodass eine Partition des Systems in zwei Teile vorliegt, die sich gegenseitig nicht mehr erreichen können.</p></li>
169</ol>
170<dl>
171<dt>.</dt>
172<dd><img src="/home/user/my/acha/www-img/mongodb/f01-02.jpg" />
173</dd>
174</dl>
175<!--  -->
176<hr />
177<ol style="list-style-type: lower-alpha">
178<li>Erlaubt man nun einem der Knoten, seinen Zustand zu ändern (also im Falle eines Datenbanksystems schreibende Operationen auszuführen), wird das Gesamtsystem inkonsistent, man gibt also <em>C</em> auf.</li>
179<li>Will man die Konsistenz erhalten, muss der Knoten, dessen Zustand sich nicht ändert, sich als nicht verfügbar »abmelden« (da er sonst gegenüber den Clients einen nicht aktuellen Datenbestand ausliefern würde), womit man die Verfügbarkeit (<em>A</em>) des Systems auf nur noch einen Knoten reduziert.</li>
180<li>Nur wenn alle Knoten stets miteinander kommunizieren können, kann man dauerhaft <em>C</em> und <em>A</em> aufrecht erhalten, was dann offenbar im Widerspruch zu <em>P</em> steht.</li>
181</ol>
182<hr />
183<hr />
184<ol start="7" class="example" style="list-style-type: decimal">
185<li>Vergleichen Sie relationale Datenbanksysteme mit NoSQL-Datenbanken bezüglich des CAP-Theorems.</li>
186</ol>
187<hr />
188<p>Relationale Datenbanksysteme fallen in der Regel in die CA-Kategorie, da sie großen Wert auf die Konsistenz legen und auch hohe Verfügbarkeiten garantieren. Bei Systemen, die nur auf einem Knoten laufen, kann die Ausfallsicherheit durch den Kauf sehr teurer Hardware ebenfalls nah an die 100% gebracht werden. Fällt der eine Knoten aus, ist das System aber nicht mehr verfügbar. Bei Datenbank-Clustern verringert sich die Verfügbarkeit, da die Transaktionen zur Sicherstellung der Konsistenz auf mehreren Knoten eine längere Laufzeit haben.</p>
189<p>Bei vielen NoSQL-Datenbanken kann man aufgrund der hohen Verteilung nicht auf die Partition Tolerance (<em>P</em>) verzichten. Da die Verfügbarkeit (<em>A</em>) ebenfalls einen sehr hohen Stellenwert einnimmt (da man grundsätzlich alle Anfragen an das System beantworten können möchte), bleibt nur der Ausweg, an der Konsistenz (<em>C</em>) zu sparen.</p>
190<h2 id="acid-vs.-base-..."><span class="header-section-number">1.2</span> ACID vs. BASE <a href="#TOC">...</a></h2>
191<p>Ein technischer Berater möchte seinem Kunden die Zuverlässigkeit von relationalen und NoSQL-Datenbanken erläutern.</p>
192<ol start="8" class="example" style="list-style-type: decimal">
193<li>Erklären Sie den Begriff "Transaktion".</li>
194</ol>
195<hr />
196<ul>
197<li>Eine Transaktion ist also eine Folge von Operationen, die atomar, konsistent, isoliert und dauerhaft ist.</li>
198<li>Diese Folge von Elementaroperationen wird entweder als Ganzes abgeschlossen oder in ihrer Gesamtheit abgebrochen und zurückgesetzt.</li>
199<li>Sie führt die Datenbank von einem konsistenten Zustand in einen anderem konsistenten Zustand über.</li>
200</ul>
201<hr />
202<hr />
203<ol start="9" class="example" style="list-style-type: decimal">
204<li>Nennen und beschreiben Sie die SQL-Befehle zur Transaktionskontrolle.</li>
205</ol>
206<hr />
207<p><strong>Beispiel</strong></p>
208<pre><code> BEGIN;
209 INSERT INTO dept VALUES (10, "ACCOUNTING", "NEW YORK");
210 INSERT INTO emp VALUES (7782, "CLARK", "MANAGER", 7839, "1981-06-09", "2450.00", NULL, 10);
211 INSERT INTO emp VALUES (7934, "MILLER", "CLERK", 7782, "1982-01-23", "1300.00", NULL, 10);
212 COMMIT;</code></pre>
213<p><strong><code>BEGIN</code></strong></p>
214<p>Legt den Beginn der Transaktion fest. Alle folgenden Befehle werden zu einer Transaktion gebündelt.</p>
215<p><strong><code>COMMIT</code></strong></p>
216<p>Änderungen permanent machen. Bis zur Eingabe von COMMIT können Änderungen mit ROLLBACK annulliert werden.</p>
217<p><strong><code>ROLLBACK</code></strong></p>
218<p>Macht Änderungen (INSERT, UPDATE) rückgängig und zwar bis zu dem Punkt an dem letztmalig COMMIT eingegeben wurde.</p>
219<hr />
220<hr />
221<ol start="10" class="example" style="list-style-type: decimal">
222<li>Erklären Sie das Zweiphasen-Commit-Protokoll.</li>
223</ol>
224<hr />
225<p>Das Zweiphasen-Commit-Protokoll bestimmt die Art der abschließenden Synchronisation zwischen Subtransaktionen in einem verteilten Datenbankmanagementsystem.</p>
226<hr />
227<hr />
228<ol start="11" class="example" style="list-style-type: decimal">
229<li>Nennen und beschreiben Sie die Bedingungen des ACID-Prinzips.</li>
230</ol>
231<hr />
232<ul>
233<li>Atomarität(Atomicity): Eine Transaktion wird entweder vollständig ausgeführt oder sie hinterläßt keinerlei Wirkung.</li>
234<li>Konsistenz(Consistency): Eine Transaktion führt einen konsistenten Datenbestand wieder in einen solchen über.</li>
235<li>Isolation(Isolation): Die Zwischenergebnisse einer Transaktion sind für andere Transaktionen nicht sichtbar.</li>
236<li>Dauerhaftigkeit(Durability): Die Änderungen einer beendeten und bestätigten Transaktion können weder verloren gehen noch rückgängig gemacht werden.</li>
237</ul>
238<hr />
239<hr />
240<ol start="12" class="example" style="list-style-type: decimal">
241<li>Erörtern Sie Motivation und Konsequenzen des ACID-Prinzips.</li>
242</ol>
243<hr />
244<ul>
245<li>Um eine Datenbank in einem konsistenten Zustand zu halten, ist es nötig, dass Änderungen, die ein Anwender an Datensätzen vorgenommen hat, von einem anderen <strong>nicht überschrieben</strong> werden können und somit relevante Informationen verloren gehen.</li>
246<li>Mit Hilfe von <strong>Transaktionen</strong> können also mehrere Anwender gleichzeitig mit der Datenbank arbeiten, ohne dass es zu Problemen aufgrund von Inkonsistenzen kommt.</li>
247<li>Durch die <strong>Nebenläufigkeit</strong>, also die Koexistenz mehrerer konkurrierender Transaktionen, ist das ACID-Prinzip allerdings gefährdet.</li>
248<li>Darum benötigen Transaktionssysteme
249<ul>
250<li>Maßnahmen zur <strong>Koordination von Transaktionen</strong> sowie zur</li>
251<li>Erhaltung und <strong>Wiederherstellung der Daten</strong> und ihrer Konsistenz nach Fehlern, verursacht beispielsweise durch Systemausfälle.</li>
252</ul></li>
253</ul>
254<hr />
255<hr />
256<ol start="13" class="example" style="list-style-type: decimal">
257<li>Erläutern Sie das BASE-Prinzip.</li>
258</ol>
259<hr />
260<ul>
261<li>NoSQL-Datenbanken können eine Konsistenz im Sinne des ACID-Prinzips oft nicht garantieren, gewährleisten dann aber einen anderen Grad an Konsistenz.</li>
262<li>Hier kommt der Begriff BASE ins Spiel:
263<ul>
264<li><em>B</em>asically <em>A</em>vailable</li>
265<li><em>S</em>oft State</li>
266<li><em>E</em>ventual Consistency</li>
267</ul></li>
268<li>Dieses Akronym will den Gegensatz zu ACID (im Englischen Säure) und BASE (Lauge) aus der Chemie aufgreifen.</li>
269<li>Die beiden Begriffe <em>Basically Available</em> und <em>Soft State</em> sind nicht präzise definiert, greifen aber die Verfügbarkeit (A) des CAP-Theorems auf.</li>
270<li>Unter <em>Eventual Consistency</em> wird relativ klar das C des CAP-Theorems adressiert, und zwar in dem Sinne, dass das verteilte System (nach einer möglichst kurzen Zeitspanne der Inkonsistenz) <em>letztendlich</em> wieder in einem konsistenten Zustand ist.</li>
271</ul>
272<hr />
273<hr />
274<ol start="14" class="example" style="list-style-type: decimal">
275<li>Nennen Sie ein Beispiel für die <em>Eventual Consistency</em> des BASE-Prinzips.</li>
276</ol>
277<hr />
278<p>Ein Beispiel mit zwei Knoten:</p>
279<ul>
280<li>Schreibzugriffe sind nur an einem der Knoten, den wir Master nennen, erlaubt.</li>
281<li>Der Master repliziert den Datenbestand in regelmäßigen Abständen an den anderen Knoten, den wir Slave nennen.</li>
282<li>Lesezugriffe sind an beiden Knoten erlaubt.</li>
283<li>Nach einem Schreibvorgang auf dem Master sehen Clients, die vom Slave lesen, die neuen oder geänderten Daten nicht sofort.</li>
284<li>Erst nach Abschluss der Replikation, die ggf. asynchron arbeitet, ist der Slave wieder auf dem aktuellen Stand.</li>
285</ul>
286<hr />
287<hr />
288<ol start="15" class="example" style="list-style-type: decimal">
289<li>Beschreiben Sie Transaktionen in MongoDB.</li>
290</ol>
291<hr />
292<ul>
293<li>Mit MongoDB können Sie keine Transaktionen fahren, die mehr als ein Dokument umfassen.</li>
294<li>Selbst bei Operationen auf nur einem Dokument ist kein explizites Rollback möglich.</li>
295<li>Immerhin sind Änderungen an einem Dokument aber atomar im Sinne des ACID-Prinzips. Da Sie ganze Objektnetze in einem Dokument unterbringen können, sind dokumentenübergreifende Transaktionen oft auch gar nicht notwendig.</li>
296</ul>
297<h1 id="b.-grundlagen-datenmodelle-..."><span class="header-section-number">2</span> B. Grundlagen Datenmodelle <a href="#TOC">...</a></h1>
298<h2 id="attributwerte-schlüssel-..."><span class="header-section-number">2.1</span> Attributwerte, Schlüssel <a href="#TOC">...</a></h2>
299<p>Wir betrachten eine Bank.</p>
300<blockquote>
301<ul>
302<li>Hans Meyer eröffnet am 4.7.1993 ein Geschäftskonto mit der Kontonummer 4711.<br />
303Er wird dadurch zum Kunden der Bank.<br />
304</li>
305<li>Zwei Monate später eröffnet er bei der gleichen Bank noch ein privates Konto, das die Kontonummer 1234 erhält.<br />
306</li>
307<li>Jedes Konto lautet nur auf den Namen Hans Meyer.</li>
308</ul>
309</blockquote>
310<ol start="16" class="example" style="list-style-type: decimal">
311<li>Modellieren Sie diesen Sachverhalt in einem Objektdiagramm.</li>
312</ol>
313<hr />
314<dl>
315<dt>.</dt>
316<dd><img src="/home/user/acha/www-img/db/kunde-objektdia.jpg" />
317</dd>
318</dl>
319<ul>
320<li>Bei Objektdiagrammen gehört der Klassennamen unterstrichen.</li>
321<li>Die Verbindungen zwischen den Objekten werden auch als Links bezeichnet.</li>
322<li>Es müssen nicht alle Attribute der Klasse angegeben werden.</li>
323</ul>
324<hr />
325<hr />
326<ol start="17" class="example" style="list-style-type: decimal">
327<li>Modellieren Sie diesen Sachverhalt in einem Klassendiagramm.</li>
328</ol>
329<hr />
330<dl>
331<dt>.</dt>
332<dd><img src="/home/user/acha/www-img/db/kunde-klassendia.jpg" />
333</dd>
334</dl>
335<hr />
336<hr />
337<ol start="18" class="example" style="list-style-type: decimal">
338<li>Beschreiben Sie die Darstellung von Klassen mit ihren Rubriken in UML.</li>
339</ol>
340<hr />
341<ul>
342<li>Klassen werden durch Rechtecke dargestellt, die entweder nur
343<ul>
344<li>den Namen der Klasse (fett gedruckt) tragen oder zusätzlich auch</li>
345<li>Attribute und</li>
346<li>Methoden spezifiziert haben.</li>
347</ul></li>
348<li>Dabei werden diese drei Rubriken (engl. compartment) – Klassenname, Attribute, Methoden – jeweils durch eine horizontale Linie getrennt.</li>
349<li>Wenn die Klasse keine Methoden besitzt, kann die unterste horizontale Linie entfallen.</li>
350</ul>
351<hr />
352<hr />
353<ol start="19" class="example" style="list-style-type: decimal">
354<li>Beschreiben Sie die wesentlichsten Merkmale von UML.</li>
355</ol>
356<hr />
357<ul>
358<li>UML ist die Abkürzung für Unified Modeling Language</li>
359<li>UML ist der bislang erfolgreichste Versuch, eine allgemeine Norm für technische Zeichnungen in der Informatik zu schaffen.</li>
360<li>UML hat verschiedene Diagrammtypen wie
361<ul>
362<li>Klassendiagramm</li>
363<li>Objektdiagramm</li>
364<li>Anwendungsfalldiagramm (Use-Casediagramm)</li>
365</ul></li>
366<li>Mit den UML-Diagrammen kann man Strukturen und Abläufe in objektorientierten Programmsystemen darstellen.</li>
367</ul>
368<hr />
369<hr />
370<ol start="20" class="example" style="list-style-type: decimal">
371<li><p>Vergleichen Sie die Darstellung von Attributen in Klassen- und Objekdiagrammen.</p></li>
372<li><p>Erklären Sie die Begriffe "Attribut", "optionales Attribut" und "Attributwert".</p></li>
373</ol>
374<hr />
375<hr />
376<p>Die <strong>Attribute</strong> beschreiben die Daten, die von den Objekten einer Klasse angenommen werden können. Jedes Attribut ist von einem bestimmten Typ. Alle Objekte einer Klasse besitzen dieselben Attribute, jedoch unterschiedliche <strong>Attributwerte</strong>.</p>
377<p>Während die Klasse festlegt, welche Attribute ihre Objekte besitzen, enthalten die Objekte die Attributwerte.</p>
378<p>Das Feld für den Attributwert darf leer sein. Wir sprechen von einem <strong>optionalen Attribut</strong>. Das bedeutet, daß dieses Attribut nicht bei der Erzeugung des Objekts, sondern zu irgendeinem späteren Zeitpunkt – evtl. auch nie – einen definierten Wert erhält.</p>
379<p>In Objektdiagrammen werden die Attribute mit den Attributwerten dargestellt, in Klassendiagrammen werden nur die Attribute dargestellt.</p>
380<hr />
381<p>Ein Kleinunternehmen hat sich dazu entschieden, ihre Angestellten- und Filialdaten in einer relationalen Datenbank zu verwalten. Dadurch kann das Unternehmen besonders einfach den Datenbestand auswerten.</p>
382<pre><code> |EMPNO| ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
383 | 7782| CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
384 | 7839| KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
385
386 |DEPTNO| DNAME | LOC |
387 | 10| ACCOUNTING| NEW YORK |</code></pre>
388<ol start="22" class="example" style="list-style-type: decimal">
389<li>Ermitteln Sie den Primär-, Sekundär- und Fremdschlüssel.</li>
390</ol>
391<hr />
392<p><strong>emp</strong></p>
393<ul>
394<li>Primärschlüssel: empno</li>
395<li>Fremdschlüssel: mgr, deptno</li>
396</ul>
397<p><strong>dept</strong></p>
398<ul>
399<li>Primärschlüssel: deptno</li>
400<li>Sekundärschlüssel: dname</li>
401</ul>
402<hr />
403<hr />
404<ol start="23" class="example" style="list-style-type: decimal">
405<li>Beschreiben Sie die Begriffe Schlüssel, Primär-, Sekundär- und Fremdschlüssel.</li>
406</ol>
407<hr />
408<ul>
409<li>Ein <strong>Schlüssel</strong> (=key, Schlüsselkandidat) ist eine Menge von Attributen, die ein Objekt eindeutig identifizieren.</li>
410<li>Ein Objekt kann mehrere Schlüssel haben. Genau einen dieser Schlüssel wählt besonders aus. Man nennt ihn <strong>Primärschlüssel</strong> (=primary key).</li>
411<li>Alle anderen Schlüssel sind <strong>Sekundärschlüssel</strong> (= secondary key).</li>
412<li>Ein <strong>Fremdschlüssel</strong> ist ein Attribut oder eine Attributkombination, das/die in einer anderen Relation Primärschlüssel ist.</li>
413</ul>
414<hr />
415<hr />
416<ol start="24" class="example" style="list-style-type: decimal">
417<li>Erklären Sie den Zusammenhang zwischen dem Uniqueness-Constraint und Schlüsseln.</li>
418</ol>
419<hr />
420<ul>
421<li>Der <strong>Uniqueness-Constraint</strong> (=Eindeutigkeitseinschränkung) verhindert, dass mehrere Datensätze denselben Attributwert (diesselben Attributwerte) haben.</li>
422<li>Attribute sind entweder <strong>optional</strong> oder <strong>verpflichtend(=mandatory)</strong>: Optionale Attribute können auch keinen Wert annehmen. Das heißt, sie können den Wert NULL enthalten.</li>
423<li>Attribute, die verpflichtend und unique sind, sind <strong>Schlüssel</strong>.</li>
424</ul>
425<h2 id="datentypen-..."><span class="header-section-number">2.2</span> Datentypen <a href="#TOC">...</a></h2>
426<p>Ein Kleinunternehmen hat sich dazu entschieden, ihre Angestellten- und Filialdaten in einer relationalen Datenbank zu verwalten. Dadurch kann das Unternehmen besonders einfach den Datenbestand auswerten.</p>
427<pre><code> |EMPNO| ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
428 | 7782| CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
429 | 7839| KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
430
431 |DEPTNO| DNAME | LOC |
432 | 10| ACCOUNTING| NEW YORK |</code></pre>
433<hr />
434<ol start="25" class="example" style="list-style-type: decimal">
435<li>Modellieren Sie diesen Sachverhalt in einem Objektdiagramm.</li>
436</ol>
437<hr />
438<dl>
439<dt>.</dt>
440<dd><img src="/home/user/acha/www-img/db/uml-object.jpg" />
441</dd>
442</dl>
443<hr />
444<hr />
445<ol start="26" class="example" style="list-style-type: decimal">
446<li>Beschreiben Sie die Darstellung von Datentypen in UML.</li>
447</ol>
448<hr />
449<p>In der UML ist nicht festgelegt, wie der <strong>Typ</strong> eines Attributs definiert wird. Um ein standardisiertes OOA-Modell zu erstellen, verwenden wir in der Systemanalyse folgende Typen:</p>
450<ul>
451<li>Standardtypen,</li>
452<li>Aufzählungstypen,</li>
453<li>(elementare) Klassen,</li>
454<li>list of Typ, wobei ein beliebiger Typ erlaubt ist.</li>
455</ul>
456<p>Mit anderen Worten:</p>
457<p><code>Typ = [Standardtyp | Aufzählungstyp | Klasse | list of Typ]</code></p>
458<p>In der Analyse dient die Typdefinition dem Zweck, das Attribut aus fachlicher Sicht möglichst präzise zu beschreiben. In Entwurf und Implementierung wird dann in Abhängigkeit von der gewählten Programmiersprache der Typ neu definiert.</p>
459<hr />
460<hr />
461<ol start="27" class="example" style="list-style-type: decimal">
462<li>Beschreiben Sie die Darstellung der Standardtypen in UML.</li>
463</ol>
464<hr />
465<p>Als <strong>Standardtypen</strong> stehen dem Systemanalytiker zur Verfügung:</p>
466<ul>
467<li><code>String</code> = String (Länge)</li>
468<li><code>Int</code>: ganze Zahl von 32 Bit</li>
469<li><code>UInt</code>: positive ganze Zahl 32 Bit</li>
470<li><code>Float</code>: Gleitkommazahl 32 Bit</li>
471<li><code>Double</code>: Gleitkommazahl 64 Bit</li>
472<li><code>Fixed (Vorkommastellen, Nachkommastellen)</code>: Festkommazahl</li>
473<li><code>Boolean</code></li>
474<li><code>Date</code></li>
475<li><code>Time</code></li>
476</ul>
477<hr />
478<hr />
479<ol start="28" class="example" style="list-style-type: decimal">
480<li>Beschreiben Sie die Darstellung der Aufzähltypen in UML.</li>
481</ol>
482<hr />
483<p>Für einen <strong>Aufzählungstyp</strong> sind anzugeben:</p>
484<ul>
485<li><p>Bereich</p>
486<p>Hier werden alle Werte aufgezählt, die das Attribut annehmen kann.</p></li>
487<li><p>Selektionsart</p>
488<p>Es soll möglich sein, ein oder mehrere Werte zu selektieren, wobei individuell festgelegt wird, wie viele das sein können. Daher sind Angaben zur minimalen und zur maximalen Anzahl der zu selektierenden Elemente notwendig. Als Voreinstellung wird angenommen, daß genau ein Wert selektiert wird.</p></li>
489<li><p>Die Werteliste kann erweiterbar sein.</p>
490<p>In diesem Fall kann der spätere Benutzer neue Werte eingeben, die in die Liste permanent aufgenommen werden. Wir gehen davon aus, daß diese Erweiterbarkeit standardmäßig gilt.</p></li>
491</ul>
492<p>Für die Definition von Aufzählungstypen verwenden wir folgende Notation:</p>
493<p><code>{values: W1, W2, W3,</code> ... Wertebereich.<br />
494<code>select: 1..n,</code> ... Selektionsart mit minimaler und maximaler Anzahl.<br />
495<code>noAdd}</code> ... Festlegung, daß der Wertebereich nicht erweiterbar ist.</p>
496<p>Wenn bei der Selektionsart und der Erweiterbarkeit die Voreinstellungen gelten, dann reicht die Angabe der Werte, d.h. <code>{values: W1, W2, W3}</code>.</p>
497<p><strong>Alternative</strong></p>
498<p>Alternativ kann ein Aufzählungstyp auch mit Hilfe des Klassenkonstrukts beschrieben werden. Der Typ wird als Klassenname eingetragen und mit dem Stereotypen <strong>«enumeration»</strong> gekennzeichnet. Die Werte des Aufzählungstyps werden als Attribute eingetragen.</p>
499<hr />
500<hr />
501<ol start="29" class="example" style="list-style-type: decimal">
502<li>Beschreiben Sie die Darstellung von Klassen als Typen in UML.</li>
503</ol>
504<hr />
505<dl>
506<dt>.</dt>
507<dd><img src="/home/user/acha/www-img/uml/elementare-klasse.png" />
508</dd>
509</dl>
510<p>Der Typ eines Attributs kann selbst wieder durch eine Klasse beschrieben werden. Wir bezeichnen diese Klassen als <strong>elementare Klassen</strong> (support classes) und tragen sie im Gegensatz zu den (Architektur-)Klassen nicht in das Klassendiagramm des Gesamtmodells ein. Sie werden in der Regel – in Abhängigkeit von der jeweiligen Anwendung – einmal definiert und bei jedem Projekt wiederverwendet. Um Konflikte mit Attributnamen zu vermeiden, kann man an den Namen ein "T" anhängen.</p>
511<h2 id="normalformen-..."><span class="header-section-number">2.3</span> Normalformen <a href="#TOC">...</a></h2>
512<ol start="30" class="example" style="list-style-type: decimal">
513<li>In welcher Normalform befindet sich folgendes Relationen-System?</li>
514<li>Entwerfen Sie das Relationen-System in einer höheren Normalform!</li>
515</ol>
516<pre><code>Vorgang* Datum Benutzer Straße PLZ Ort
517--------- ------- -------- ---------------- ----- -------
5181352 22.1.97 ST442 Schellingstr. 3 80799 München
5191353 22.1.97 DOZ387 Oettingenstr. 67 80538 München
520
521Signatur* Titel
522---------- ---------------------
523MAI I/1 Logic Programming
524CLO I/2 Programming in Prolog
525ZEH I/1 Informationssysteme
526
527Vorgang* Signatur*
528--------- ----------
5291352 MAI I/1
5301352 CLO I/2
5311353 ZEH I/1</code></pre>
532<p>Die Primärschlüssel sind mit "*" gekennzeichnet.</p>
533<hr />
534<p>Das Relationensystem befindet sich in der zweiten Normalform.</p>
535<p>Begründung:</p>
536<ul>
537<li>Die Straße ist von dem Nichtschlüsselattribut "Benutzer" abhängig.</li>
538<li>Kein Attribut ist von einem Teilschlüsselattribut abhängig.</li>
539</ul>
540<hr />
541<p><strong>dritte Normalform</strong></p>
542<p><em>Benutzer</em></p>
543<table>
544<thead>
545<tr class="header">
546<th>Benutzer</th>
547<th align="left">Straße</th>
548<th align="left">PLZ</th>
549</tr>
550</thead>
551<tbody>
552<tr class="odd">
553<td>ST442</td>
554<td align="left">Schellingstr. 3</td>
555<td align="left">80799</td>
556</tr>
557<tr class="even">
558<td>DOZ387</td>
559<td align="left">Oettingenstr. 67</td>
560<td align="left">80538</td>
561</tr>
562</tbody>
563</table>
564<p><em>PLZVerzeichnis</em></p>
565<table>
566<thead>
567<tr class="header">
568<th align="left">PLZ</th>
569<th align="left">Ort</th>
570</tr>
571</thead>
572<tbody>
573<tr class="odd">
574<td align="left">80799</td>
575<td align="left">München</td>
576</tr>
577<tr class="even">
578<td align="left">80538</td>
579<td align="left">München</td>
580</tr>
581</tbody>
582</table>
583<p><em>Katalog</em></p>
584<table>
585<thead>
586<tr class="header">
587<th>Signatur</th>
588<th align="left">Titel</th>
589</tr>
590</thead>
591<tbody>
592<tr class="odd">
593<td>MAI I/1</td>
594<td align="left">Logic Programming</td>
595</tr>
596<tr class="even">
597<td>CLO I/2</td>
598<td align="left">Programming in Prolog</td>
599</tr>
600<tr class="odd">
601<td>ZEH I/1</td>
602<td align="left">Informationssysteme</td>
603</tr>
604</tbody>
605</table>
606<p><em>Ausleihvorgang</em></p>
607<table>
608<thead>
609<tr class="header">
610<th>Vorgang</th>
611<th align="left">Datum</th>
612<th>Benutzer</th>
613</tr>
614</thead>
615<tbody>
616<tr class="odd">
617<td>1352</td>
618<td align="left">22.1.97</td>
619<td>ST442</td>
620</tr>
621<tr class="even">
622<td>1353</td>
623<td align="left">22.1.97</td>
624<td>DOZ387</td>
625</tr>
626</tbody>
627</table>
628<p><em>Buchverleih</em></p>
629<table>
630<thead>
631<tr class="header">
632<th>Vorgang</th>
633<th>Signatur</th>
634</tr>
635</thead>
636<tbody>
637<tr class="odd">
638<td>1352</td>
639<td>MAI I/1</td>
640</tr>
641<tr class="even">
642<td>1352</td>
643<td>CLO I/2</td>
644</tr>
645<tr class="odd">
646<td>1353</td>
647<td>ZEH I/1</td>
648</tr>
649</tbody>
650</table>
651<hr />
652<hr />
653<ol start="32" class="example" style="list-style-type: decimal">
654<li>Prüfen Sie ob es eine funktionale Abhängigkeit "Benutzer -> Vorgang" gibt.</li>
655</ol>
656<hr />
657<p>Es scheint auch eine funktionale Abhängigkeit "Benutzer -> Vorgang" zu bestehen. Diese gilt aber in der wirklichen Welt nicht, denn ein Benutzer kann unter unterschiedlichen Vorgangsnummern Bücher ausgeliehen haben, auch wenn dies in der aktuellen Datenbank nicht der Fall ist.</p>
658<!--
659
660 **Beispiel**
661
662In der realen Welt gilt die folgende funktionale Abhängigkeit in der Regel
663nicht:
664
665Straße -> Ort
666
667In einer Relation mit den folgenden Einträgen aber scheint sie zu gelten:
668
669Straße Ort
670-------------- --------
671Leopoldstraße München
672Kurfürstendamm Berlin
673Gänsemarkt Hamburg
674
675-->
676<hr />
677<hr />
678<ol start="33" class="example" style="list-style-type: decimal">
679<li>Erläutern Sie die Begriffe Schlüssel, funktionale Abhängigkeit und transitive Abhängigkeit.</li>
680</ol>
681<hr />
682<p>Innerhalb des relationalen Modells spielt die Abhängigkeit von Attributen bzw. Attributskombinationen eine bedeutende Rolle.</p>
683<p>Für eine Relation R mit Attributen X und Y heißt Y <strong>funktional abhängig</strong> von X, genau dann, wenn jeder X-Wert in R genau einen Y-Wert in R bestimmt.</p>
684<p>So könnte man sich etwa eine Kundendatenbank vorstellen, in der die Anschrift und die Telefonnummer eines Kunden eindeutig durch seine Kunden-Nr bestimmt ist.</p>
685<p>Eine besondere Stellung hat der <strong>Schlüssel</strong>: er ist ein Attribut (oder eine Attributskombination) von dem alle anderen Attribut einer Relation funktional abhängig sind.</p>
686<p>Von transitiver Abhängigkeit spricht man dann, wenn ein Attribut C von einem Attribut A derart abhängig ist, daß C funktional von einem Attribut B abhängt, das seinerseits funktional von A abhängt.</p>
687<p>Ziel der Normalisierung ist, die Attribute so zu Entitätsmengen bzw. Relationen zu ordnen, daß innerhalb einer Relation <strong>keine Redundanzen</strong> auftreten.</p>
688<p>Ob eine funktionale Abhängigkeit vorliegt, ist nicht immer einfach zu beurteilen: die Abhängigkeit kann in der modellierten Welt nicht bestehen, während sie in den Einträgen der Datenbank durchaus zu finden ist:</p>
689<hr />
690<hr />
691<ol start="34" class="example" style="list-style-type: decimal">
692<li>Erläutern Sie das Konzept der Normalformen.</li>
693</ol>
694<hr />
695<p><strong>1.e Normalform</strong></p>
696<p>Alle Wertebereiche der Attribute einer Relation sind atomar. Atomar ist ein Wertebereich dann, wenn seine Werte nicht selbst Mengen sind bzw. keine innere Struktur aufweisen.</p>
697<table>
698<thead>
699<tr class="header">
700<th><em>Vorgang</em></th>
701<th align="left">Datum</th>
702<th><em>Signatur</em></th>
703<th align="left">Titel</th>
704<th>Benutzer</th>
705<th align="left">Anschrift</th>
706</tr>
707</thead>
708<tbody>
709<tr class="odd">
710<td>1352</td>
711<td align="left">22.1.97</td>
712<td>MAI I/1</td>
713<td align="left">Logic Programming</td>
714<td>ST442</td>
715<td align="left">Schellingstr. 3, 80799 München</td>
716</tr>
717<tr class="even">
718<td>1352</td>
719<td align="left">22.1.97</td>
720<td>CLO I/2</td>
721<td align="left">Programming in Prolog</td>
722<td>ST442</td>
723<td align="left">Schellingstr. 3, 80799 München</td>
724</tr>
725<tr class="odd">
726<td>1353</td>
727<td align="left">22.1.97</td>
728<td>ZEH I/1</td>
729<td align="left">Informationssysteme</td>
730<td>DOZ387</td>
731<td align="left">Oettingenstr. 67, 80538</td>
732</tr>
733</tbody>
734</table>
735<p>Diese Relation hat die Attributkombination Vorgang und Signatur als Schlüssel. Die Schlüssel sind stets die kursiven Attribute.</p>
736<p>Obige Relation ist nicht in 1.NF, da das Attribut Anschrift offensichtlich nicht atomar ist: Die Anschrift gliedert sich in Straßenname mit Nummer, Postleitzahl, und Ort.</p>
737<table>
738<thead>
739<tr class="header">
740<th><em>Vorgang</em></th>
741<th align="left">Datum</th>
742<th><em>Signatur</em></th>
743<th align="left">Titel</th>
744<th>Benutzer</th>
745<th align="left">Straße</th>
746<th align="left">PLZ</th>
747<th align="left">Ort</th>
748</tr>
749</thead>
750<tbody>
751<tr class="odd">
752<td>1352</td>
753<td align="left">22.1.97</td>
754<td>MAI I/1</td>
755<td align="left">Logic Programming</td>
756<td>ST442</td>
757<td align="left">Schellingstr. 3</td>
758<td align="left">80799</td>
759<td align="left">München</td>
760</tr>
761<tr class="even">
762<td>1352</td>
763<td align="left">22.1.97</td>
764<td>CLO I/2</td>
765<td align="left">Programming in Prolog</td>
766<td>ST442</td>
767<td align="left">Schellingstr. 3</td>
768<td align="left">80799</td>
769<td align="left">München</td>
770</tr>
771<tr class="odd">
772<td>1353</td>
773<td align="left">22.1.97</td>
774<td>ZEH I/1</td>
775<td align="left">Informationssysteme</td>
776<td>DOZ387</td>
777<td align="left">Oettingenstr. 67</td>
778<td align="left">80538</td>
779<td align="left">München</td>
780</tr>
781</tbody>
782</table>
783<p>Man unterscheidet bei der ersten Normalform die Interpretation des darunterliegenden Wertbereiches.</p>
784<table>
785<thead>
786<tr class="header">
787<th align="left">ISBN#</th>
788<th align="left">Titel</th>
789<th align="left">Autor</th>
790</tr>
791</thead>
792<tbody>
793<tr class="odd">
794<td align="left">0070447527</td>
795<td align="left">Database System Concept</td>
796<td align="left">Korth, Silberschatz</td>
797</tr>
798</tbody>
799</table>
800<p>Obwohl die Menge aller Zeichenfolgen mit n Zeichen dem Attribut Autor zugrundeliegt, ist das Beispiel nicht in 1NF, da Autor als Menge interpretiert wird.</p>
801<p>Das Tupel</p>
802<table>
803<thead>
804<tr class="header">
805<th align="left">ISBN#</th>
806<th align="left">Titel</th>
807<th align="left">Autor</th>
808</tr>
809</thead>
810<tbody>
811<tr class="odd">
812<td align="left">0070447527</td>
813<td align="left">Database System Concept</td>
814<td align="left">Korth, Silberschatz</td>
815</tr>
816</tbody>
817</table>
818<p>ist in 1NF, da Korth-Silberschatz als atomarer Wert, d.h. eine unteilbare Zeichenfolge, angesehen wird.</p>
819<hr />
820<p><strong>2.e Normalform</strong></p>
821<p>Kein Attribut der Relation ist von einem Teilschlüssel funktional abhängig.</p>
822<table>
823<thead>
824<tr class="header">
825<th><em>Vorgang</em></th>
826<th align="left">Datum</th>
827<th>Benutzer</th>
828<th align="left">Straße</th>
829<th align="left">PLZ</th>
830<th align="left">Ort</th>
831</tr>
832</thead>
833<tbody>
834<tr class="odd">
835<td>1352</td>
836<td align="left">22.1.97</td>
837<td>ST442</td>
838<td align="left">Schellingstr. 3</td>
839<td align="left">80799</td>
840<td align="left">München</td>
841</tr>
842<tr class="even">
843<td>1353</td>
844<td align="left">22.1.97</td>
845<td>DOZ387</td>
846<td align="left">Oettingenstr. 67</td>
847<td align="left">80538</td>
848<td align="left">München</td>
849</tr>
850</tbody>
851</table>
852<table>
853<thead>
854<tr class="header">
855<th><em>Signatur</em></th>
856<th align="left">Titel</th>
857</tr>
858</thead>
859<tbody>
860<tr class="odd">
861<td>MAI I/1</td>
862<td align="left">Logic Programming</td>
863</tr>
864<tr class="even">
865<td>CLO I/2</td>
866<td align="left">Programming in Prolog</td>
867</tr>
868<tr class="odd">
869<td>ZEH I/1</td>
870<td align="left">Informationssysteme</td>
871</tr>
872</tbody>
873</table>
874<table>
875<thead>
876<tr class="header">
877<th><em>Vorgang</em></th>
878<th><em>Signatur</em></th>
879</tr>
880</thead>
881<tbody>
882<tr class="odd">
883<td>1352</td>
884<td>MAI I/1</td>
885</tr>
886<tr class="even">
887<td>1352</td>
888<td>CLO I/2</td>
889</tr>
890<tr class="odd">
891<td>1353</td>
892<td>ZEH I/1</td>
893</tr>
894</tbody>
895</table>
896<hr />
897<p><strong>3.e Normalform</strong></p>
898<p>Kein Attribut der Relation ist von einem Teilschlüssel oder Nichtschlüssel- Attributen funktional abhängig (transitiv).</p>
899<p>Von transitiver Abhängigkeit spricht man dann, wenn ein Attribut C von einem Attribut A derart abhängig ist, daß C funktional von einem Attribut B abhängt, das seinerseits funktional von A abhängt.</p>
900<p>Die obige Relation ist nicht in 3. NF, da z. B. die Straße funktional abhängig vom Nichtschlüsselattribut <strong>Benutzer</strong> ist.</p>
901<p><em>Benutzer</em></p>
902<table>
903<thead>
904<tr class="header">
905<th>Benutzer</th>
906<th align="left">Straße</th>
907<th align="left">PLZ</th>
908</tr>
909</thead>
910<tbody>
911<tr class="odd">
912<td>ST442</td>
913<td align="left">Schellingstr. 3</td>
914<td align="left">80799</td>
915</tr>
916<tr class="even">
917<td>DOZ387</td>
918<td align="left">Oettingenstr. 67</td>
919<td align="left">80538</td>
920</tr>
921</tbody>
922</table>
923<p><em>PLZVerzeichnis</em></p>
924<table>
925<thead>
926<tr class="header">
927<th align="left">PLZ</th>
928<th align="left">Ort</th>
929</tr>
930</thead>
931<tbody>
932<tr class="odd">
933<td align="left">80799</td>
934<td align="left">München</td>
935</tr>
936<tr class="even">
937<td align="left">80538</td>
938<td align="left">München</td>
939</tr>
940</tbody>
941</table>
942<p><em>Katalog</em></p>
943<table>
944<thead>
945<tr class="header">
946<th>Signatur</th>
947<th align="left">Titel</th>
948</tr>
949</thead>
950<tbody>
951<tr class="odd">
952<td>MAI I/1</td>
953<td align="left">Logic Programming</td>
954</tr>
955<tr class="even">
956<td>CLO I/2</td>
957<td align="left">Programming in Prolog</td>
958</tr>
959<tr class="odd">
960<td>ZEH I/1</td>
961<td align="left">Informationssysteme</td>
962</tr>
963</tbody>
964</table>
965<p><em>Ausleihvorgang</em></p>
966<table>
967<thead>
968<tr class="header">
969<th>Vorgang</th>
970<th align="left">Datum</th>
971<th>Benutzer</th>
972</tr>
973</thead>
974<tbody>
975<tr class="odd">
976<td>1352</td>
977<td align="left">22.1.97</td>
978<td>ST442</td>
979</tr>
980<tr class="even">
981<td>1353</td>
982<td align="left">22.1.97</td>
983<td>DOZ387</td>
984</tr>
985</tbody>
986</table>
987<p><em>Buchverleih</em></p>
988<table>
989<thead>
990<tr class="header">
991<th>Vorgang</th>
992<th>Signatur</th>
993</tr>
994</thead>
995<tbody>
996<tr class="odd">
997<td>1352</td>
998<td>MAI I/1</td>
999</tr>
1000<tr class="even">
1001<td>1352</td>
1002<td>CLO I/2</td>
1003</tr>
1004<tr class="odd">
1005<td>1353</td>
1006<td>ZEH I/1</td>
1007</tr>
1008</tbody>
1009</table>
1010<!--
1011
1012 **Speicherplatz**
1013
1014Eine Normalisierung erhöht die Anzahl der Relationen in einer Datenbank. Ein
1015Gewinn an Speicherplatz ist nicht immer gegeben, da für jede neue Relation
1016mindestens ein Attribut als Schlüsselattribut hinzugefügt werden muß (Signatur,
1017Benutzer, PLZ sind jetzt in jeweils zwei Relationen enthalten).
1018
1019Durch die Zerlegung in mehrere Relationen werden Abfragen komplizierter, da nun
1020vermehrt Joins formuliert werden müssen.
1021
1022 *Beispiel*
1023
1024Finde die Orte aller Benutzer vom 22.1.97
1025
1026~~~ sql
1027SELECT Ort
1028FROM Buchverleih
1029WHERE Datum = "22.1.97"
1030~~~
1031
1032In der Datenbank in 3. NF ist diese Abfrage wesentlich komplexer:
1033
1034~~~ sql
1035SELECT PLZVerzeichnis.Ort
1036FROM Ausleihvorgang, Benutzer, PLZVerzeichnis
1037WHERE Ausleihvorgang.Datum = "22.1.97"
1038 AND Ausleihvorgang.Benutzer = Benutzer.Benutzer
1039 AND Benutzer.PLZ = PLZVerzeichnis.PLZ
1040~~~
1041
1042Dem Nachteil der komplexen Abfragen steht die völlige Redundanzfreiheit von
1043Nichtschlüsselattributen gegenüber, die die Datenbank vor Inkonsistenzen
1044weitgehend schützt. Es ist z.B. nicht mehr möglich, einer Postleitzahl mehrere
1045Orte zuzuordnen, so wie dies sowohl in der Datenbank in 1. NF als auch in 2. NF
1046noch möglich war.
1047
1048Eine Normalisierung muß in jedem Fall mindestens theoretisch durchgeführt
1049werden, um alle Redundanzen zu erkennen. Ob diese normalisierte Datenbank dann
1050auch implementiert wird, muß nach Abwägung von Platzgewinn und zusätzlicher
1051Sicherheit gegenüber den komplizierteren Abfragen entschieden werden. In vielen
1052Fällen ist kontrollierte Redundanz ein guter Kompromiss: durch geeignete
1053Maßnahmen wie z.B. Datenbankprozeduren, die Änderungen an einem redundanten
1054Eintrag an allen weiteren Einträgen durchführen, werden Anomalien vermieden.
1055
1056
1057 **4.e Normalform**
1058
1059Kein Schlüssel-Attribut der Relation ist von anderen Schlüssel-Attributen
1060funktional abhängig.
1061
1062*Vorlesung* *Lehrer* *Buch*
1063----------- -------- ------------
1064Mathematik Mayer Mathematik 1
1065Mathematik Mayer Mathematik 2
1066Mathematik Mülle Mathematik 1
1067Mathematik Mülle Mathematik 2
1068
1069---
1070
1071 **Ein weiteres Beispiel**
1072
1073 *unnormalisierte Relation*
1074
1075*M#* P# MA-Name Proj-Name A# Abt-Name
1076---- --- ------- --------- -- --------
10771 1,2 Mayer WIFIS, VF 1 Personal
10782 2 Müller VF 2 EDV
10793 2 Weber VF 2 EDV
1080
1081 *erste Normalform*
1082
1083*M#* *P#* MA-Name Proj-Name A# Abt-Name
1084---- ---- ------- --------- -- ---------
10851 1 Mayer WIFIS 1 Personal
10861 2 Mayer VF 1 Personal
10872 2 Müller VF 2 EDV
10883 2 Weber VF 2 EDV
1089
1090 *zweite Normalform*
1091
1092Mitarbeiter
1093
1094*M#* MA-Name A# Abt-Name
1095---- ------- -- --------
10961 Mayer 1 Personal
10972 Müller 2 EDV
10983 Weber 2 EDV
1099
1100Projekt-Mitarbeit
1101
1102*M#* *P#*
1103---- ----
11041 1
11051 2
11062 2
11073 2
1108
1109Projekt
1110
1111*P#* Proj-Name
1112---- ---------
11131 WIFIS
11142 VF
1115
1116 *dritte Normalform*
1117
1118Abteilung
1119
1120*A#* Abt-Name
1121---- --------
11221 Personal
11232 EDV
1124
1125Mitarbeiter
1126
1127*M#* MA-Name A#
1128---- ------- --
11291 Mayer 1
11302 Müller 2
11313 Weber 2
1132
1133---
1134
1135 **Weiteres Beispiel**
1136
1137 *Unnormalisierte Form*
1138
1139RechnungsNr|Rechnungsdatum|KundenNr|Vorname|Name|Strasse|Plz|Ort|Anzahl|ArtikelNr|Artikel|Preis|Rechnungssumme
1140-|-|-|-|-|-|-|-|-|-|-|-|-|-
11411|3.2.2016|12|Hans|Mayer|Karlsplatz 3|1040|Wien|2,1|1002,1007|Linux-Magazin 6/16,Linux-CD|9,40.95|58.95
1142
1143 *erste Normalform*
1144
1145RechnungsNr|Rechnungsdatum|KundenNr|Vorname|Name|Strasse|Plz|Ort|Anzahl|ArtikelNr|Artikel|Preis|Rechnungssumme
1146-|-|-|-|-|-|-|-|-|-|-|-|-|-
11471|3.2.2016|12|Hans|Mayer|Karlsplatz 3|1040|Wien|2|1002|Linux-Magazin 6/16|9|58.95
11481|3.2.2016|12|Hans|Mayer|Karlsplatz 3|1040|Wien|1|1007|Linux-CD|40.95|58.95
1149
1150 *zweite Normalform*
1151
1152RechnungsNr|Rechnungsdatum|KundenNr|Vorname|Name|Strasse|Plz|Ort|Anzahl|ArtikelNr|Preis|Rechnungssumme
1153-|-|-|-|-|-|-|-|-|-|-|-|-|-
11541|3.2.2016|12|Hans|Mayer|Karlsplatz 3|1040|Wien|2|1002|58.95
11551|3.2.2016|12|Hans|Mayer|Karlsplatz 3|1040|Wien|1|1007|58.95
1156
1157Artikelnummer|Artikel|Einzelpreis
1158-|-|-|-|-|-|-|-|-|-|-|-|-|-
11591002|Linux-Magazin|6/97|9
11601007|Linux-CD|40.95
1161
1162 *zweite Normalform*
1163
1164RechnungsNr|Rechnungsdatum|KundenNr|Vorname|Name|Strasse|Plz|Ort|Rechnungssumme
1165-|-|-|-|-|-|-|-|-|-|-|-|-|-
11661|3.2.2016|12|Hans|Mayer|Karlsplatz 3|1040|Wien|58.95
1167
1168 Rechnungsposition
1169
1170RechnungsNr|ArtikelNr|Anzahl
1171-|-|-|-|-|-|-|-|-|-|-|-|-|-
11721|1002|2
11731|1007|1
1174
1175 *dritte Normalform*
1176
1177RechnungsNr|Rechnungsdatum|KundenNr|Rechnungssumme
1178-|-|-|-|-|-|-|-|-|-|-|-|-|-
11791|3.2.2016|12|58.95
1180
1181Kundennummer|Vorname|Name|Strasse|Plz|Ort
1182-|-|-|-|-|-|-|-|-|-|-|-|-|-
118312|Hans|Mayer|Karlsplatz 3|1040|Wien
1184
1185 *DDL*
1186
1187 CREATE TABLE Kunden (
1188 Kundennummer INT KEY,
1189 Vorname CHAR(30),
1190 Name CHAR(30) NOT NULL,
1191 Straße CHAR(40) NOT NULL,
1192 Plz INT CHECK Plz BETWEEN 1 AND 99999,
1193 Ort CHAR(35) NOT NULL
1194 )
1195
1196 CREATE TABLE Kunden (
1197 Kundennummer INT KEY,
1198 Vorname CHAR(30),
1199 Name CHAR(30) NOT NULL,
1200 Straße CHAR(40) NOT NULL,
1201 Plz INT CHECK Plz BETWEEN 1 AND 99999,
1202 Ort CHAR(35) NOT NULL
1203 )
1204
1205 CREATE TABLE Rechnung (
1206 Rechnungsnummer INT KEY,
1207 Rechnungsdatum DATE NOT NULL,
1208 Kundennummer INT REFERENCES Kunden,
1209 Rechnungspreis FIXED(10,2)
1210 )
1211
1212 CREATE TABLE Artikel (
1213 Artikelnummer INT KEY,
1214 Artikel CHAR(40) NOT NULL,
1215 Einzelpreis FIXED(10,2) NOT NULL,
1216 Mwst FIXED(2,2)
1217 )
1218
1219 CREATE TABLE Rechnungsposition (
1220 Rechnungsnummer INT,
1221 Artikelnummer INT,
1222 Anzahl INT,
1223 FOREIGN KEY (Rechnungsnummer) REFERENCES Rechnung,
1224 FOREIGN KEY (Artikelnummer) REFERENCES Artikel
1225 )
1226
1227
1228 **Kernfrage:**
1229
1230- Entwerfen Sie für die ersten drei Normalformen eine Tabelle, die diese Normalform verletzt.
1231
1232 **Zusatzfrage:**
1233
1234- Welche Probleme resultieren aus unnormalisierten Daten?
1235
1236-->
1237<hr />
1238<hr />
1239<ol start="35" class="example" style="list-style-type: decimal">
1240<li>Erläutern Sie die Anomalien, die in Relationensystemen der ersten (oder zweiten) Normalform auftreten können.</li>
1241</ol>
1242<hr />
1243<p><strong>Insert-Anomalie:</strong></p>
1244<p>Wie die Bezeichnung bereits vermuten läßt, tritt ein Problem beim Hinzufügen eines neuen Objektes auf. Und zwar genau dann, wenn keine Möglichkeit besteht, dieses Objekt einzutragen, weil sich die zu diesem Objekt gehörenden Attribute zusammen mit logisch fremden Attributen in einer Tabelle befinden.</p>
1245<p><strong>Delete-Anomalie:</strong></p>
1246<p>In einer Relation, wie eben beschrieben, existiert ein zur Insert-Anomalie inverses Problem: Wenn ein Objekt aus dem Datenbestand entfernt werden soll, werden die logisch fremden Attribute ebenfalls gelöscht, weil sie in der gleichen Zeile stehen.</p>
1247<p><strong>Update-Anomalie:</strong></p>
1248<p>Als Folgeerscheinung von Redundanz innerhalb einer Relation begegnet man der Update-Anomalie dann, wenn Änderungen in den Attributwerten eines Objekts in mehreren Zeilen gleichzeitig erfolgen müssen.</p>
1249<h1 id="c.-datenmodellierung-systemanalyse-..."><span class="header-section-number">3</span> C. Datenmodellierung / Systemanalyse <a href="#TOC">...</a></h1>
1250<h2 id="assoziationen-..."><span class="header-section-number">3.1</span> Assoziationen <a href="#TOC">...</a></h2>
1251<p>Ein Kleinunternehmen hat sich dazu entschieden, ihre Angestellten- und Filialdaten in einer relationalen Datenbank zu verwalten. Dadurch kann das Unternehmen besonders einfach den Datenbestand auswerten.</p>
1252<pre><code> |EMPNO| ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
1253 | 7782| CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
1254 | 7839| KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
1255
1256 |DEPTNO| DNAME | LOC |
1257 | 10| ACCOUNTING| NEW YORK |</code></pre>
1258<hr />
1259<ol start="36" class="example" style="list-style-type: decimal">
1260<li><p>Modellieren Sie diesen Sachverhalt in einem Klassendiagramm.</p></li>
1261<li><p>Beschreiben Sie die Attribute mit ihren Datentypen und wesentlichen Merkmalen (Primärschlüssel, Optionalität, Eindeutigkeit)</p></li>
1262</ol>
1263<hr />
1264<dl>
1265<dt>.</dt>
1266<dd><img src="/home/user/acha/www-img/db/uml-emp.jpg" />
1267</dd>
1268</dl>
1269<hr />
1270<hr />
1271<ol start="38" class="example" style="list-style-type: decimal">
1272<li>Beschreiben Sie den Begriff "Assoziation" in UML.</li>
1273</ol>
1274<hr />
1275<ul>
1276<li>Eine Assoziation beschreibt eine Beziehung zwischen zwei oder mehr Klassen.</li>
1277<li>An den Enden von Assoziationen sind häufig Kardinalitäten (Multiplizitäten) vermerkt. Diese drücken aus, wie viele dieser Objekte in Relation zu den anderen Objekten dieser Assoziation stehen.</li>
1278</ul>
1279<hr />
1280<hr />
1281<ol start="39" class="example" style="list-style-type: decimal">
1282<li>Beschreiben Sie den Begriff "Kardinalität" in UML.</li>
1283</ol>
1284<hr />
1285<ul>
1286<li>Die Kardinalität einer Beziehung bestimmt die Anzahl der Klassen, die auf beiden Seiten einer Beziehung miteinander verbunden sind.</li>
1287<li>Auf jeder Seite legt man die untere und die obere Grenze fest.</li>
1288<li>Jede Grenze ist eine ganze, nicht negative Zahl.</li>
1289<li>Die Grenze "*" steht für den Wert unbeschränkt.</li>
1290<li>"*" ist eine Abkürzung für "0..*"</li>
1291<li>Sind beide Grenzen gleich, kann nur eine obere Grenze angegeben werden.</li>
1292<li>Ein Element mit Kardinalität 0..1 wird als optional bezeichnet.</li>
1293</ul>
1294<dl>
1295<dt>.</dt>
1296<dd><img src="/home/user/acha/www-img/db/multiplizitaet.jpg" />
1297</dd>
1298</dl>
1299<hr />
1300<hr />
1301<ol start="40" class="example" style="list-style-type: decimal">
1302<li>Erläutern Sie die Assoziationstypen 1:1, 1:n und m:n mit einem Beispiel.</li>
1303</ol>
1304<hr />
1305<ul>
1306<li><p>1:1 Beziehungen</p>
1307<p>Einem Objekt aus Entität A ist genau ein Objekt aus Entität B zugeordnet und umgekehrt.</p>
1308<p>Bsp.: Die katholische Kirche geht davon aus, daß jeder Mann mit einer Frau (und nicht mehr) verheiratet ist - also eine 1:1-Relation.</p></li>
1309<li><p>1:n Beziehungen</p>
1310<p>Einem Objekt aus Entität A sind mehrere Objekte aus Entität B zugeordnet.</p>
1311<p>Bsp.: In anderen Kulturen kann ein Mann auch mit mehreren Frauen verheiratet sein. Dieser Sachverhalt läßt sich mit einer 1:n Beziehung modellieren.</p></li>
1312<li><p>m:n Beziehungen</p>
1313<p>Einem Objekt aus Entität A sind mehrere Objekte aus Entität B zugeordnet, umgekehrt sind aber auch einem Objekt aus Entität B mehrere Objekte aus Entität A zugeordnet.</p>
1314<p>Bsp.: Mir sind keine Kulturen bekannt, in denen mehrere Männer mit mehreren Frauen verheiratet sind. Es besteht also keine Notwendigkeit die Beziehung „Ehe“ mit einer m:n Beziehung darzustellen.</p></li>
1315</ul>
1316<hr />
1317<hr />
1318<ol start="41" class="example" style="list-style-type: decimal">
1319<li>Erläutern Sie den Begriff assoziative Klasse. Zeichnen Sie dazu ein aussagekräftiges Beispiel.</li>
1320</ol>
1321<hr />
1322<p>Eine assoziative Klasse ist eine Assoziation, die selbst Attribute hat.</p>
1323<p>Z. B. ist das Hochzeitsdatum Attribut der Beziehung Ehe.</p>
1324<dl>
1325<dt>.</dt>
1326<dd><img src="/home/user/acha/www-img/uml-assoziation/assoziative-klasse.png" />
1327</dd>
1328</dl>
1329<hr />
1330<hr />
1331<ol start="42" class="example" style="list-style-type: decimal">
1332<li>Erläutern Sie den Begriff rekursive Assoziation.</li>
1333</ol>
1334<hr />
1335<p>Eine rekursive Assoziation hat eine Entität mit sich selbst.</p>
1336<p>Bsp.: „ist Mutter von“ ist eine rekursive Assoziation auf der Entität „Person“</p>
1337<hr />
1338<hr />
1339<ol start="43" class="example" style="list-style-type: decimal">
1340<li>Erläutern Sie die Speicherung von Assoziationen in MongoDB.</li>
1341</ol>
1342<hr />
1343<p>MongoDB verwendet statt <strong>Fremdschlüssel</strong> das Konzept von Einbettung und Verlinkung. Ein <strong>Link</strong> ist ein Verweis auf ein anderes Dokument.</p>
1344<p>Er muss auf der Ebene der Anwendungsprogramme interpretiert und das referenzierte Dokument in einer zusätzlichen Abfrage eingelesen werden.</p>
1345<p>Bei der <strong>Einbettung</strong> werden die referenzierten Datensätze als Unterdokument in das referenzierende Dokument eingebettet.</p>
1346<p>Beispielsweise enthält ein Dokument, dass eine CD repräsentiert, ein Unterdokument für jeden Track auf der CD, das dann die Eigenschaften wie Tracknummer, Künstler, Titel, etc. enthält.</p>
1347<hr />
1348<hr />
1349<ol start="44" class="example" style="list-style-type: decimal">
1350<li><p>Entwerfen Sie die Collections für ein hochperformantes Shop-System:</p>
1351<ul>
1352<li>Eine Bestellung umfasst mehrere Bestellpositionen.</li>
1353<li>Die wesentlichen Produktdaten sollen redundant bei der Bestellung abgespeichert werden.</li>
1354</ul>
1355<p>Der Produktkatalog ist vielfältig, im Datenmodell ist das über eine Vererbungshierarchie abgebildet:</p></li>
1356</ol>
1357<dl>
1358<dt>.</dt>
1359<dd><img src="/home/user/my/acha/www-img/mongodb/produkte.png" />
1360</dd>
1361</dl>
1362<hr />
1363<dl>
1364<dt>.</dt>
1365<dd><img src="/home/user/acha/www-img/mongodb/bestellungen.png" />
1366</dd>
1367</dl>
1368<p><strong>Bestellung</strong></p>
1369<p>Objekte mit 1:n-Beziehungen können direkt in einem Datensatz (=Dokument) abspeichert werden.</p>
1370<ul>
1371<li>Jede <strong>Bestellposition</strong> einer <em>Bestellung</em> referenziert zum einen das <em>Produkt</em> mit all seinen Attributen (auch solchen, die für den Aspekt der Bestellung unwichtig sind),</li>
1372<li>zum anderen werden in der <em>ProduktInfo</em> die für die <em>Bestellung</em> relevanten Daten eines <em>Produkts</em>, z. B. der Name und die Größe, denormalisiert bei der Bestellung gespeichert.</li>
1373</ul>
1374<p><strong>Produkt</strong></p>
1375<p>All diese verschiedenen Produkte des Produktkatalogs können wir in einer Collection speichern.</p>
1376<p>In der Collection "Produkt" gibt es ein Attribut, das die Art des Produkts (CD, Buch, ...) festlegt.</p>
1377<h2 id="vererbung-attribute-..."><span class="header-section-number">3.2</span> Vererbung, Attribute <a href="#TOC">...</a></h2>
1378<p>Ein Kleinunternehmen hat sich dazu entschieden, ihre Angestellten- und Filialdaten in einer relationalen Datenbank zu verwalten. Dadurch kann das Unternehmen besonders einfach den Datenbestand auswerten.</p>
1379<ol start="45" class="example" style="list-style-type: decimal">
1380<li><p>Erweitern Sie das Klassendiagramm um folgenden Sachverhalt:</p>
1381<p>Die Analytiker Scott und Jones sind keine US-Staatsbürger. Das Unternehmen muss die Nummer der Greencard und das Ausstellungsdatum speichern.</p></li>
1382</ol>
1383<dl>
1384<dt>.</dt>
1385<dd><img src="/home/user/acha/www-img/db/uml-emp.jpg" />
1386</dd>
1387</dl>
1388<hr />
1389<dl>
1390<dt>.</dt>
1391<dd><img src="/home/user/acha/www-img/db/immigrant.jpg" />
1392</dd>
1393</dl>
1394<!--
1395greencard-id: String {mandatory}
1396greencard-issued: Date {mandatory}
1397-->
1398<hr />
1399<hr />
1400<ol start="46" class="example" style="list-style-type: decimal">
1401<li>Erläutern Sie die Vererbung mit einem Beispiel.</li>
1402</ol>
1403<hr />
1404<ul>
1405<li>Bei der Vererbung wird aus ähnlich Klassen eine <strong>Super-Klasse abstrahiert</strong>.</li>
1406<li>Alle seine <strong>Sub-Klassen erben</strong> von ihm Attribute und Beziehungen.</li>
1407<li>Nur die <strong>speziellen Eigenschaften</strong> einer Sub-Klasse <strong>verbleiben</strong> bei dieser, da sie nicht allen Typen gemein sind.</li>
1408<li>Man sagt auch, die Sub-Klasse ist eine <strong>Spezialisierung</strong> der Super-Klasse.</li>
1409</ul>
1410<p><strong>Bsp.:</strong></p>
1411<ul>
1412<li>Die Super-Klasse Produkt hat die Sub-Klassen Lebensmittel und Hygieneartikel.</li>
1413<li>Die Super-Klasse hat all die Attribute, die alle Sub-Klassen gemeinsam haben („Preis“, ...).</li>
1414<li>Die Sub-Klassen haben nur die Attribute, die sie mit den anderen Sub-Klassen nicht teilen.
1415<ul>
1416<li>So haben z. B. nur Lebensmittel ein „Ablaufdatum“.</li>
1417</ul></li>
1418<li>Die Sub-Klassen erben nun alle Attribute der Super-Klasse.</li>
1419</ul>
1420<hr />
1421<hr />
1422<ol start="47" class="example" style="list-style-type: decimal">
1423<li>Spezifizieren Sie die Attribute möglichst vollständig.<br> Spezifizieren Sie auch die zeitliche Abfolge von Geburtsdatum, Immatrikulation und Vordiplom.</li>
1424</ol>
1425<dl>
1426<dt>.</dt>
1427<dd><img src="/home/user/acha/www-img/uml/attribut.png" />
1428</dd>
1429</dl>
1430<hr />
1431<pre><code>Matrikelnr: String(7) {mandatory, key, frozen}
1432Name: NameT {mandatory}
1433Geburtsdatum: Date {mandatory, frozen}
1434Immatrikulation: Date {mandatory, Beschreibung: Datum des Studienbeginns}
1435Vordiplom: Date {Beschreibung: Datum der abschließenden Vordiplomprüfung}
1436Noten: list of NoteT
1437Restriktionen: {Geburtsdatum < Immatrikulation < Vordiplom}</code></pre>
1438<p>Bei den Typen NameT und NoteT handelt es sich um elementare Klassen.</p>
1439<p>Beim Aufzählungstyp NotenwertT soll genau ein Wert ausgewählt werden, wobei die Liste für den Benutzer nicht erweiterbar sein darf. Daher ergibt sich für NotenwertT folgende Definition:</p>
1440<pre><code> {values: 1.0, 1.3, 1.7, 2.0, 2.3, 2.7, 3.0, 3.3, 3.7, 4.0, 5.0, noAdd}</code></pre>
1441<hr />
1442<hr />
1443<ol start="48" class="example" style="list-style-type: decimal">
1444<li>Erklären Sie die Beschreibung von Attributen.<br></li>
1445</ol>
1446<hr />
1447<pre><code> Attribut: Typ = Anfangswert {Merkmal1, Merkmal2, ...}</code></pre>
1448<p>Attribute werden durch ihren Namen und ihren Typ beschrieben.</p>
1449<p>Optional können angegeben werden:</p>
1450<ul>
1451<li><p>Anfangswert (initial-value)</p>
1452<p>Er legt fest, welchen Wert ein neu erzeugtes Objekt für dieses Attribut annimmt.</p></li>
1453<li><p>Liste von Merkmalen</p>
1454<p>Hier können die Merkmale bzw. die Eigenschaften des Attributs angegeben werden.</p>
1455<pre><code>{mandatory, key, frozen, Einheit: ...., Beschreibung: ... }</code></pre>
1456<ul>
1457<li>key: Schlüssel (Sind mehrere Attribute einer Klasse mit key gekennzeichnet, dann bilden sie einen zusammengesetzten Schlüssel.)</li>
1458<li>mandatory: Muß-Attribut</li>
1459<li>frozen: Attributwert nicht änderbar</li>
1460<li>Einheit: zB Fahrzeit in [min], gefahrene Strecke in [km]</li>
1461<li>Beschreibung: Die Bedeutung des Attributs noch durch eine Beschreibung erläutert werden.</li>
1462</ul>
1463<p>Fehlen <code>mandatory, key, frozen</code>, dann gelten die <strong>Voreinstellungen</strong>, d.h. das Attribut ist ein Kann-Attribut, kein Schlüsselattribut und beliebig änderbar.</p></li>
1464</ul>
1465<hr />
1466<hr />
1467<ol start="49" class="example" style="list-style-type: decimal">
1468<li>Beschreiben Sie die grafische Notation der Attribute.<br> Erläutern Sie die Begriffe "abgeleitetes Attribut" und "Klassenattribut.</li>
1469</ol>
1470<hr />
1471<dl>
1472<dt>.</dt>
1473<dd><img src="/home/user/acha/www-img/uml/attribut-notation.png" />
1474</dd>
1475<dt>.</dt>
1476<dd><img src="/home/user/acha/www-img/uml/attribut-abgeleitet.png" />
1477</dd>
1478</dl>
1479<p>Der Wert eines <strong>abgeleiteten Attributs</strong> (derived attribute) kann jederzeit aus anderen Attributwerten berechnet werden. Abgeleitete Attribute werden mit dem <strong>Präfix »/«</strong> gekennzeichnet. Ein abgeleitetes Attribut darf nicht geändert werden.</p>
1480<p>Ein Klassenattribut liegt vor, wenn nur ein Attributwert für alle Objekte einer Klasse existiert. Klassenattribute existieren auch dann, wenn es zu einer Klasse – noch – keine Objekte gibt. Um die Klassenattribute von den (Objekt-) Attributen zu unterscheiden, werden sie in der UML <strong>unterstrichen</strong>.</p>
1481<hr />
1482<hr />
1483<ol start="50" class="example" style="list-style-type: decimal">
1484<li>Erläuten Sie die Begriffe "komplexes Objekt" und "rekursives Objekt".</li>
1485</ol>
1486<hr />
1487<p>Besitzt ein Objekt Attribute, die selbst wieder Objekte sind, so wird es als <strong>komplexes Objekt</strong> (composite object, complex object, structured object, molecular object) bezeichnet. Dieses (Unter-) Objekt kann ebenfalls komplex sein.</p>
1488<p><strong>Rekursive Objekte</strong> entstehen, wenn die Klasse eines Objekts dieselbe ist wie die eines direkten oder indirekten Unterobjekts.</p>
1489<hr />
1490<hr />
1491<ol start="51" class="example" style="list-style-type: decimal">
1492<li>Erklären Sie die Beschreibung von Restriktionen mit einem Beispiel.</li>
1493</ol>
1494<hr />
1495<p>Zwischen den Attributwerten eines Objekts können Beziehungen Restriktionen existieren, die während der Ausführung des Systems unverändert (constraints) erhalten bleiben müssen. Wir sprechen hier von Restriktionen (constraints). Eine Restriktion wird auch als Invariante bezeichnet. Es ist eine Zusicherung, die immer wahr sein muß.</p>
1496<p><em>Beispiele:</em></p>
1497<ol style="list-style-type: decimal">
1498<li><p><code>{Vordiplom > Immatrikulation > Geburtsdatum}</code></p></li>
1499<li><p><code>{Verkaufspreis >= 1.5 * Einkaufspreis}</code></p>
1500<p>Für die Klasse Artikel mit den Attributen Einkaufspreis und Verkaufspreis gilt, daß der Verkaufspreis mindestens 150 Prozent des Einkaufspreises betragen soll. Dann muß durch die Implementierung sichergestellt werden, daß beim Ändern des einen Preises auch der andere geändert wird.</p></li>
1501</ol>
1502<h1 id="d.-datenbankabfrage-sql-..."><span class="header-section-number">4</span> D. Datenbankabfrage (SQL) <a href="#TOC">...</a></h1>
1503<h2 id="joins-..."><span class="header-section-number">4.1</span> Joins <a href="#TOC">...</a></h2>
1504<p>Ein Kleinunternehmen hat sich dazu entschieden, ihre Angestellten- und Filialdaten in einer relationalen Datenbank zu verwalten. Dadurch kann das Unternehmen besonders einfach den Datenbestand auswerten.</p>
1505<pre><code>|EMPNO| ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
1506| 7934| MILLER| CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
1507| 7782| CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
1508| 7839| KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
1509| 7369| SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
1510| 7876| ADAMS | CLERK | 7788 | 1983-01-12 | 1100.00 | NULL | 20 |
1511| 7566| JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
1512| 7788| SCOTT | ANALYST | 7566 | 1982-12-09 | 3000.00 | NULL | 20 |
1513| 7902| FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
1514| 7900| JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
1515| 7654| MARTIN| SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
1516| 7521| WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
1517| 7844| TURNER| SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
1518| 7499| ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
1519| 7698| BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |</code></pre>
1520<hr />
1521<ol start="52" class="example" style="list-style-type: decimal">
1522<li>Ermitteln Sie alle Mitarbeiter, die mehr verdienen als JONES. Lösen Sie dieses Problem auf zwei Arten.</li>
1523</ol>
1524<hr />
1525<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> someone.ename
1526<span class="kw">FROM</span> emp <span class="kw">AS</span> someone, emp <span class="kw">AS</span> jones
1527<span class="kw">WHERE</span> jones.ename = <span class="st">'JONES'</span>
1528 <span class="kw">AND</span> someone.sal > jones.sal;
1529
1530<span class="kw">SELECT</span> ename
1531<span class="kw">FROM</span> emp
1532<span class="kw">WHERE</span> sal > (<span class="kw">SELECT</span> sal <span class="kw">FROM</span> emp <span class="kw">WHERE</span> ename = <span class="st">'JONES'</span>);</code></pre></div>
1533<hr />
1534<hr />
1535<ol start="53" class="example" style="list-style-type: decimal">
1536<li>Die SQL-Befehle lassen sich drei Kategorien zuordnen. Beschreiben Sie diese.</li>
1537</ol>
1538<hr />
1539<ul>
1540<li>DML: (Data Manipulation Language) Befehle zur Datenmanipulation (Ändern, Einfügen, Löschen) und <strong>lesendem Zugriff</strong>.
1541<ul>
1542<li>Diese Befehle werden auch unter der Bezeichnung <strong>CRUD</strong> zusammengefasst.</li>
1543<li>CRUD ist ein Akronym aus den Worten "Create", "Read", "Update" und "DELETE"</li>
1544</ul></li>
1545<li>DDL: (Data Definition Language) Befehle zur Definition des Datenbankschemas</li>
1546<li>DCL: (Data Control Language) Befehle für die Rechteverwaltung und Transaktionskontrolle</li>
1547</ul>
1548<hr />
1549<hr />
1550<ol start="54" class="example" style="list-style-type: decimal">
1551<li>Das SELECT-Statement legt in seinen Klauseln relationale Operatoren fest. Erläutern Sie diese.<br> Hinweis: Die Operatoren der Grundrechnungsarten sind Addition, Subtraktion, .... -- Und Sie sollen analoge Operatoren des SELECT-Statements beschreiben.</li>
1552</ol>
1553<hr />
1554<p>Zu diesen Operatoren gehören</p>
1555<ul>
1556<li>Selektion,</li>
1557<li>Projektion und</li>
1558<li>Verbundoperation.</li>
1559</ul>
1560<p><strong>Selektion</strong> (WHERE-Klausel): Sie liefert aus einer gegebenen <strong>Relation</strong> (= Tabelle) die Menge der <strong>Tupel</strong> (=Zeilen, Datensätze), die der Selektionsbedingung genügen.</p>
1561<p><strong>Projektion</strong> (SELECT-Klausel): Bei dieser Operation erhält man eine Auswahl von Spalten einer Relation.</p>
1562<p><strong>Verbundoperationen</strong> (FROM-Klausel): Der Verbund (Join) verbindet mehrere Relationen über einen gemeinsamen Ausdruck und erzeugt eine Resultatrelation.</p>
1563<hr />
1564<hr />
1565<ol start="55" class="example" style="list-style-type: decimal">
1566<li>Beschreiben und erläutern Sie die einzelnen Schritte der SELECT-Pipeline. Also die Reihenfolge, in der das DBMS, die Query abarbeitet.</li>
1567</ol>
1568<hr />
1569<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> [<span class="kw">DISTINCT</span>] <span class="kw">select</span> heading
1570<span class="kw">FROM</span> <span class="kw">source</span> <span class="kw">tables</span>
1571<span class="kw">WHERE</span> <span class="kw">filter</span> expression
1572<span class="kw">GROUP</span> <span class="kw">BY</span> <span class="fu">grouping</span> expressions
1573<span class="kw">HAVING</span> <span class="kw">filter</span> expression
1574<span class="kw">ORDER</span> <span class="kw">BY</span> ordering expressions
1575<span class="kw">LIMIT</span> <span class="fu">count</span>
1576OFFSET <span class="fu">count</span></code></pre></div>
1577<ol style="list-style-type: decimal">
1578<li><code>FROM source tables</code>: Legt eine oder mehrere Ausgangstabellen fest und kombiniert sie zu einer grossen Arbeitstabelle.</li>
1579<li><code>WHERE filter expressions</code>: Filtert bestimmte Zeilen aus der Arbeittstabelle heraus.</li>
1580<li><code>GROUP BY grouping expressions</code>: Fasst Zeilen zusammen, die in bestimmten Werten übereinstimmen.</li>
1581<li><code>SELECT select heading</code>: Definiert die Kolonnen der Resultatmenge sowie die gruppierenden Funktionen (Aggregatsfunktionen), sofern diese anwendbar sind.</li>
1582<li><code>HAVING filter expression</code>: Filtert bestimmte Zeilen aus der gruppierten Tabelle. Verlangt ein GROUP BY.</li>
1583<li><code>DISTINCT</code>: Eliminiert identische Zeilen.</li>
1584<li><code>ORDER BY ordering expressions</code>: Sortiert die Zeilen der Resultatmenge.</li>
1585<li><code>OFFSET count</code>: Überspringt count Zeilen am anfang der Resultatmenge. Verlangt ein LIMIT.</li>
1586<li><code>LIMIT count</code>: Begrenzt die Anzahl der auszugebenden Zeilen der Resultatmenge auf count .</li>
1587</ol>
1588<hr />
1589<hr />
1590<ol start="56" class="example" style="list-style-type: decimal">
1591<li>Nennen und erläutern Sie die unterschiedlichen Verbundoperationen.</li>
1592</ol>
1593<hr />
1594<ul>
1595<li>Cross Join</li>
1596<li>Equijoin</li>
1597<li>Non-Equijoin</li>
1598<li>Self Join</li>
1599<li>Outer Join</li>
1600</ul>
1601<p><strong><em>Cross Join</em></strong></p>
1602<p>Entspricht dem kartesischen Produkt von zwei oder mehr selektierten Tabellen ohne Join-Bedingung.</p>
1603<p><em>Beispiel:</em></p>
1604<pre><code>sqlite> SELECT ename, loc
1605 FROM emp, dept;
1606
1607ENAME LOC
1608---------- -------------
1609SMITH NEW YORK
1610ALLEN NEW YORK
1611WARD NEW YORK
1612JONES NEW YORK
1613MARTIN NEW YORK
1614BLAKE NEW YORK
1615CLARK NEW YORK
1616SCOTT NEW YORK
1617KING NEW YORK
1618TURNER NEW YORK
1619ADAMS NEW YORK
1620JAMES NEW YORK
1621FORD NEW YORK
1622MILLER NEW YORK
1623SMITH DALLAS
1624ALLEN DALLAS
1625WARD DALLAS
1626JONES DALLAS
1627... </code></pre>
1628<p>Alternative Schreibweise:</p>
1629<pre><code>sqlite> SELECT ename, loc, grade
1630 FROM emp CROSS JOIN dept;</code></pre>
1631<p><strong><em>Equijoin</em></strong></p>
1632<p>Bei einem Equijoin werden die Tabellen über ein Gleichheitszeichen verknüpft: der Wert einer Spalte in der ersten Tabelle muss genau dem Wert einer Spalte in der zweiten Tabelle entsprechen. Zeilen ohne Entsprechung in der jeweils anderen Tabelle werden nicht ausgewählt.</p>
1633<p>Ein Equijoin wird auch als "Inner Join" bezeichnet.</p>
1634<p><em>Beispiel:</em></p>
1635<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql">sqlite> <span class="kw">SELECT</span> ename, loc
1636 <span class="kw">FROM</span> emp, dept <span class="kw">ON</span> emp.deptno = dept.deptno;
1637
1638ename loc
1639<span class="co">------- ----------</span>
1640SMITH DALLAS
1641ALLEN CHICAGO
1642WARD CHICAGO
1643JONES DALLAS
1644MARTIN CHICAGO
1645BLAKE CHICAGO
1646CLARK <span class="kw">NEW</span> YORK
1647SCOTT DALLAS
1648KING <span class="kw">NEW</span> YORK
1649TURNER CHICAGO
1650ADAMS DALLAS
1651JAMES CHICAGO
1652FORD DALLAS </code></pre></div>
1653<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> t1.spalte1, t1.spalte2, t2.spalte1, t2.spalte2, .....
1654<span class="kw">FROM</span> tabelle1 t1 <span class="kw">JOIN</span> tabelle2 t2
1655<span class="kw">ON</span> t1.spalte1 = t2. spalte1
1656<span class="kw">WHERE</span> <weitere Bedingungen></code></pre></div>
1657<p>ODER:</p>
1658<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> t1.spalte1, t1.spalte2, t2.spalte1, t2.spalte2, .....
1659<span class="kw">FROM</span> tabelle1 t1, tabelle2 t2
1660<span class="kw">WHERE</span> t1.spalte1 = t2.spalte1
1661<span class="kw">AND</span> <weitere Bedingungen></code></pre></div>
1662<p>Sie können für die Tabellen einen kurzen Aliasnamen vergeben und alle Spalten mittels Punktnotation mit dem Aliasnamen ihrer Herkunftstabellen zu kennzeichnen.</p>
1663<p>Beispiel: Gesucht sind Name, Gehalt, Abteilungsname, Vorgesetzter und Arbeitsort der emp-Mitarbeiter, die mehr als 1000 € verdienen.</p>
1664<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> ma.ename Chef, ma.sal, d.dname, bo.ename Chef, d.loc
1665<span class="kw">FROM</span> emp ma
1666 <span class="kw">JOIN</span> dept d <span class="kw">ON</span> ma.deptno = d.deptno
1667 <span class="kw">JOIN</span> emp bo <span class="kw">ON</span> ma.mgr = bo.empno
1668<span class="kw">WHERE</span> ma.sal > <span class="dv">1000</span>;</code></pre></div>
1669<p>oder</p>
1670<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> ma.ename Chef, ma.sal, d.dname, bo.ename Chef, d.loc
1671<span class="kw">FROM</span> emp ma, dept d, emp bo
1672<span class="kw">WHERE</span> ma.deptno = d.deptno
1673<span class="kw">AND</span> ma.mgr = bo.empno
1674<span class="kw">AND</span> ma.sal > <span class="dv">1000</span>;
1675
1676CHEF SAL DNAME CHEF LOC
1677<span class="co">------- ------ ---------- ---------- ----------</span>
1678FORD <span class="dv">3000</span> RESEARCH JONES DALLAS
1679SCOTT <span class="dv">3000</span> RESEARCH JONES DALLAS
1680TURNER <span class="dv">1500</span> SALES BLAKE CHICAGO
1681MARTIN <span class="dv">1250</span> SALES BLAKE CHICAGO
1682WARD <span class="dv">1250</span> SALES BLAKE CHICAGO
1683ALLEN <span class="dv">1600</span> SALES BLAKE CHICAGO
1684MILLER <span class="dv">1300</span> ACCOUNTING CLARK <span class="kw">NEW</span> YORK
1685ADAMS <span class="dv">1100</span> RESEARCH SCOTT DALLAS
1686CLARK <span class="dv">2450</span> ACCOUNTING KING <span class="kw">NEW</span> YORK
1687BLAKE <span class="dv">2850</span> SALES KING CHICAGO
1688JONES <span class="dv">2975</span> RESEARCH KING DALLAS</code></pre></div>
1689<p><strong><em>Non-Equijoin</em></strong></p>
1690<p>Bei einer Verknüpfung durch einen Non-Equijoin besteht das "Problem", dass sich keine Spalten der zu verknüpfenden Tabellen direkt entsprechen und somit die Beziehung auch nicht durch ein Gleichheitszeichen dargestellt werden kann. Ein Zusammenhang ergibt sich lediglich durch überschneidende Wertebereiche der Inhalte einzelner Spalten. Zum Beispiel durch den Bereichsoperator BETWEEN ... AND.</p>
1691<p><strong><em>Self Join</em></strong></p>
1692<p>Bei einem Self Join wird eine Tabelle mit sich selbst verknüpft.</p>
1693<p>Da die Tabelle zweimal in der FROM-Klausel erscheint, muss ein Alias verwendet werden.</p>
1694<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> a.*, b.*
1695<span class="kw">FROM</span> tabelle1 a, tabelle1 b
1696<span class="kw">WHERE</span> a.spalte1 = b.spalte2</code></pre></div>
1697<p><em>Beispiel:</em></p>
1698<p>Geben Sie die Mitarbeiter und ihre direkten Vorgesetzten aus: </p>
1699<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql">sqlite> <span class="kw">SELECT</span> arbeiter.ename <span class="ot">"Mitarbeiter"</span>, vorgesetzter.ename <span class="ot">"Chef"</span>
1700 FROM emp <span class="kw">AS</span> arbeiter, emp <span class="kw">AS</span> vorgesetzter
1701 WHERE vorgesetzter.empno=arbeiter.mgr ;
1702
1703Mitarbeiter Chef
1704<span class="co">------- --------</span>
1705SMITH FORD
1706ALLEN BLAKE
1707WARD BLAKE
1708JONES KING
1709MARTIN BLAKE
1710BLAKE KING
1711CLARK KING
1712SCOTT JONES
1713TURNER BLAKE
1714ADAMS SCOTT
1715JAMES BLAKE
1716FORD JONES
1717MILLER CLARK</code></pre></div>
1718<p><em>Hinweis:</em></p>
1719<p>Der oben genannte Self Join kann auch so geschrieben werden:</p>
1720<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"> sqlite> <span class="kw">SELECT</span> arbeiter.ename <span class="ot">"Mitarbeiter"</span>, vorgesetzter.ename <span class="ot">"Chef"</span>
1721 FROM emp arbeiter <span class="kw">JOIN</span> emp vorgesetzter ON
1722 (arbeiter.mgr=vorgesetzter.empno);</code></pre></div>
1723<p><strong><em>Outer Join</em></strong></p>
1724<ul>
1725<li>In der Join-Bedingung werden die Schlüsselwörter LEFT JOIN bzw. LEFT OUTER JOIN verwendet.</li>
1726<li>Entspricht eine Zeile nicht der Join-Bedingung, so wird die Zeile nicht in das Abfrageergebnis aufgenommen.</li>
1727<li>Durch die Bezeichnung LEFT JOIN werden auch die Zeilen, die keine Entsprechung in der anderen Tabelle aufweisen, angezeigt.</li>
1728</ul>
1729<p><em>Beispiele:</em></p>
1730<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql">sqlite> <span class="kw">SELECT</span> dname, ename <span class="kw">FROM</span> dept <span class="kw">LEFT</span> <span class="kw">JOIN</span> emp <span class="kw">ON</span> dept.deptno = emp.deptno;
1731
1732dname ename
1733<span class="co">------- ----------</span>
1734ACCOUNTING CLARK
1735ACCOUNTING KING
1736ACCOUNTING MILLER
1737RESEARCH ADAMS
1738RESEARCH FORD
1739RESEARCH JONES
1740RESEARCH SCOTT
1741RESEARCH SMITH
1742SALES ALLEN
1743SALES BLAKE
1744SALES JAMES
1745SALES MARTIN
1746SALES TURNER
1747SALES WARD
1748OPERATIONS </code></pre></div>
1749<h2 id="index-..."><span class="header-section-number">4.2</span> Index <a href="#TOC">...</a></h2>
1750<p>Ein Kleinunternehmen hat sich dazu entschieden, ihre Angestellten- und Filialdaten in einer relationalen Datenbank zu verwalten. Dadurch kann das Unternehmen besonders einfach den Datenbestand auswerten.</p>
1751<pre><code>|EMPNO| ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
1752| 7934| MILLER| CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
1753| 7782| CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
1754| 7839| KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
1755| 7369| SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
1756| 7876| ADAMS | CLERK | 7788 | 1983-01-12 | 1100.00 | NULL | 20 |
1757| 7566| JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
1758| 7788| SCOTT | ANALYST | 7566 | 1982-12-09 | 3000.00 | NULL | 20 |
1759| 7902| FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
1760| 7900| JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
1761| 7654| MARTIN| SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
1762| 7521| WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
1763| 7844| TURNER| SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
1764| 7499| ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
1765| 7698| BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |</code></pre>
1766<hr />
1767<ol start="57" class="example" style="list-style-type: decimal">
1768<li>Ermitteln Sie alle Abteilungen mit mindestens 3 Verkäufern.</li>
1769</ol>
1770<hr />
1771<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> deptno
1772<span class="kw">FROM</span> emp
1773<span class="kw">WHERE</span> job = <span class="st">'SALESMAN'</span>
1774<span class="kw">GROUP</span> <span class="kw">BY</span> deptno
1775<span class="kw">HAVING</span> <span class="fu">COUNT</span>(*) >= <span class="dv">3</span>;</code></pre></div>
1776<hr />
1777<hr />
1778<ol start="58" class="example" style="list-style-type: decimal">
1779<li>Der Suchvorgang nach dem Namen soll beschleunigt werden.</li>
1780</ol>
1781<blockquote>
1782<ul>
1783<li>Entwerfen Sie ein Verfahren, das dies ermöglicht.</li>
1784<li>Erläutern Sie die dazu notwendigen Kommandos.</li>
1785</ul>
1786</blockquote>
1787<hr />
1788<pre><code>CREATE INDEX emp_name ON emp(ename);</code></pre>
1789<hr />
1790<hr />
1791<ol start="59" class="example" style="list-style-type: decimal">
1792<li>Erläutern Sie die Befehle, mit denen ein Index erstellt oder gelöscht werden kann.</li>
1793</ol>
1794<hr />
1795<pre><code>CREATE [UNIQUE] INDEX index-name ON table-name (column [, column ...]);
1796
1797DROP INDEX index-name;</code></pre>
1798<hr />
1799<hr />
1800<ol start="60" class="example" style="list-style-type: decimal">
1801<li>Erläutern Sie den Datenbank-Index.</li>
1802</ol>
1803<hr />
1804<p>Einen Index können Sie sich wie ein <strong>Telefonbuch</strong> vorstellen.</p>
1805<p>Wenn Sie einen Namen suchen, schlagen Sie das Telefonbuch zuerst in etwa in der <strong>Mitte</strong> auf und vergleichen den Namen, den Sie dort vorfinden, mit dem von Ihnen gesuchten Namen. Ist der von Ihnen gesuchte Name größer (weiter hinten im Alphabet), so können Sie die vordere Hälfte getrost vergessen - denn der Name muss sich in der hinteren Hälfte befinden. Nun schlagen Sie die Hälfte der hinteren Hälfte auf u.s.w.</p>
1806<p>Wäre das Telefonbuch <strong>nicht alphabetisch</strong> sortiert, so müssten Sie das ganze Buch durchblättern, um die entsprechende Telefonnummer herauszubekommen.</p>
1807<hr />
1808<hr />
1809<ol start="61" class="example" style="list-style-type: decimal">
1810<li>Nennen und beschreiben Sie die wesentlichsten Eigenschaften von Indexes.</li>
1811</ol>
1812<hr />
1813<ul>
1814<li>Mit einem Index kann die <strong>Position</strong> eines Datensatzes ermittelt werden.</li>
1815<li>Ein Index ist eine Attributkombination für die eine <strong>Tabelle</strong> vom DBMS angelegt wurde.</li>
1816<li>Indizes beschleunigen Such- und Sortieraktionen, <strong>verlangsamen</strong> aber Anfügevorgänge.</li>
1817<li>Ein Index arbeitet ähnlich dem Telefonbuchprinzip. Zuerst wird die indizierte Spalte <strong>sortiert</strong> und anschließend als <strong>Baumstruktur</strong> gespeichert.</li>
1818</ul>
1819<hr />
1820<hr />
1821<ol start="62" class="example" style="list-style-type: decimal">
1822<li>Der Datenbankadministrator möchte sich die bestehende Indizes ansehen.</li>
1823</ol>
1824<blockquote>
1825<ul>
1826<li>Entwerfen Verfahren, das dies ermöglichen.</li>
1827<li>Erläutern Sie die dazu notwendigen Kommandos.</li>
1828</ul>
1829</blockquote>
1830<hr />
1831<p>Mit Hilfe bestimmter Data Dictionary Tables und Views erhalten Sie eine Übersicht über die bestehenden Indizes und die beteiligten Tabellen.</p>
1832<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql">sqlite> <span class="kw">create</span> <span class="kw">table</span> t1(f, g);
1833
1834sqlite> <span class="kw">create</span> <span class="kw">index</span> i1 <span class="kw">on</span> t1(f);
1835
1836sqlite> <span class="kw">select</span> * <span class="kw">from</span> sqlite_master;
1837<span class="kw">type</span> name tbl_name rootpage sql
1838<span class="co">------- ---------- ---------- ---------- ---------------------</span>
1839<span class="kw">table</span> t1 t1 <span class="dv">2</span> <span class="kw">CREATE</span> <span class="kw">TABLE</span> t1(f, g)
1840<span class="kw">index</span> i1 t1 <span class="dv">3</span> <span class="kw">CREATE</span> <span class="kw">INDEX</span> i1 <span class="kw">on</span> t1
1841
1842sqlite> PRAGMA INDEX_LIST(<span class="st">'t1'</span>);
1843seq name <span class="kw">unique</span>
1844<span class="co">------- ---------- ----------</span>
1845<span class="dv">0</span> i1 <span class="dv">0</span>
1846
1847sqlite> PRAGMA INDEX_INFO(<span class="st">'i1'</span>);
1848seqno cid name
1849<span class="co">------- ---------- ----------</span>
1850<span class="dv">0</span> <span class="dv">0</span> f </code></pre></div>
1851<ul>
1852<li>In der Data Dictionary Sicht <strong>sqlite_master</strong> sind auch alle Indizes gespeichert.</li>
1853<li>Sie können auch das PRAGMAS "INDEX_LIST" und "INDEX_INFO" verwenden.</li>
1854</ul>
1855<hr />
1856<hr />
1857<ol start="63" class="example" style="list-style-type: decimal">
1858<li><p>Der Datenbankadministrator hat eine Hilfstabelle erstellt.<br> Prüfen Sie, ob ein Index für die Spalte "f" erstellt werden muss.</p>
1859<pre><code>CREATE TABLE t2(f INT PRIMARY KEY, g);</code></pre></li>
1860</ol>
1861<hr />
1862<ul>
1863<li>Für Primärschlüssel werden Indizes auch automatisch erstellt:</li>
1864<li>Das funktioniert aber nicht bei "INTEGER PRIMARY KEY". Da gibt es einen anderen Mechanismus, der die Funktionalität gewährleistet.</li>
1865</ul>
1866<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql">sqlite> <span class="kw">CREATE</span> <span class="kw">TABLE</span> t2(f <span class="dt">INT</span> <span class="kw">PRIMARY</span> <span class="kw">KEY</span>, g);
1867
1868sqlite> PRAGMA INDEX_LIST(<span class="st">'t2'</span>);
1869seq name <span class="kw">unique</span>
1870<span class="co">------- --------------------- ----------</span>
1871<span class="dv">0</span> sqlite_autoindex_t2_1 <span class="dv">1</span>
1872
1873sqlite> PRAGMA INDEX_INFO(<span class="st">'sqlite_autoindex_t2_1'</span>);
1874seqno cid name
1875<span class="co">------- ---------- ----------</span>
1876<span class="dv">0</span> <span class="dv">0</span> f </code></pre></div>
1877<hr />
1878<hr />
1879<ol start="64" class="example" style="list-style-type: decimal">
1880<li>Entwickeln Sie Richtlinien für das Erstellen von Indexen.</li>
1881</ol>
1882<hr />
1883<ul>
1884<li>Die Spalte wird häufig als Join-Kriterium benutzt.</li>
1885<li>Die meisten Abfragen ermitteln als Ergebnismenge weniger als 5% der Gesamtmenge.</li>
1886<li>Die Tabelle enthält einen sehr selektiven Wertebereich, dass heißt, es kommen verhältnismäßig wenig doppelte Spaltenwerte vor.</li>
1887<li>Die Tabelle wird selten aktualisiert.</li>
1888<li>Die Tabelle ist groß.</li>
1889</ul>
1890<hr />
1891<hr />
1892<ol start="65" class="example" style="list-style-type: decimal">
1893<li>Erläutern Sie die Komplexität von Algorithmen.</li>
1894</ol>
1895<hr />
1896<ul>
1897<li>Komplexität bezeichnet in der Informatik die „Kompliziertheit“ von Problemen, Algorithmen oder Daten.</li>
1898<li>Unter der Komplexität (auch Aufwand oder Kosten) eines Algorithmus versteht man seinen maximalen Ressourcenbedarf.</li>
1899<li>Prozesse verbrauchen u.a. zwei Ressourcen:
1900<ul>
1901<li>Rechenzeit (=Laufzeit)</li>
1902<li>Speicherplatz</li>
1903</ul></li>
1904</ul>
1905<hr />
1906<hr />
1907<ol start="66" class="example" style="list-style-type: decimal">
1908<li>Erläutern Sie die Effektivität von Algorithmen.</li>
1909</ol>
1910<hr />
1911<p>Die Effektivität eines Algorithmus wird an der <strong>Anzahl elementarer Operationen</strong> (Schritte) gemessen, die dieses zur Lösung eines gegebenen Problems benötigt. Aufgrund dieser Zahl kann die Laufzeit ermittelt</p>
1912<ul>
1913<li>Die <strong>Laufzeit</strong> eines Computerprogramms, ist die Zeit, die ein Rechenprozess benötigt, um bei gegebenen Eingabedaten ein Resultat zu erzielen.</li>
1914<li>Die Laufzeit hängt wesentlich vom verwendeten Algorithmus ab.</li>
1915</ul>
1916<hr />
1917<hr />
1918<ol start="67" class="example" style="list-style-type: decimal">
1919<li>Erläutern Sie die O-Notation anhand von Beispielen.</li>
1920</ol>
1921<hr />
1922<ul>
1923<li>Mit der O-Notation lässt sich die Komplexität eines Algorithmus charakterisieren.</li>
1924<li>Sie stellt die Größenordnung der Komplexität dar und abstrahiert von den Details</li>
1925<li>Die O-Notation ist deshalb so wichtig, weil ab einer gewissen Problemgröße die konstanten Faktoren zusehends weniger Rolle spielen.<br />
1926</li>
1927<li>Dabei interessiert nicht der Aufwand eines konkreten Programms auf einem bestimmten Computer, sondern viel mehr, wie der Ressourcenbedarf wächst, wenn mehr Daten zu verarbeiten sind, also z. B. ob sich der Aufwand für die doppelte Datenmenge verdoppelt oder quadriert.</li>
1928</ul>
1929<hr />
1930<table>
1931<thead>
1932<tr class="header">
1933<th align="left">Ordnung</th>
1934<th align="left">Sprechweise</th>
1935<th align="left">Typische Algorithmen / Operationen</th>
1936</tr>
1937</thead>
1938<tbody>
1939<tr class="odd">
1940<td align="left">O(1)</td>
1941<td align="left">konstant</td>
1942<td align="left">Addition</td>
1943</tr>
1944<tr class="even">
1945<td align="left">O(log n)</td>
1946<td align="left">logarithmisch</td>
1947<td align="left">Suchen auf einer sortierten Menge</td>
1948</tr>
1949<tr class="odd">
1950<td align="left">O(n)</td>
1951<td align="left">linear</td>
1952<td align="left">Bearbeiten jedes Elementes einer Menge</td>
1953</tr>
1954<tr class="even">
1955<td align="left">O(n * log n)</td>
1956<td align="left"></td>
1957<td align="left">gute Sortierverfahren</td>
1958</tr>
1959<tr class="odd">
1960<td align="left">O(n<sup>2</sup>)</td>
1961<td align="left">quadratisch</td>
1962<td align="left">primitive Sortierverfahren</td>
1963</tr>
1964<tr class="even">
1965<td align="left">O(n<sup>k</sup>)</td>
1966<td align="left">polynomiell</td>
1967<td align="left"></td>
1968</tr>
1969<tr class="odd">
1970<td align="left">O(2<sup>n</sup>)</td>
1971<td align="left">exponentiell</td>
1972<td align="left">Ausprobieren von Kombinationen</td>
1973</tr>
1974</tbody>
1975</table>
1976<hr />
1977<table>
1978<thead>
1979<tr class="header">
1980<th>Ordnun</th>
1981<th>g n=</th>
1982<th>10 n=1</th>
1983<th>00 n=1000</th>
1984</tr>
1985</thead>
1986<tbody>
1987<tr class="odd">
1988<td>1</td>
1989<td>1</td>
1990<td>1</td>
1991<td>1</td>
1992</tr>
1993<tr class="even">
1994<td>log(n)</td>
1995<td>1</td>
1996<td>2</td>
1997<td>3</td>
1998</tr>
1999<tr class="odd">
2000<td>n</td>
2001<td>10</td>
2002<td>100</td>
2003<td>1000</td>
2004</tr>
2005<tr class="even">
2006<td>n*log(</td>
2007<td>n) 10</td>
2008<td>200</td>
2009<td>3000</td>
2010</tr>
2011<tr class="odd">
2012<td>n<sup>2</sup></td>
2013<td>100</td>
2014<td>1000</td>
2015<td>0 1E6</td>
2016</tr>
2017<tr class="even">
2018<td>2<sup>n</sup></td>
2019<td>102</td>
2020<td>4 1.3E</td>
2021<td>30 1.1E301</td>
2022</tr>
2023</tbody>
2024</table>
2025<p>Anmerkung: 1.3E30 = 1.3 x 10<sup>30</sup></p>
2026<hr />
2027<ul>
2028<li>Die Laufzeit eines Algorithmus der <strong>Ordnung 1 "O(1)"</strong> ist proportional zu "1". Analog dazu gibt es die Ordnungen n, n<sup>2</sup>, ....</li>
2029<li>Konstanten und Polynome niedriger Ordnung werden nicht berücksichtigt.
2030<ul>
2031<li>Bsp.: Ein Verfahren benötigt O(n<sup>2</sup>) Schritte, wenn die exakte Schrittzahl c<sub>2</sub>n<sup>2</sup> + c<sub>1</sub>n + c<sub>0</sub> ist.</li>
2032<li>Deshalb ist es auch egal, welche Basis obige Logarithmen haben.</li>
2033</ul></li>
2034<li>typische Algorithmen der Ordnung <strong>n<sup>2</sup></strong> bearbeiten alle paarweisen Kombinationen von Daten</li>
2035<li>typische Algorithmen der Ordnung <strong>2<sup>n</sup></strong> lösen Probleme "gewaltsam", in dem sie alle Möglichkeiten durchprobieren
2036<ul>
2037<li>Diese Probleme nennt man auch <strong>NP-vollständig</strong>.</li>
2038<li>NP steht für "nicht polynomial".</li>
2039<li>Polynome (Bsp.: 3x+5x3 +8x9) haben stets Konstanten im Exponenten.</li>
2040<li>Schlechtere als polynomielle Laufzeit gilt als nicht effizient.</li>
2041</ul></li>
2042</ul>
2043<hr />
2044<hr />
2045<ol start="68" class="example" style="list-style-type: decimal">
2046<li>Prüfen Sie die algorithmische Komplexität von Suchverfahren in einem geordneten Feld.</li>
2047</ol>
2048<hr />
2049<p>Sei N die Problemgröße == die Anzahl der Elemente in einem geordneten Feld</p>
2050<p>Der Algorithmus SequentialSearch,</p>
2051<ul>
2052<li>welcher das Array sequentiell durchläuft,</li>
2053<li>braucht durchschnittlich N/2 Schritte;</li>
2054<li>seine Komplexität ist O(N)</li>
2055</ul>
2056<p>Der Algorithmus BinarySearch,</p>
2057<ul>
2058<li>welcher das Element nach dem binären Suchverfahren im sortierten Array sucht,</li>
2059<li>braucht durchschnittlich ld(N) Schritte;</li>
2060<li>seine Komplexität ist O(ld(N))</li>
2061</ul>
2062<p>was wesentlich besser ist.</p>
2063<p>Anmerkung: Der Logarithmus zur Basis 2 wird auch als Logarithmus dualis bezeichnet: log2=ld.</p>
2064<h2 id="aufgaben-..."><span class="header-section-number">4.3</span> Aufgaben <a href="#TOC">...</a></h2>
2065<p>Die Datenbank finden Sie <a href="../etc/create_employee.sql.txt">hier</a>.</p>
2066<hr />
2067<hr />
2068<p>Ein Kleinunternehmen hat sich dazu entschieden, ihre Angestellten- und Filialdaten in einer relationalen Datenbank zu verwalten. Dadurch kann das Unternehmen besonders einfach den Datenbestand auswerten.</p>
2069<pre><code>|EMPNO| ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
2070| 7934| MILLER| CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
2071| 7782| CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
2072| 7839| KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
2073| 7369| SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
2074| 7876| ADAMS | CLERK | 7788 | 1983-01-12 | 1100.00 | NULL | 20 |
2075| 7566| JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
2076| 7788| SCOTT | ANALYST | 7566 | 1982-12-09 | 3000.00 | NULL | 20 |
2077| 7902| FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
2078| 7900| JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
2079| 7654| MARTIN| SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
2080| 7521| WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
2081| 7844| TURNER| SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
2082| 7499| ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
2083| 7698| BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |</code></pre>
2084<pre><code>|DEPTNO| DNAME | LOC |
2085| 10| ACCOUNTING| NEW YORK |
2086| 20| RESEARCH | DALLAS |
2087| 30| SALES | CHICAGO |
2088| 40| OPERATIONS| BOSTON |</code></pre>
2089<p>Ihre Aufgabe ist es nun, die SQL-Statements für einige dieser Auswertungen zu schreiben.<br />
2090Die Tabellennamen sind "emp" und "dept".</p>
2091<ol style="list-style-type: decimal">
2092<li>Ermitteln Sie alle Informationen zu den Abteilungen. <!--
2093SELECT * FROM EMP;
2094--></li>
2095<li>Ermitteln Sie Name, Job und Einstellungsdatum der Angestellten, die in der Abteilung 10 arbeiten. <!--
2096SELECT ename, job, hiredate FROM emp WHERE deptno = 10;
2097--></li>
2098<li>Ermitteln Sie die Angestellten, die mehr Provision als Gehalt verdienen. <!--
2099SELECT ename FROM emp WHERE comm > sal;
2100--></li>
2101<li>Ermitteln Sie die Angestellten, die keine Verkäufer sind. <!--
2102SELECT ename, job FROM emp WHERE job != 'SALESMAN';
2103--></li>
2104<li>Ermitteln Sie die Angestellten, die am 3. Dezember 1981 angestellt wurden. <!--
2105SELECT ename FROM emp WHERE hiredate = '1981-12-03';
2106--></li>
2107<li>Ermitteln Sie Name und Gehalt der Angestellten, die nicht zwischen 1250 und 1600 verdienen! Trennen Sie den Namen vom Gehalt mit einen Bindestrich! Erfinden Sie eine andere Überschrift für die Ausgabe. <!--
2108SELECT ename||'-'||sal AS namgel FROM emp WHERE sal NOT BETWEEN 1250 AND 1600;
2109--></li>
2110<li>Ermitteln Sie die Angestellten, deren Provision größer als 25% ihres Gehalts ist. <!--
2111SELECT ename, sal, comm FROM emp WHERE comm > 0.25*sal;
2112--></li>
2113<li>Ermitteln Sie die Angestellten, die keine Führungskräfte (Manager und Präsident) sind. <!--
2114SELECT ename, job FROM emp WHERE job NOT IN ('MANAGER','PRESIDENT');
2115--></li>
2116<li>Ermitteln Sie die Angestellten, deren Name an dritter Stelle ein "A" hat. <!--
2117SELECT ename FROM emp WHERE ename LIKE '__A%';
2118--></li>
2119<li>Ermitteln Sie die Angestellten, die provisionsberechtigt sind (auch wenn die Provision "0" ist). <!--
2120SELECT ename FROM emp WHERE comm IS NOT NULL;
2121--></li>
2122<li>Ermitteln Sie die Angestellten, deren Name 6 Zeichen lang sind. <!--
2123SELECT ename FROM emp WHERE ename LIKE '______';
2124--></li>
2125<li>Ermitteln Sie alle Berufe. <!--
2126SELECT DISTINCT job FROM emp;
2127--></li>
2128<li>Ermitteln Sie das monatlichen Gesamtgehalt aller Angestellten. <!--
2129SELECT SUM(sal) FROM emp;
2130--></li>
2131<li>Ermitteln Sie die durchschnittliche Provision im Konzern, wenn für die Mitarbeiter, welche keine Provision eingetragen haben, eine Pauschale von 250 vorgesehen ist. <!--
2132SELECT AVG(IFNULL(comm,250)) FROM emp;
2133--></li>
2134<li>Ermitteln Sie das geringste Gehalt (inklusive Provision). <!--
2135SELECT MIN(sal+IFNULL(comm,0)) FROM emp;
2136--></li>
2137<li>Ermitteln Sie 1) die Anzahl aller Mitarbeiter, 2) die Anzahl der Mitarbeiter, die ein Gehalt bekommen und 3) die Anzahl der Mitarbeiter, die eine Provision (von mindestens 0) bekommen. <!--
2138SELECT COUNT(*), COUNT(sal), COUNT(comm) FROM emp;
2139--></li>
2140<li>Ermitteln Sie die Anzahl der Vorgesetzten! Beachten Sie, dass die Analytiker FORD und SCOTT Vorgesetzte von SMITH und ADAMS sind. <!--
2141SELECT COUNT(DISTINCT mgr) FROM emp;
2142--></li>
2143<li>Ermitteln Sie die Durchschnittsgehälter je Job, wobei Personen mit Provisionszahlungen nicht berücksichtigt werden. <!--
2144SELECT job, AVG(sal) FROM emp WHERE comm IS NULL GROUP BY job;
2145--></li>
2146<li>Ermitteln Sie das Gesamt-Jahresgehalt (incl. Provision) je Abteilung! Die Mitarbeiter, bei denen keine Provision eingetragen ist, erhalten eine Ersatzzahlung in der Höhe von 100 USD/Monat. <!--
2147SELECT deptno, SUM(12*(sal + IFNULL(comm,100))) FROM emp GROUP BY deptno;
2148--></li>
2149<li>Ermitteln Sie die Jobs, deren Durchschnittsgehalt über 1500 USD liegt und sortieren Sie die Ausgabe nach Durchschnittseinkommen. <!--
2150SELECT job, AVG(sal) FROM emp GROUP BY job HAVING AVG(sal) > 1500 ORDER BY 2;
2151--></li>
2152<li>Ermitteln Sie alle Abteilungen mit mindestens 4 Angestellten. <!--
2153SELECT MIN(sal+IFNULL(comm,0)) FROM emp;
2154--></li>
2155<li>Ermitteln Sie alle Abteilungen mit mindestens 3 Verkäufern.</li>
2156<li>Ermitteln Sie den Mitarbeiter, der am meisten verdient.</li>
2157<li>Ermitteln Sie die Mitarbeiter, die in der Abteilung "New York" arbeiten.</li>
2158<li>Ermitteln Sie die Anzahl der Mitarbeiter in der Abteilung "New York".</li>
2159<li>Ermitteln Sie die Mitarbeiter, die mehr verdienen als ihr Vorgesetzter.</li>
2160<li>Ermitteln Sie die Mitarbeiter, die weniger als 30% vom Einkommen des Präsidenten verdienen.</li>
2161<li>Ermitteln Sie die Abteilungen ohne Mitarbeiter. <!--
2162Ermitteln Sie die Mitarbeiter, die mehr verdienen als der Durchschnitt ihrer Abteilung.
2163Ermitteln Sie die Mitarbeiter, die um mehr als 10 % mehr verdienen als der Durchschnitt ihres Jobs.
2164--></li>
2165</ol>
2166<h1 id="e.-datenbankdefinition-ddl-..."><span class="header-section-number">5</span> E. Datenbankdefinition (DDL) <a href="#TOC">...</a></h1>
2167<h2 id="constraints-..."><span class="header-section-number">5.1</span> Constraints <a href="#TOC">...</a></h2>
2168<p>Ein Kleinunternehmen hat sich dazu entschieden, ihre Angestellten- und Filialdaten in einer relationalen Datenbank zu verwalten. Dadurch kann das Unternehmen besonders einfach den Datenbestand auswerten.</p>
2169<pre><code> |DEPTNO| DNAME | LOC |
2170 | 10| ACCOUNTING| NEW YORK |
2171
2172
2173 |EMPNO| ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
2174 | 7782| CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
2175 | 7839| KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |</code></pre>
2176<hr />
2177<ol start="69" class="example" style="list-style-type: decimal">
2178<li><p>Erstellen Sie eine Tabelle für die Abteilungen eines Unternehmens.</p>
2179<ul>
2180<li>Wählen Sie sinnvolle Datentypen.</li>
2181<li>Definieren Sie die Primärschlüssel.</li>
2182</ul></li>
2183</ol>
2184<hr />
2185<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">DROP</span> <span class="kw">TABLE</span> <span class="kw">IF</span> <span class="kw">EXISTS</span> dept;
2186<span class="kw">CREATE</span> <span class="kw">TABLE</span> dept (
2187 deptno <span class="dt">INTEGER</span> <span class="kw">PRIMARY</span> <span class="kw">KEY</span>,
2188 dname TEXT <span class="kw">UNIQUE</span> <span class="kw">NOT</span> <span class="kw">NULL</span>,
2189 loc TEXT <span class="kw">NOT</span> <span class="kw">NULL</span>
2190);</code></pre></div>
2191<hr />
2192<hr />
2193<ol start="70" class="example" style="list-style-type: decimal">
2194<li><p>Erstellen Sie eine Tabelle für die Angestellten eines Unternehmens.</p>
2195<ul>
2196<li>"mgr" ist die empno des Vorgesetzten.</li>
2197<li>Gewährleisten Sie die referentielle Integrität.</li>
2198<li>Wählen Sie sinnvolle Datentypen.</li>
2199<li>Definieren Sie die Primärschlüssel.</li>
2200</ul></li>
2201</ol>
2202<hr />
2203<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">DROP</span> <span class="kw">TABLE</span> <span class="kw">IF</span> <span class="kw">EXISTS</span> emp;
2204<span class="kw">CREATE</span> <span class="kw">TABLE</span> emp(
2205 empno <span class="dt">INTEGER</span> <span class="kw">PRIMARY</span> <span class="kw">KEY</span>,
2206 ename TEXT <span class="kw">NOT</span> <span class="kw">NULL</span>,
2207 job TEXT,
2208 mgr <span class="dt">INT</span>,
2209 hiredate TEXT,
2210 sal <span class="dt">REAL</span>,
2211 comm <span class="dt">REAL</span>,
2212 deptno <span class="dt">INT</span>,
2213 <span class="kw">FOREIGN</span> <span class="kw">KEY</span>(mgr) <span class="kw">REFERENCES</span> emp (empno),
2214 <span class="kw">FOREIGN</span> <span class="kw">KEY</span>(deptno) <span class="kw">REFERENCES</span> dept (deptno)
2215);</code></pre></div>
2216<ul>
2217<li>Eine Tabelle entfernen: DROP TABLE table</li>
2218<li>Bei <code>DROP TABLE IF EXISTS</code> gibt es keine Fehlermeldung für den Fall, dass die Tabelle gar nicht mehr existiert.</li>
2219</ul>
2220<hr />
2221<hr />
2222<ol start="71" class="example" style="list-style-type: decimal">
2223<li>Nennen Sie eine andere Möglichkeit für die Klausel <code>PRIMARY KEY</code>.</li>
2224</ol>
2225<hr />
2226<p><code>PRIMARY KEY</code> entspricht den beiden Klauseln <code>UNIQUE</code> und <code>NOT NULL</code>.</p>
2227<hr />
2228<hr />
2229<ol start="72" class="example" style="list-style-type: decimal">
2230<li>Erläutern Sie die von SQLite verwendeten Datentypen.</li>
2231</ol>
2232<hr />
2233<ul>
2234<li>SQLite speichert die Daten nicht mit einem festen Datentyp je Tabellenspalte, sondern mit einer <strong>Datentyp-Affinität</strong>. Damit ist gemeint, dass eine Spalte zwar einen Datentyp darstellt, dieser aber nur ein Hinweis darauf ist, wie die gespeicherten Daten zu interpretieren sind. Tatsächlich dürfen alle möglichen Datentypen in einer Spalte gespeichert werden.</li>
2235<li>Folgende Affinitäten kennt SQLite:
2236<ul>
2237<li>INT(EGER)</li>
2238<li>REAL</li>
2239<li>NUMERIC bedeutet "INTEGER" oder "REAL"</li>
2240<li>TEXT Zeichenkette</li>
2241<li>BLOB (Binary Large Object) exakte Kopie des Inputs, zB Medien-Dateien</li>
2242</ul></li>
2243<li>Das Datum wird als TEXT im Format 'YYYY-MM-DD' gespeichert.</li>
2244</ul>
2245<hr />
2246<hr />
2247<ol start="73" class="example" style="list-style-type: decimal">
2248<li>Erläutern Sie die Foreign-Key-Klausel.</li>
2249</ol>
2250<hr />
2251<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">FOREIGN</span> <span class="kw">KEY</span> spalte, ...
2252 <span class="kw">REFERENCES</span> tabelle (spalte, ...)
2253 [<span class="kw">ON</span> <span class="kw">DELETE</span> {RESTRICT|CASCADE|SET <span class="kw">NULL</span>}]
2254 [<span class="kw">ON</span> <span class="kw">UPDATE</span> {RESTRICT|CASCADE|SET <span class="kw">NULL</span>}]</code></pre></div>
2255<ul>
2256<li>Bsp.: ON DELETE CASCADE bewirkt, dass das Löschen eines Datensatzes der Master-Tabelle alle zugehörigen Einträge in Detail-Tabelle entfernt.</li>
2257<li>ON DELETE RESTRICT verbietet das Ändern der betroffenen Spalten in der Master-Tabelle</li>
2258<li>SET NULL setzt die Fremdschlüssel auf NULL</li>
2259</ul>
2260<hr />
2261<hr />
2262<ol start="74" class="example" style="list-style-type: decimal">
2263<li>Beschreiben Sie die Begriffe Datenintegrität und referentielle Integrität.</li>
2264</ol>
2265<hr />
2266<ul>
2267<li>Datenintegrität ist die Korrektheit der gespeicherten Daten.</li>
2268<li>Die referentielle Integrität stellt sicher, daß alle Werte eines Attributes oder einer Attributkombination, das/die als Fremdschlüssel definiert ist, in einer anderen Relation (als Primärschlüssel) vorhanden ist.</li>
2269</ul>
2270<hr />
2271<hr />
2272<ol start="75" class="example" style="list-style-type: decimal">
2273<li>Erläutern Sie die Befehlsgruppe DDL.</li>
2274</ol>
2275<hr />
2276<p>Die DDL (Data Definition Language, Datenbeschreibungssprache) ist Sprache zum Erstellen und Verändern des konzeptuellen und externen Schemas. Damit erstellt man Tabellen und Views.</p>
2277<h2 id="views-collections-..."><span class="header-section-number">5.2</span> Views, Collections <a href="#TOC">...</a></h2>
2278<ol start="76" class="example" style="list-style-type: decimal">
2279<li>Erläutern Sie den Begriff "View".</li>
2280</ol>
2281<hr />
2282<ul>
2283<li>Eine Sicht ist genau genommen nichts weiter als eine <strong>gespeicherte Abfrage</strong>.</li>
2284<li>Diese gespeicherte Abfrage wird <strong>wie eine Tabelle behandelt</strong>. Sie kann genau wie eine Tabelle abgefragt werden.</li>
2285<li>Selbst <strong>DML-Statements</strong> (INSERT, UPDATE, DELETE) sind unter bestimmten Umständen möglich. Dies hängt von der gespeicherten Abfrage ab. In SQLite ist das allerdings nicht möglich</li>
2286</ul>
2287<p><strong>Views anlegen</strong>: <code>CREATE [TEMP[ORARY]] VIEW [IF NOT EXISTS] <viewname> AS <select-stmt></code></p>
2288<p><strong>Views löschen</strong>: <code>DROP VIEW [IF EXISTS] <viewname></code></p>
2289<p>Der eigentliche Nutzen einer Sicht ist das <strong>Verstecken</strong> einer recht komplizierten und umfangreichen Abfrage. So ist es einfacher, alle Datensätze der Sicht <code>research_mitarbeiter</code> abzufragen als sich die Abfrage, welche alle Research-Mitarbeiter ermittelt, zu schreiben und anschließend auszuführen.</p>
2290<hr />
2291<hr />
2292<ol start="77" class="example" style="list-style-type: decimal">
2293<li>Erstellen Sie ein View "dept_sal" für das Minimal- und das Durchschnittsgehalt jeder Abteilung. Die Gehälter der Führungskräfte (Manager, Präsident) werden dabei nicht berücksichtigt.</li>
2294</ol>
2295<hr />
2296<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">CREATE</span> <span class="kw">VIEW</span> dept_sal <span class="kw">AS</span>
2297<span class="kw">SELECT</span> deptno, <span class="fu">MIN</span>(sal), <span class="fu">AVG</span>(sal) <span class="kw">FROM</span> emp
2298<span class="kw">WHERE</span> job <span class="kw">NOT</span> <span class="kw">IN</span> (<span class="st">'MANAGER'</span>, <span class="st">'PRESIDENT'</span>) <span class="kw">GROUP</span> <span class="kw">BY</span> deptno;</code></pre></div>
2299<hr />
2300<hr />
2301<ol start="78" class="example" style="list-style-type: decimal">
2302<li>Erklären Sie das Konzept von Ebenenmodellen.</li>
2303</ol>
2304<hr />
2305<p><strong>Datenunabhängigkeit</strong> bewirkt: Die Änderung der logischen und physischen Struktur der Daten erfordert keine Änderung der Anwendungsprogramme.</p>
2306<p><strong>Physische Datenunabhängigkeit</strong> betrifft die physischen Organisation der Daten (Dateien, Feldlängen, ...).</p>
2307<p><strong>Logische Datenunabhängigkeit</strong>: Die logische Sicht eines Programms auf die benutzten Daten soll von der logischen Gesamtsicht auf alle Daten unabhängig sein. Neue Felder, neue Beziehungen, ... sollen keine Änderung der Anwendungsprogramme bewirken.</p>
2308<p>Die Realisierung physischer und logischer Datenunabhängigkeit macht eine Betrachtung der gespeicherten Daten in mindestens drei verschiedenen <strong>Abstraktionsebenen</strong> erforderlich:</p>
2309<ul>
2310<li>die <strong>interne</strong> Datensicht (physische Datenorganisation; tatsächliche Speicherung der Daten),</li>
2311<li>die <strong>konzeptionelle</strong> Datensicht (logische Gesamtsicht aller Daten)</li>
2312<li>die <strong>externen</strong> Datensichten (logische Sichten von Applikationen auf Teile der Datenbank). Sie umfassen individuelle Sichten (=Views) der einzelnen Benutzergruppen. Eine <strong>View</strong> enthält nur den Ausschnitt dem konzeptionellen Schema, die der Anwender sehen möchte.</li>
2313</ul>
2314<p>Die Beschreibungen der 3 Datensichten erfolgen durch das</p>
2315<ul>
2316<li>interne Schema</li>
2317<li>konzeptionelle Schema</li>
2318<li>externe Schema</li>
2319</ul>
2320<p>Ein <strong>Schema</strong> ist eine in einer Datenbeschreibungssprache (=DDL) abgefaßte Definition der in einer Datenbank zugelassenen Datenstrukturen.</p>
2321<p><strong>Beispiel:</strong></p>
2322<p>Konzeptionelles Schema: Kursbuch der Deutschen Bundesbahn.</p>
2323<p>Verschiedene externe Schemata:</p>
2324<ul>
2325<li>Fahrplan der IC-Züge zwischen den Großstädten der BRD</li>
2326<li>Innerhalb einer Großstadt die Vorortverbindungen</li>
2327<li>Externe Datensicht des Reisenden: Abfahrt und Ankunft von einigen Anschlußzügen</li>
2328</ul>
2329<hr />
2330<hr />
2331<ol start="79" class="example" style="list-style-type: decimal">
2332<li>Vergleichen Sie MongoDB mit dem SQL-Strukturen: Datenbank, Tabelle, Datensatz.</li>
2333</ol>
2334<hr />
2335<p><em>Abbildung 3: Vergleich MongoDB – SQL-Schema</em></p>
2336<dl>
2337<dt>.</dt>
2338<dd><img src="/home/user/acha/www-img/mongodb/volke-5_1.png" /> .
2339</dd>
2340<dd><img src="/home/user/acha/www-img/mongodb/volke-5_2.png" />
2341</dd>
2342</dl>
2343<p>Dokumente werden in Collections zusammengefasst. Eine <strong>Collection</strong> ist eine benannte Menge von Dokumenten.</p>
2344<p>Jede Collection ist in einer <strong>Datenbank</strong> gespeichert und jedes MongoDB-System enthält eine Menge von Datenbanken.</p>
2345<p>Dadurch ergibt sich eine gewisse Ähnlichkeit zu der Strukturierung in relationalen Datenbankensystemen (siehe Abbildung 3).</p>
2346<p>Auch in letzteren sind die Daten in Datenbanken gespeichert, die wiederum Tabellen enthalten. Diese Tabellen entsprechen in etwa den Collections in MongoDB.</p>
2347<p>Innerhalb einer Tabelle sind die Datensätze als Zeilen gespeichert, wobei jede Zeile ein Tupel aus einem oder mehreren Werten ist.</p>
2348<p>Dies entspricht in MongoDB einem Dokument als Sammlung von Schlüssel-Werte-Paaren.</p>
2349<p>In einem RDBMS unterliegt aber die Tabelle einem Schema, sodass alle Zeilen der Tabelle den gleichen Aufbau haben, d.h. die gleiche Anzahl von Werten mit jeweils den gleichen Datentypen.</p>
2350<p>In MongoDB unterliegen die Dokumente keinem festen Schema, sondern jedes Dokument hat seine eigene Strukturierung.</p>
2351<p>Die Dokumente einer Collection können Ähnlichkeiten aufweisen, müssen es aber nicht.</p>
2352<h1 id="f.-datenbankmanipulation-dml-..."><span class="header-section-number">6</span> F. Datenbankmanipulation (DML) <a href="#TOC">...</a></h1>
2353<h2 id="grundlagen-..."><span class="header-section-number">6.1</span> Grundlagen <a href="#TOC">...</a></h2>
2354<p>Ein Kleinunternehmen hat sich dazu entschieden, ihre Angestellten- und Filialdaten in einer relationalen Datenbank zu verwalten. Dadurch kann das Unternehmen besonders einfach den Datenbestand auswerten.</p>
2355<pre><code> |DEPTNO| DNAME | LOC |
2356 | 10| ACCOUNTING| NEW YORK |
2357
2358
2359 |EMPNO| ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
2360 | 7782| CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
2361 | 7839| KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |</code></pre>
2362<hr />
2363<ol start="80" class="example" style="list-style-type: decimal">
2364<li>Erstellen Sie ein Insert-Statement für die erste Abteilung und den ersten Angestellten!</li>
2365</ol>
2366<hr />
2367<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">INSERT</span> <span class="kw">INTO</span> dept <span class="kw">VALUES</span>(<span class="dv">10</span>,<span class="st">'ACCOUNTING'</span>,<span class="st">'NEW YORK'</span>);
2368<span class="kw">INSERT</span> <span class="kw">INTO</span> dept <span class="kw">VALUES</span>(<span class="dv">20</span>,<span class="st">'RESEARCH'</span>,<span class="st">'DALLAS'</span>);
2369<span class="kw">INSERT</span> <span class="kw">INTO</span> dept <span class="kw">VALUES</span>(<span class="dv">30</span>,<span class="st">'SALES'</span>,<span class="st">'CHICAGO'</span>);
2370<span class="kw">INSERT</span> <span class="kw">INTO</span> dept <span class="kw">VALUES</span>(<span class="dv">40</span>,<span class="st">'OPERATIONS'</span>,<span class="st">'BOSTON'</span>);
2371
2372<span class="kw">INSERT</span> <span class="kw">INTO</span> emp <span class="kw">VALUES</span>(<span class="dv">7369</span>,<span class="st">'SMITH'</span>,<span class="st">'CLERK'</span>,<span class="dv">7902</span>,<span class="st">'1980-12-17'</span>,<span class="fl">800.0</span>,<span class="kw">NULL</span>,<span class="dv">20</span>);
2373<span class="kw">INSERT</span> <span class="kw">INTO</span> emp <span class="kw">VALUES</span>(<span class="dv">7499</span>,<span class="st">'ALLEN'</span>,<span class="st">'SALESMAN'</span>,<span class="dv">7698</span>,<span class="st">'1981-02-20'</span>,<span class="fl">1600.0</span>,<span class="fl">300.0</span>,<span class="dv">30</span>);
2374<span class="kw">INSERT</span> <span class="kw">INTO</span> emp <span class="kw">VALUES</span>(<span class="dv">7521</span>,<span class="st">'WARD'</span>,<span class="st">'SALESMAN'</span>,<span class="dv">7698</span>,<span class="st">'1981-02-22'</span>,<span class="fl">1250.0</span>,<span class="fl">500.0</span>,<span class="dv">30</span>);
2375<span class="kw">INSERT</span> <span class="kw">INTO</span> emp <span class="kw">VALUES</span>(<span class="dv">7566</span>,<span class="st">'JONES'</span>,<span class="st">'MANAGER'</span>,<span class="dv">7839</span>,<span class="st">'1981-04-02'</span>,<span class="fl">2975.0</span>,<span class="kw">NULL</span>,<span class="dv">20</span>);
2376<span class="kw">INSERT</span> <span class="kw">INTO</span> emp <span class="kw">VALUES</span>(<span class="dv">7654</span>,<span class="st">'MARTIN'</span>,<span class="st">'SALESMAN'</span>,<span class="dv">7698</span>,<span class="st">'1981-09-28'</span>,<span class="fl">1250.0</span>,<span class="fl">1400.0</span>,<span class="dv">30</span>);
2377<span class="kw">INSERT</span> <span class="kw">INTO</span> emp <span class="kw">VALUES</span>(<span class="dv">7698</span>,<span class="st">'BLAKE'</span>,<span class="st">'MANAGER'</span>,<span class="dv">7839</span>,<span class="st">'1981-05-01'</span>,<span class="fl">2850.0</span>,<span class="kw">NULL</span>,<span class="dv">30</span>);
2378<span class="kw">INSERT</span> <span class="kw">INTO</span> emp <span class="kw">VALUES</span>(<span class="dv">7782</span>,<span class="st">'CLARK'</span>,<span class="st">'MANAGER'</span>,<span class="dv">7839</span>,<span class="st">'1981-06-09'</span>,<span class="fl">2450.0</span>,<span class="kw">NULL</span>,<span class="dv">10</span>);
2379<span class="kw">INSERT</span> <span class="kw">INTO</span> emp <span class="kw">VALUES</span>(<span class="dv">7788</span>,<span class="st">'SCOTT'</span>,<span class="st">'ANALYST'</span>,<span class="dv">7566</span>,<span class="st">'1982-12-09'</span>,<span class="fl">3000.0</span>,<span class="kw">NULL</span>,<span class="dv">20</span>);
2380<span class="kw">INSERT</span> <span class="kw">INTO</span> emp <span class="kw">VALUES</span>(<span class="dv">7839</span>,<span class="st">'KING'</span>,<span class="st">'PRESIDENT'</span>,<span class="kw">NULL</span>,<span class="st">'1981-11-17'</span>,<span class="fl">5000.0</span>,<span class="kw">NULL</span>,<span class="dv">10</span>);
2381<span class="kw">INSERT</span> <span class="kw">INTO</span> emp <span class="kw">VALUES</span>(<span class="dv">7844</span>,<span class="st">'TURNER'</span>,<span class="st">'SALESMAN'</span>,<span class="dv">7698</span>,<span class="st">'1981-09-08'</span>,<span class="fl">1500.0</span>,<span class="fl">0.0</span>,<span class="dv">30</span>);
2382<span class="kw">INSERT</span> <span class="kw">INTO</span> emp <span class="kw">VALUES</span>(<span class="dv">7876</span>,<span class="st">'ADAMS'</span>,<span class="st">'CLERK'</span>,<span class="dv">7788</span>,<span class="st">'1983-01-12'</span>,<span class="fl">1100.0</span>,<span class="kw">NULL</span>,<span class="dv">20</span>);
2383<span class="kw">INSERT</span> <span class="kw">INTO</span> emp <span class="kw">VALUES</span>(<span class="dv">7900</span>,<span class="st">'JAMES'</span>,<span class="st">'CLERK'</span>,<span class="dv">7698</span>,<span class="st">'1981-12-03'</span>,<span class="fl">950.0</span>,<span class="kw">NULL</span>,<span class="dv">30</span>);
2384<span class="kw">INSERT</span> <span class="kw">INTO</span> emp <span class="kw">VALUES</span>(<span class="dv">7902</span>,<span class="st">'FORD'</span>,<span class="st">'ANALYST'</span>,<span class="dv">7566</span>,<span class="st">'1981-12-03'</span>,<span class="fl">3000.0</span>,<span class="kw">NULL</span>,<span class="dv">20</span>);
2385<span class="kw">INSERT</span> <span class="kw">INTO</span> emp <span class="kw">VALUES</span>(<span class="dv">7934</span>,<span class="st">'MILLER'</span>,<span class="st">'CLERK'</span>,<span class="dv">7782</span>,<span class="st">'1982-01-23'</span>,<span class="fl">1300.0</span>,<span class="kw">NULL</span>,<span class="dv">10</span>);</code></pre></div>
2386<hr />
2387<hr />
2388<ol start="81" class="example" style="list-style-type: decimal">
2389<li>Erhöhen Sie das Gehalt des dienstältesten Mitarbeiters um 10%.</li>
2390</ol>
2391<hr />
2392<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">UPDATE</span> emp <span class="kw">SET</span> sal = sal*<span class="fl">1.1</span> <span class="kw">WHERE</span> hiredate = (<span class="kw">SELECT</span> <span class="fu">MIN</span>(hiredate) <span class="kw">from</span> emp);</code></pre></div>
2393<hr />
2394<hr />
2395<ol start="82" class="example" style="list-style-type: decimal">
2396<li>Erläutern Sie die Befehlsgruppe DML.</li>
2397</ol>
2398<hr />
2399<p>Die Befehlsgruppe <strong>DML (=Data Manipulation Language)</strong></p>
2400<ul>
2401<li>fügt Daten ein (<strong>INSERT</strong>)</li>
2402<li>ändert Daten (<strong>UPDATE</strong>)</li>
2403<li>löscht Daten (<strong>DELETE</strong>)</li>
2404</ul>
2405<p><strong>INSERT</strong></p>
2406<ul>
2407<li>Datensatz einfügen: <code>INSERT INTO tabelle VALUES (wert, ...);</code></li>
2408<li>oder: <code>INSERT INTO tabelle SELECT ...</code></li>
2409<li>Bsp: <code>INSERT INTO dept VALUES(10,'ACCOUNTING','NEW YORK');</code></li>
2410<li>Der Wert NULL bedeutet, dass kein Wert vorhanden ist.</li>
2411</ul>
2412<p><strong>UPDATE</strong></p>
2413<ul>
2414<li>Daten ändern <code>UPDATE tabelle SET spalte = wert, ... WHERE ...;</code></li>
2415<li>Bsp: <code>UPDATE emp SET sal = sal*1.1 WHERE job = 'SALESMAN';</code></li>
2416<li>Fehlt die WHERE-Bedingung, so werden alle Datensätze geändert.</li>
2417</ul>
2418<p><strong>DELETE</strong></p>
2419<ul>
2420<li>Daten löschen: <code>DELETE FROM tabelle WHERE ...</code></li>
2421<li>Bsp: <code>DELETE FROM emp where job = 'SALESMAN';</code></li>
2422<li>Fehlt die WHERE-Bedingung, so werden alle Datensätze gelöscht.</li>
2423</ul>
2424<hr />
2425<hr />
2426<ol start="83" class="example" style="list-style-type: decimal">
2427<li>Erläutern Sie den Begriff "Dokument" in MongoDB.</li>
2428</ol>
2429<hr />
2430<ul>
2431<li>Ein <em>Dokument</em> ist ein einzelner Datensatz, der im Prinzip aus einer geordneten Liste von Key-Value-Paaren besteht und als Werte auch Arrays und eingebettete Dokumente zulässt.</li>
2432<li>Ein Dokument kann man gut im JSON-Format darstellen.</li>
2433<li>Zur Speicherung verwendet MongoDB intern allerdings nicht das JSON-Format, sondern eine Abwandlung davon.</li>
2434<li>Mit diesem Datenformat adressiert MongoDB den Big-Data-Aspekt <em>Variety</em>: Ein Dokument eignet sich hervorragend zum Umgang mit semistrukturierten Daten, z. B. komplexen Vererbungshierarchien in OO-Sprachen.</li>
2435</ul>
2436<p><strong>Bsp</strong></p>
2437<pre class=".javascript"><code>{
2438 "name": "MongoDB",
2439 versionen: [
2440 { "major": 2, "minor": 6 },
2441 { "major": 2, "minor": 4 },
2442 { "major": 2, "minor": 2 }
2443 ]
2444}</code></pre>
2445<hr />
2446<hr />
2447<ol start="84" class="example" style="list-style-type: decimal">
2448<li>Erläutern Sie den Aufbau eines Dokuments in MongoDB!<br> Nennen Sie zulässige Datentypen!</li>
2449</ol>
2450<hr />
2451<p>Als Dokumenten-Datenbank bildet in MongoDB das Dokument einen zentralen Bestandteil des Datenmodells.</p>
2452<p>Ein Dokument ist im wesentlichen eine Sammlung von zusammengehörigen Daten.</p>
2453<p>In MongoDB ist ein <strong>Dokument</strong> einfach eine Menge von Feldern, wobei ein <strong>Feld</strong> ein Schlüssel-Wert-Paar ist.</p>
2454<p>Der Schlüssel ist gleichzeitig der Name des Feldes und wird als String repräsentiert.</p>
2455<p>Der Wert kann ein</p>
2456<ul>
2457<li><strong>primitiver Datentyp</strong> sein,</li>
2458<li>eine <strong>Liste</strong> von Werten oder ein</li>
2459<li><strong>Dokument</strong>.</li>
2460</ul>
2461<p>Das bedeutet insbesondere, dass jedes Dokument Subdokumente enthalten kann.</p>
2462<p>Die primitiven Datentypen sind die üblicherweise verfügbaren</p>
2463<ul>
2464<li>Boolean,</li>
2465<li>Integer,</li>
2466<li>Float</li>
2467<li>String.</li>
2468</ul>
2469<p>Die Schlüssel-Namen unterliegen fast keinen Einschränkungen.</p>
2470<p>MongoDB verbietet allerdings Bezeichner, die mit einem „$“ beginnen oder einen Punkt enthalten, da solche für die MongoDB-eigene Query-Sprache verwendet werden.</p>
2471<div class="sourceCode"><pre class="sourceCode json"><code class="sourceCode json"><span class="fu">{</span>
2472 <span class="er">boolValue</span> <span class="fu">:</span> <span class="kw">true</span><span class="fu">,</span>
2473 <span class="er">_id</span> <span class="fu">:</span> <span class="st">"eindeutige_ID_12351asd"</span><span class="fu">,</span>
2474 <span class="er">array</span> <span class="fu">:</span> <span class="ot">[</span> <span class="kw">true</span><span class="ot">,</span> <span class="st">"value2"</span><span class="ot">,</span> <span class="dv">3</span><span class="ot">,</span> <span class="ot">[</span><span class="dv">1</span><span class="ot">,</span><span class="dv">2</span><span class="ot">,</span><span class="dv">3</span><span class="ot">]</span> <span class="ot">]</span><span class="fu">,</span>
2475 <span class="er">object</span> <span class="fu">:</span> <span class="fu">{</span>
2476 <span class="er">name1</span> <span class="fu">:</span> <span class="st">"value1"</span><span class="fu">,</span>
2477 <span class="er">name2</span> <span class="fu">:</span> <span class="st">"value2"</span>
2478 <span class="fu">}</span>
2479 <span class="er">string</span> <span class="er">:</span> <span class="st">"value"</span>
2480<span class="fu">}</span></code></pre></div>
2481<p><em>Abbildung 2: Beispiel-Dokument</em></p>
2482<p>Des weiteren gibt es eine besonderes Feld, das jedes Dokument aufweist: das <strong>„_id“-Feld</strong> enthält einen innerhalb der Collection (siehe unten) eindeutigen Wert, der als Primärschlüssel verwendet wird.</p>
2483<p>In MongoDB werden Dokumente als BSON-Objekte dargestellt, also mithilfe einer speichereffizienten, binären Variante von JSON.</p>
2484<p>Eine wichtige Einschränkung ist die maximale Dokumentgröße von 16MB. Diese hat keine technischen Gründe, sondern dient mehr als eine Art Konsistenz-Check. Wenn Dokumente diese Datenmenge überschreiten, spricht das für eine schlechte Datenmodellierung.</p>
2485<hr />
2486<hr />
2487<ol start="85" class="example" style="list-style-type: decimal">
2488<li>Erstellen Sie die Collections für die Abteilungen und Angestellten eines Unternehmens.<br> Erstellen Sie ein Dokument für die erste Abteilung und den ersten Angestellten!</li>
2489</ol>
2490<hr />
2491<div class="sourceCode"><pre class="sourceCode js"><code class="sourceCode javascript"><span class="va">db</span>.<span class="va">dept</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">10</span><span class="op">,</span> <span class="dt">dname</span><span class="op">:</span><span class="st">"ACCOUNTING"</span><span class="op">,</span> <span class="dt">loc</span><span class="op">:</span><span class="st">"NEW YORK"</span><span class="op">}</span>)<span class="op">;</span>
2492<span class="va">db</span>.<span class="va">dept</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">20</span><span class="op">,</span> <span class="dt">dname</span><span class="op">:</span><span class="st">"RESEARCH"</span><span class="op">,</span> <span class="dt">loc</span><span class="op">:</span><span class="st">"DALLAS"</span><span class="op">}</span>)<span class="op">;</span>
2493<span class="va">db</span>.<span class="va">dept</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">30</span><span class="op">,</span> <span class="dt">dname</span><span class="op">:</span><span class="st">"SALES"</span><span class="op">,</span> <span class="dt">loc</span><span class="op">:</span><span class="st">"CHICAGO"</span><span class="op">}</span>)<span class="op">;</span>
2494<span class="va">db</span>.<span class="va">dept</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">40</span><span class="op">,</span> <span class="dt">dname</span><span class="op">:</span><span class="st">"OPERATIONS"</span><span class="op">,</span> <span class="dt">loc</span><span class="op">:</span><span class="st">"BOSTON"</span><span class="op">}</span>)<span class="op">;</span>
2495
2496
2497<span class="va">db</span>.<span class="va">emp</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">7369</span><span class="op">,</span> <span class="dt">ename</span><span class="op">:</span><span class="st">"SMITH"</span><span class="op">,</span> <span class="dt">job</span><span class="op">:</span><span class="st">"CLERK"</span><span class="op">,</span> <span class="dt">mgr</span><span class="op">:</span><span class="dv">7902</span><span class="op">,</span> <span class="dt">hiredate</span><span class="op">:</span><span class="st">"1980-12-17"</span><span class="op">,</span> <span class="dt">sal</span><span class="op">:</span><span class="dv">800</span> <span class="op">,</span><span class="dt">deptno</span><span class="op">:</span><span class="dv">20</span><span class="op">}</span>)<span class="op">;</span>
2498<span class="va">db</span>.<span class="va">emp</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">7499</span><span class="op">,</span> <span class="dt">ename</span><span class="op">:</span><span class="st">"ALLEN"</span><span class="op">,</span> <span class="dt">job</span><span class="op">:</span><span class="st">"SALESMAN"</span><span class="op">,</span> <span class="dt">mgr</span><span class="op">:</span><span class="dv">7698</span><span class="op">,</span> <span class="dt">hiredate</span><span class="op">:</span><span class="st">"1981-02-20"</span><span class="op">,</span> <span class="dt">sal</span><span class="op">:</span><span class="dv">1600</span><span class="op">,</span> <span class="dt">comm</span><span class="op">:</span><span class="dv">300</span><span class="op">,</span> <span class="dt">deptno</span><span class="op">:</span><span class="dv">30</span><span class="op">}</span>)<span class="op">;</span>
2499<span class="va">db</span>.<span class="va">emp</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">7521</span><span class="op">,</span> <span class="dt">ename</span><span class="op">:</span><span class="st">"WARD"</span><span class="op">,</span> <span class="dt">job</span><span class="op">:</span><span class="st">"SALESMAN"</span><span class="op">,</span> <span class="dt">mgr</span><span class="op">:</span><span class="dv">7698</span><span class="op">,</span> <span class="dt">hiredate</span><span class="op">:</span><span class="st">"1981-02-22"</span><span class="op">,</span> <span class="dt">sal</span><span class="op">:</span><span class="dv">1250</span><span class="op">,</span> <span class="dt">comm</span><span class="op">:</span><span class="dv">500</span><span class="op">,</span> <span class="dt">deptno</span><span class="op">:</span><span class="dv">30</span><span class="op">}</span>)<span class="op">;</span>
2500<span class="va">db</span>.<span class="va">emp</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">7566</span><span class="op">,</span> <span class="dt">ename</span><span class="op">:</span><span class="st">"JONES"</span><span class="op">,</span> <span class="dt">job</span><span class="op">:</span><span class="st">"MANAGER"</span><span class="op">,</span> <span class="dt">mgr</span><span class="op">:</span><span class="dv">7839</span><span class="op">,</span> <span class="dt">hiredate</span><span class="op">:</span><span class="st">"1981-04-02"</span><span class="op">,</span> <span class="dt">sal</span><span class="op">:</span><span class="dv">2975</span><span class="op">,</span> <span class="dt">deptno</span><span class="op">:</span><span class="dv">20</span><span class="op">}</span>)<span class="op">;</span>
2501<span class="va">db</span>.<span class="va">emp</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">7654</span><span class="op">,</span> <span class="dt">ename</span><span class="op">:</span><span class="st">"MARTIN"</span><span class="op">,</span> <span class="dt">job</span><span class="op">:</span><span class="st">"SALESMAN"</span><span class="op">,</span> <span class="dt">mgr</span><span class="op">:</span><span class="dv">7698</span><span class="op">,</span> <span class="dt">hiredate</span><span class="op">:</span><span class="st">"1981-09-28"</span><span class="op">,</span> <span class="dt">sal</span><span class="op">:</span><span class="dv">1250</span><span class="op">,</span> <span class="dt">comm</span><span class="op">:</span><span class="dv">1400</span><span class="op">,</span> <span class="dt">deptno</span><span class="op">:</span><span class="dv">30</span><span class="op">}</span>)<span class="op">;</span>
2502<span class="va">db</span>.<span class="va">emp</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">7698</span><span class="op">,</span> <span class="dt">ename</span><span class="op">:</span><span class="st">"BLAKE"</span><span class="op">,</span> <span class="dt">job</span><span class="op">:</span><span class="st">"MANAGER"</span><span class="op">,</span> <span class="dt">mgr</span><span class="op">:</span><span class="dv">7839</span><span class="op">,</span> <span class="dt">hiredate</span><span class="op">:</span><span class="st">"1981-05-01"</span><span class="op">,</span> <span class="dt">sal</span><span class="op">:</span><span class="dv">2850</span><span class="op">,</span> <span class="dt">deptno</span><span class="op">:</span><span class="dv">30</span><span class="op">}</span>)<span class="op">;</span>
2503<span class="va">db</span>.<span class="va">emp</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">7782</span><span class="op">,</span> <span class="dt">ename</span><span class="op">:</span><span class="st">"CLARK"</span><span class="op">,</span> <span class="dt">job</span><span class="op">:</span><span class="st">"MANAGER"</span><span class="op">,</span> <span class="dt">mgr</span><span class="op">:</span><span class="dv">7839</span><span class="op">,</span> <span class="dt">hiredate</span><span class="op">:</span><span class="st">"1981-06-09"</span><span class="op">,</span> <span class="dt">sal</span><span class="op">:</span><span class="dv">2450</span><span class="op">,</span> <span class="dt">deptno</span><span class="op">:</span><span class="dv">10</span><span class="op">}</span>)<span class="op">;</span>
2504<span class="va">db</span>.<span class="va">emp</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">7788</span><span class="op">,</span> <span class="dt">ename</span><span class="op">:</span><span class="st">"SCOTT"</span><span class="op">,</span> <span class="dt">job</span><span class="op">:</span><span class="st">"ANALYST"</span><span class="op">,</span> <span class="dt">mgr</span><span class="op">:</span><span class="dv">7566</span><span class="op">,</span> <span class="dt">hiredate</span><span class="op">:</span><span class="st">"1982-12-09"</span><span class="op">,</span> <span class="dt">sal</span><span class="op">:</span><span class="dv">3000</span><span class="op">,</span> <span class="dt">deptno</span><span class="op">:</span><span class="dv">20</span><span class="op">}</span>)<span class="op">;</span>
2505<span class="va">db</span>.<span class="va">emp</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">7839</span><span class="op">,</span> <span class="dt">ename</span><span class="op">:</span><span class="st">"KING"</span><span class="op">,</span> <span class="dt">job</span><span class="op">:</span><span class="st">"PRESIDENT"</span><span class="op">,</span> <span class="dt">hiredate</span><span class="op">:</span><span class="st">"1981-11-17"</span><span class="op">,</span> <span class="dt">sal</span><span class="op">:</span><span class="dv">5000</span><span class="op">,</span> <span class="dt">deptno</span><span class="op">:</span><span class="dv">10</span><span class="op">}</span>)<span class="op">;</span>
2506<span class="va">db</span>.<span class="va">emp</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">7844</span><span class="op">,</span> <span class="dt">ename</span><span class="op">:</span><span class="st">"TURNER"</span><span class="op">,</span> <span class="dt">job</span><span class="op">:</span><span class="st">"SALESMAN"</span><span class="op">,</span> <span class="dt">mgr</span><span class="op">:</span><span class="dv">7698</span><span class="op">,</span> <span class="dt">hiredate</span><span class="op">:</span><span class="st">"1981-09-08"</span><span class="op">,</span> <span class="dt">sal</span><span class="op">:</span><span class="dv">1500</span><span class="op">,</span> <span class="dt">comm</span><span class="op">:</span><span class="dv">0</span><span class="op">,</span> <span class="dt">deptno</span><span class="op">:</span><span class="dv">30</span><span class="op">}</span>)<span class="op">;</span>
2507<span class="va">db</span>.<span class="va">emp</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">7876</span><span class="op">,</span> <span class="dt">ename</span><span class="op">:</span><span class="st">"ADAMS"</span><span class="op">,</span> <span class="dt">job</span><span class="op">:</span><span class="st">"CLERK"</span><span class="op">,</span> <span class="dt">mgr</span><span class="op">:</span><span class="dv">7788</span><span class="op">,</span> <span class="dt">hiredate</span><span class="op">:</span><span class="st">"1983-01-12"</span><span class="op">,</span> <span class="dt">sal</span><span class="op">:</span><span class="dv">1100</span><span class="op">,</span> <span class="dt">deptno</span><span class="op">:</span><span class="dv">20</span><span class="op">}</span>)<span class="op">;</span>
2508<span class="va">db</span>.<span class="va">emp</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">7900</span><span class="op">,</span> <span class="dt">ename</span><span class="op">:</span><span class="st">"JAMES"</span><span class="op">,</span> <span class="dt">job</span><span class="op">:</span><span class="st">"CLERK"</span><span class="op">,</span> <span class="dt">mgr</span><span class="op">:</span><span class="dv">7698</span><span class="op">,</span> <span class="dt">hiredate</span><span class="op">:</span><span class="st">"1981-12-03"</span><span class="op">,</span> <span class="dt">sal</span><span class="op">:</span><span class="dv">950</span><span class="op">,</span> <span class="dt">deptno</span><span class="op">:</span><span class="dv">30</span><span class="op">}</span>)<span class="op">;</span>
2509<span class="va">db</span>.<span class="va">emp</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">7902</span><span class="op">,</span> <span class="dt">ename</span><span class="op">:</span><span class="st">"FORD"</span><span class="op">,</span> <span class="dt">job</span><span class="op">:</span><span class="st">"ANALYST"</span><span class="op">,</span> <span class="dt">mgr</span><span class="op">:</span><span class="dv">7566</span><span class="op">,</span> <span class="dt">hiredate</span><span class="op">:</span><span class="st">"1981-12-03"</span><span class="op">,</span> <span class="dt">sal</span><span class="op">:</span><span class="dv">3000</span><span class="op">,</span> <span class="dt">deptno</span><span class="op">:</span><span class="dv">20</span><span class="op">}</span>)<span class="op">;</span>
2510<span class="va">db</span>.<span class="va">emp</span>.<span class="at">insert</span>(<span class="op">{</span><span class="dt">_id</span><span class="op">:</span><span class="dv">7934</span><span class="op">,</span> <span class="dt">ename</span><span class="op">:</span><span class="st">"MILLER"</span><span class="op">,</span> <span class="dt">job</span><span class="op">:</span><span class="st">"CLERK"</span><span class="op">,</span> <span class="dt">mgr</span><span class="op">:</span><span class="dv">7782</span><span class="op">,</span> <span class="dt">hiredate</span><span class="op">:</span><span class="st">"1982-01-23"</span><span class="op">,</span> <span class="dt">sal</span><span class="op">:</span><span class="dv">1300</span><span class="op">,</span> <span class="dt">deptno</span><span class="op">:</span><span class="dv">10</span><span class="op">}</span>)<span class="op">;</span></code></pre></div>
2511<h2 id="dml-mongodb-..."><span class="header-section-number">6.2</span> DML MongoDB <a href="#TOC">...</a></h2>
2512<ol start="86" class="example" style="list-style-type: decimal">
2513<li><p>Der Datenbankadministrator möchte mehrere Angestellte in die Datenbank einfügen. Er möchte dabei gewährleisten, dass die referentielle Integrität auch bei Netzwerk- oder Serverfehlern nicht verletzt wird.</p>
2514<pre><code>{_id:7839, ename:"KING", job:"PRESIDENT", hiredate:"1981-11-17", sal:5000, deptno:10}
2515{_id:7566, ename:"JONES", job:"MANAGER", mgr:7839, hiredate:"1981-04-02", sal:2975, deptno:20}
2516{_id:7698, ename:"BLAKE", job:"MANAGER", mgr:7839, hiredate:"1981-05-01", sal:2850, deptno:30}</code></pre></li>
2517</ol>
2518<hr />
2519<pre><code> db.emp.insert( [ {_id:7839, ename:"KING", ...}, {_id:7566, ename:"JONES", ...}, ... ] )</code></pre>
2520<ol style="list-style-type: decimal">
2521<li>Wenn Sie mehrere Dokumente in einem Rutsch einfügen wollen, bietet es sich an, einen sogenannten <strong>Bulk-Insert</strong> zu verwenden, da dieser das Netzwerk deutlich weniger belastet.</li>
2522<li>In der Mongo Shell kann man mehrere Dokumente einfügen, indem man beim Aufruf von insert() ein Array von Dokumenten übergibt.</li>
2523<li>Falls beim Einfügen mehrerer Dokumente ein Fehler auftritt, findet ein <strong>Abbruch</strong> statt und die nachfolgenden Dokumente werden nicht mehr eingefügt.</li>
2524<li>Allerdings ist es möglich, über den Treiber eine Option continueOnError anzugeben, die bei Fehlern nicht abbricht, sondern mit dem Einfügen weiterer Dokumente fortfährt.</li>
2525</ol>
2526<hr />
2527<hr />
2528<ol start="87" class="example" style="list-style-type: decimal">
2529<li>Erläutern Sie die Besonderheiten des INSERT-Kommandos!</li>
2530</ol>
2531<hr />
2532<p><strong>Bsp</strong></p>
2533<pre><code> > db.dokumente.insert({hallo: "MongoDB"})
2534 WriteResult({ "nInserted" : 1 })</code></pre>
2535<hr />
2536<ol style="list-style-type: decimal">
2537<li>Die Operation zum Einfügen neuer Dokumente heißt in MongoDB <strong>insert</strong>.</li>
2538<li>Wenn die verwendete Collection (in unserem Beispiel dokumente) noch nicht existiert, wird sie automatisch vor dem ersten Zugriff angelegt.</li>
2539<li>Grundsätzlich arbeitet MongoDB bei schreibenden Operationen nach dem Fire-and- Forget-Prinzip.</li>
2540<li>Schreibende Operationen auf einem einzelnen Dokument sind gemäß des ACID4-Prinzips atomar.</li>
2541<li>Transaktionen, bei denen die Manipulation mehrerer Datensätze zu einer atomaren Operation zusammengefasst wird, kennt MongoDB hingegen nicht.</li>
2542</ol>
2543<hr />
2544<hr />
2545<ol start="88" class="example" style="list-style-type: decimal">
2546<li>Erklären Sie das Fire-and-Forget-Prinzip!</li>
2547</ol>
2548<hr />
2549<ol style="list-style-type: decimal">
2550<li>Anwendungen müssen den Fehlerstatus der letzten Schreiboperation aktiv erfragen; der Status wird nicht automatisch vom Server zurückgeliefert.</li>
2551<li>So wird im Erfolgsfall eine bessere Performance erreicht.</li>
2552<li>Die Mongo Shell führt diese Abfrage bei Verwendung von <code>insert(...)</code> auf einer Collection automatisch aus, sodass Fehlermeldungen direkt angezeigt werden.</li>
2553</ol>
2554<hr />
2555<hr />
2556<ol start="89" class="example" style="list-style-type: decimal">
2557<li>Beschreiben Sie die Parameter des UPDATE-Kommandos!</li>
2558</ol>
2559<hr />
2560<pre><code> db.<collection>.update(query,update,upsert,multi)</code></pre>
2561<ul>
2562<li>query: Diese Abfrage legt fest, welches bzw. welche Dokument(e) geändert werden sollen.</li>
2563<li>update: Neues Dokument bei vollständiger Ersetzung bzw. Änderungsdaten bei partieller Änderung.</li>
2564<li>upsert: Falls true, wird ein Dokument erzeugt, falls die Abfrage query nichts findet. Der Default ist false. (true) oder nicht. Der Default ist false.</li>
2565<li>multi: Boolesches Flag, das steuert, ob ein oder mehrere (true) Dokumente geändert werden sollen. Der Default ist false.</li>
2566</ul>
2567<hr />
2568<hr />
2569<ol start="90" class="example" style="list-style-type: decimal">
2570<li>Erläutern Sie die Besonderheiten des UPDATE-Kommandos!</li>
2571</ol>
2572<hr />
2573<ol style="list-style-type: decimal">
2574<li>Änderungen an Dokumenten werden mit dem Kommando update() vorgenommen.</li>
2575<li>In der Mongo Shell erwartet dieses Kommando bis zu vier Parameter, die sich auch in den Treibern in der einen oder anderen Form wiederfinden.</li>
2576<li>Das Feld _id ist unveränderlich und darf daher nicht geändert werden.</li>
2577</ol>
2578<hr />
2579<hr />
2580<ol start="91" class="example" style="list-style-type: decimal">
2581<li>Vergleichen Sie die vollständige Ersetzung von JSON-Dokumenten mit partiellen Änderungen.</li>
2582</ol>
2583<hr />
2584<ol style="list-style-type: decimal">
2585<li><p><strong>Vollständige Ersetzung</strong></p>
2586<p>Legen wir zunächst ein Dokument an</p>
2587<pre><code> > db.vollständig.drop()
2588 true
2589 > db.vollständig.insert( {_id:1, a:1, b: "zwei"} )
2590 > db.vollständig.find()
2591 { "_id" : 1, "a" : 1, "b" : "zwei" }</code></pre>
2592<p>um anschließend eine Änderung vorzunehmen:</p>
2593<pre><code> > db.vollständig.update( {_id:1}, {a:2} )
2594 > db.vollständig.find()
2595 { "_id" : 1, "a" : 2 }</code></pre>
2596<p>Intuitiv hätte man vielleicht erwartet, dass das Dokument nach der Änderung</p>
2597<p>{ "_id" : 1, "a" : 2, "b" : "zwei" }</p>
2598<p>gewesen wäre. Dies ist allerdings nicht der Fall, da hier eine vollständige Ersetzung des Dokuments stattfindet (bisheriges Primärschlüsselfeld _id und alle Felder aus dem Dokument des zweiten Parameters der update-Methode).</p></li>
2599<li><p><strong>Partielle Änderungen</strong></p>
2600<pre><code>> db.partiell.drop()
2601true
2602> db.partiell.insert( {_id:1, a:2, b: "drei"} )
2603> db.partiell.update( {_id:1}, {$set: {a:2} } )
2604> db.partiell.find()
2605{ "_id" : 1, "a" : 2, "b" : "drei" }</code></pre>
2606<p>Mithilfe des Operators <code>$set</code> haben wir ein Dokument <code>{a: 2}</code> angegeben, dessen Felder die des bestehenden Dokuments überschreiben bzw. ergänzen. Alle anderen Felder des Zieldokuments bleiben unverändert.</p></li>
2607</ol>
2608<hr />
2609<hr />
2610<ol start="92" class="example" style="list-style-type: decimal">
2611<li>Nennen und beschreiben Sie die skalare Operatoren des UPDATE-Statements.</li>
2612</ol>
2613<hr />
2614<p>Diese Gruppe von Operatoren bezieht sich auf skalare Felder. Im Einzelnen sind dies die nun folgenden.</p>
2615<p><strong>$set</strong></p>
2616<p>Mit $set werden ein oder mehrere Felder auf einen konstanten, neuen Wert gesetzt. Felder, die noch nicht existieren, werden angelegt.</p>
2617<pre><code>> db.set.drop()
2618> db.set.insert( {_id:1, a:1, b: "drei"} )
2619> db.set.update( {_id:1}, {$set: {a:2, c: [4,5]} } )
2620> db.set.find()
2621{ "_id" : 1, "a" : 2, "b" : "drei", "c" : [ 4, 5 ] }</code></pre>
2622<p>$set setzt die Felder unabhängig davon, ob das Dokument geändert oder im Rahmen eines upserts (s. weiter unten) erst neu angelegt wird.</p>
2623<p><strong>$unset</strong></p>
2624<p>Zum Löschen von Feldern können Sie $unset verwenden. Die Namen der zu löschenden Felder werden als Schlüssel mit Wert 1 angegeben, analog zu einer Projektion bei einer Query:</p>
2625<pre><code>> db.unset.drop()
2626> db.unset.insert( {_id:1, a:1, b: "drei"} )
2627> db.unset.update( {_id:1}, {$unset: {b:1, c:1}})
2628> db.unset.find()
2629{ "_id" : 1, "a" : 1 }</code></pre>
2630<p>Felder, die es nicht gibt, werden beim Entfernen ohne Fehlermeldung ignoriert.</p>
2631<p><strong>$rename</strong></p>
2632<p>Eine Umbenennung eines oder mehrerer Felder wird mit $rename durchgeführt. Der Schlüssel des jeweiligen Feldes im Änderungsdokument ist der Name des umzubenennenden Feldes, der Wert der neue Name.</p>
2633<pre><code>> db.rename.drop()
2634> db.rename.insert( {_id:1, a:1, b: "drei"} )
2635> db.rename.update( {_id:1}, {$rename: {b: "c", d: "e"}})
2636> db.rename.find()
2637{ "_id" : 1, "a" : 1, "c" : "drei" }</code></pre>
2638<p>Analog zu $unset werden Felder, die es nicht gibt, auch nicht umbenannt.</p>
2639<p><strong>$inc</strong></p>
2640<p>Mithilfe des $inc-Operators lassen sich numerische Felder um einen bestimmten, festen Betrag erhöhen bzw. erniedrigen (bei negativen Werten). Werden Felder angegeben, die es zuvor nicht gab, werden diese auf den entsprechenden Wert gesetzt.</p>
2641<pre><code>> db.inc.drop()
2642> db.inc.insert( {_id:1, a:1, b: "drei"} )
2643> db.inc.update( {_id:1}, {$inc: {a:0.5, d:-5}} )
2644> db.inc.find()
2645{ "_id" : 1, "a" : 1.5, "b" : "drei", "d" : -5 }</code></pre>
2646<p>Wird $inc auf nichtnumerische Felder angewendet, führt dies zu einem Fehler:</p>
2647<pre><code>> db.inc.update({_id:1}, {$inc: {b:1}})
2648Cannot apply $inc modifier to non-number</code></pre>
2649<p><strong>$mul</strong></p>
2650<p>Dieser Operator multipliziert ein numerisches Feld mit dem angegebenen Faktor, z. B.:</p>
2651<pre><code>> db.mult.drop()
2652> db.mult.insert({_id:1, a: NumberInt(2)})
2653> db.mult.update({_id:1}, {$mul: {a: NumberLong(3) }})
2654> db.mult.find()
2655{ "_id" : 1, "a" : NumberLong(6) }</code></pre>
2656<p>Wenn das zu multiplizierende Feld nicht existiert, erhält es den Wert 0.</p>
2657<p><strong>$bit</strong></p>
2658<p>Auf ganzzahligen Feldern können mit $bit Operationen auf Bit-Ebene durchgeführt werden. Da die Mongo Shell standardmäßig nur Fließkommazahlen verwendet, müssen wir zur Erzeugen der Testdaten die Wrapper-Klasse NumberInt (für 32-Bit- Ganzzahlen) bzw. NumberLong (für 64-Bit-Ganzzahlen) verwenden.</p>
2659<pre><code>> db.bit.insert({_id:1, a: new NumberInt("4"), b: Math.PI})
2660> db.bit.update({_id:1}, {$bit: {a: {or: 2}}} )
2661> db.bit.find()
2662{ "_id": 1, "a": NumberInt(6), "b": 3.141592653589793}</code></pre>
2663<p>Bei nicht ganzzahligen Typen führt der $bit-Operator zu einem Fehler:</p>
2664<pre><code>> db.bit.update({_id:1}, {$bit: {b: {and: 1 }}})
2665$bit cannot update a value of type double</code></pre>
2666<p>Felder, die nicht existieren, werden ignoriert:</p>
2667<pre><code>> db.bit.update({_id:1}, {$bit: {c: {and: 1 }}})
2668> db.bit.find()
2669{ "_id": 1, "a": NumberLong(6), "b": 3.141592653589793}</code></pre>
2670<p>Bei der bitweisen Manipulation stehen an booleschen Operationen zurzeit nur and und or zur Verfügung.</p>
2671<p><strong>$currentDate</strong></p>
2672<p>Auf Datumsfeldern können Sie mithilfe des Operators $currentDate wie folgt das aktuelle Datum setzen:</p>
2673<pre><code>> db.log.drop()
2674> db.log.insert({
2675 _id:1,
2676 status: "aktiv",
2677 ts: ISODate("2014-03-19T12:00:00")})
2678> db.log.update({_id:1}, {$currentDate: {ts: true}})
2679> db.log.find()
2680{ "_id" : 1, "status" : "aktiv", "ts" : ISODate("2014-03-20T08:27:06.892Z") }</code></pre>
2681<p>Wenn Sie das Buch in Ihren Händen halten, dürfte das aktuelle Datum bereits deutlich weiter in der Zukunft liegen ;-) Felder, die nicht existieren, werden ggf. angelegt. Sie können mehrere Felder aktualisieren und auch noch genauer angeben, ob das aktuelle Datum in Form eines Timestamps oder eines Dates (Default) abgelegt wird:</p>
2682<pre><code>> db.log.update({_id:1},
2683 { $currentDate: {
2684 ts: {$type: "timestamp"},
2685 ts_2: {$type:"date"}
2686} })
2687> db.log.find().pretty()
2688{
2689 "_id" : 1,
2690 "status" : "aktiv",
2691 "ts" : Timestamp(1395304942, 1),
2692 "ts_2" : ISODate("2014-03-20T08:42:22.467Z")
2693}</code></pre>
2694<h2 id="dml-mongodb2-..."><span class="header-section-number">6.3</span> DML MongoDB2 <a href="#TOC">...</a></h2>
2695<hr />
2696<hr />
2697<ol start="93" class="example" style="list-style-type: decimal">
2698<li>Nennen und beschreiben Sie die Array-Operatoren des UPDATE-Statements.</li>
2699</ol>
2700<hr />
2701<p>Diese Gruppe von Operatoren dient zur Manipulation von Arrays.</p>
2702<p><strong>$push, $pushAll</strong></p>
2703<p>Der $push-Operator hängt an ein Array ein weiteres Element an. Falls das Feld noch nicht existiert, wird es angelegt.</p>
2704<pre><code>> db.array.drop()
2705> db.array.insert({_id:1, a: [1,2], b:3})
2706> db.array.update({_id:1}, {$push: {a:3}})
2707> db.array.find()
2708{ "_id" : 1, "a" : [ 1, 2, 3 ], "b" : 3 }</code></pre>
2709<p>Auf skalaren Feldern führt $push zu einem Fehler:</p>
2710<pre><code>> db.array.update({_id:1}, {$push: {b:3}})
2711Cannot apply $push/$pushAll modifier to non-array</code></pre>
2712<p>Wenn Sie mehrere Elemente anhängen wollen, können Sie den Operator $pushAll in Verbindung mit einem weiteren Array verwenden. Das Ziel-Array wird dann um alle Einträge aus dem Quell-Array ergänzt:</p>
2713<pre><code>> db.array.update({_id:1},{$pushAll: {a: [5,8]}})
2714> db.array.find()
2715{ "_id" : 1, "a" : [ 1, 2, 3, 5, 8 ], "b" : 3 }</code></pre>
2716<p>Alternativ zu $pushAll kann hier auch der Operator $each verwendet werden:</p>
2717<pre><code>> db.array.update({_id:1}, {$push: {a: {$each: [5,8]}}} )</code></pre>
2718<p>In Verbindung mit $push und $each können noch zwei weitere Operatoren zum Einsatz kommen, um beim Ändern eines Arrays für eine bestimmte Länge bzw. eine Sortierung zu sorgen:</p>
2719<p><strong>$slice</strong></p>
2720<p>Mit dem Operator $slice wird die Größe des Arrays nach dem Insert festgelegt. Dem Operator kann der Wert 0 oder eine negative –n Ganzzahl übergeben werden, deren Betrag n dann die Länge des Arrays bestimmt:</p>
2721<pre><code>> db.array.drop()
2722> db.array.insert({_id:1, a:[1,2]})
2723> db.array.insert({_id:2, a:[1,2]})
2724> db.array.update({_id:1}, {$push: {a: {$each: [3,4], $slice:-3}}})
2725> db.array.update({_id:2}, {$push: {a: {$each: [3,4], $slice:0}}})
2726> db.array.find()
2727{ "_id" : 2, "a" : [ ] }
2728{ "_id" : 1, "a" : [ 2, 3, 4 ] }</code></pre>
2729<p><strong>$sort</strong></p>
2730<p>Wenn es sich bei den Array-Einträgen um Dokumente handelt, kann in Verbindung mit $each und $slice mithilfe des $sort-Operators zusätzlich noch eine Sortierung dieser Dokumente durchgeführt werden.</p>
2731<pre><code>> db.array.drop()
2732> db.array.insert({_id:1, a:[{b:2, c:2}, {b:4,c:1}]})
2733> db.array.update({_id:1}, {$push: {a:
2734 {$each: [{b:3,c:0}], $slice:-3, $sort: {b:1}}}})
2735> db.array.find().pretty()
2736{
2737 "_id" : 1,
2738 "a" : [
2739 {
2740 "b" : 2,
2741 "c" : 2
2742 },
2743 {
2744 "b" : 3,
2745 "c" : 0
2746 },
2747 {
2748 "b" : 4,
2749 "c" : 1
2750 }
2751 ]</code></pre>
2752<p>}</p>
2753<p>Nach dem Einfügen des dritten Array-Eintrags findet noch eine aufsteigende Sortierung bzgl. des Feldes b statt, sodass das neue Dokument nun an zweiter Stelle im Array liegt.</p>
2754<p><strong>$addToSet</strong></p>
2755<p>Analog zu $push fügt $addToSet einem Array einen oder mehrere Werte hinzu, allerdings nur dann, wenn der jeweilige Wert noch nicht in dem Array enthalten ist. Das Array wird in diesem Kontext im Prinzip als Menge interpretiert, in der jeder Wert nur einmal vorkommt.</p>
2756<pre><code>> db.array.find()
2757{ "_id" : 1, "a" : [ 1, 2, 3, 5, 8 ], "b" : 3 }
2758> db.array.update({_id:1}, {$addToSet: {a: 5}})
2759> db.array.find()
2760{ "_id" : 1, "a" : [ 1, 2, 3, 5, 8 ], "b" : 3 }</code></pre>
2761<p>Zum Hinzufügen mehrerer Werte kann wie zuvor der Operator $each verwendet werden:</p>
2762<pre><code>> db.array.update({_id:1},{$addToSet:{a:{$each:[8,13]}}})
2763> db.array.find()
2764{ "_id" : 1, "a" : [ 1, 2, 3, 5, 8, 13 ], "b" : 3 }</code></pre>
2765<p><strong>$pop</strong></p>
2766<p>Der $pop-Operator ist das Gegenstück zum $push- bzw. $addToSet-Operator. Mit ihm kann das letzte bzw. erste Element eines Arrays gelöscht werden. Zum Löschen des letzten Elements ist eine 1 zu übergeben, -1 löscht hingegen das erste Element:</p>
2767<pre><code>> db.array.find()
2768{ "_id" : 1, "a" : [ 1, 2, 3, 5, 8, 13 ], "b" : 3 }
2769> db.array.update({_id:1},{$pop: {a:1}})
2770> db.array.find()
2771{ "_id" : 1, "a" : [ 1, 2, 3, 5, 8 ], "b" : 3 }
2772> db.array.update({_id:1},{$pop: {a:-1}})
2773> db.array.find()
2774{ "_id" : 1, "a" : [ 2, 3, 5, 8 ], "b" : 3 }</code></pre>
2775<p>Nach dem Entfernen des einzigen Elements eines Arrays bleibt ein leeres Array zurück. Wie alle Array-Operatoren führt auch $pop auf skalaren Feldern zu einem Fehler.</p>
2776<p><strong>$pull, $pullAll</strong></p>
2777<p>Mit $pull bzw. $pullAll lassen sich gezielt bestimmte Werte aus einem Array entfernen. $pull löscht dabei alle Vorkommen eines einzelnen Wertes, $pullAll löscht alle Vorkommen mehrerer Werte.</p>
2778<pre><code>> db.array.drop()
2779> db.array.insert({_id:1, a: [1,2,2,3,4,4]})
2780> db.array.update({_id:1}, {$pull: {a:2}})
2781> db.array.find()
2782{ "_id" : 1, "a" : [ 1, 3, 4, 4 ] }
2783> db.array.update({_id:1}, {$pullAll: {a:[3,4,5]}})
2784> db.array.find()
2785{ "_id" : 1, "a" : [ 1 ] }</code></pre>
2786<p>Zu löschende Werte, die im Array nicht enthalten sind, werden dabei stillschweigend ignoriert.</p>
2787<hr />
2788<hr />
2789<ol start="94" class="example" style="list-style-type: decimal">
2790<li>Erläutern Sie das positionsbezogenes Ändern von Array-Werten</li>
2791</ol>
2792<hr />
2793<p>Da Arrays intern wie Dokumente mit 0-basiert durchnummerierten Feldnamen behandelt werden, können mit den skalaren Operatoren $set, $unset, $inc und $bit einzelne Array-Elemente auch positionsbezogen manipuliert werden, wie folgende Beispiele demonstrieren:</p>
2794<pre><code>> db.array.drop()
2795> db.array.insert({_id:1, a: [1,2,3]})
2796> db.array.update({_id:1}, {$set: {"a.2": new NumberLong("4")}})
2797> db.array.find()
2798{ "_id" : 1, "a" : [ 1, 2, NumberLong(4) ] }
2799> db.array.update({_id:1}, {$unset: {"a.1": 1}})
2800> db.array.find()
2801{ "_id" : 1, "a" : [ 1, null, NumberLong(4)] }
2802> db.array.update({_id:1}, {$inc: {"a.0": 4}})
2803> db.array.find()
2804{ "_id" : 1, "a" : [ 5, null, NumberLong(4) ] }
2805> db.array.update({_id:1}, {$bit: {"a.2" : {or:2}}})
2806> db.array.find()
2807{ "_id" : 1, "a" : [ 5, null, NumberLong(6) ] }</code></pre>
2808<p>Analog zu den Operatoren auf skalaren Feldern werden nicht existente Felder angelegt und »Lücken« im Array mit null-Werten belegt:</p>
2809<pre><code>> db.array.update({_id:1}, {$inc: {"a.5": 4}})
2810> db.array.find()
2811{ "_id" : 1, "a" : [ 5, null, NumberLong(6), null, null, 4 ] }</code></pre>
2812<p>Die Anwendung des $rename-Operators zur Umordnung zweier Felder ist allerdings nicht möglich:</p>
2813<pre><code>> db.array.update({_id:1}, {$rename: {"a.2" :"a.1"}})</code></pre>
2814<p>$rename source field invalid</p>
2815<hr />
2816<hr />
2817<ol start="95" class="example" style="list-style-type: decimal">
2818<li>Erläutern Sie den $-Operator des UPDATE-Kommandos!</li>
2819</ol>
2820<hr />
2821<p>Wenn ein Update Elemente eines Array-Feldes manipuliert, kann die Änderung nicht an einer zuvor bekannten Position erfolgen. Um dennoch die Position der Änderung referenzieren zu können, kann der $-Operator als Platzhalter verwendet werden. In folgendem Beispiel soll der Wert 1 innerhalb des Arrays a durch 4 ersetzt werden:</p>
2822<pre><code>> db.array.drop()
2823> db.array.insert({_id:1, a: [1,2]})
2824> db.array.insert({_id:2, a: [2,3,3]})</code></pre>
2825<p>Mit dem Ausdruck a.$ kann nun die jeweilige Position im Array a beschrieben werden, auf die die ändernde Operation angewendet werden soll:</p>
2826<pre><code>> db.array.update({a:1}, {$set: {"a.$": 4}})
2827> db.array.find()
2828{ "_id" : 1, "a" : [ 4, 2 ] }
2829{ "_id" : 2, "a" : [ 2, 3, 3 ] }</code></pre>
2830<p>Dabei lässt sich allerdings immer nur die Position des ersten Vorkommens eines Elements innerhalb eines Arrays beschreiben:</p>
2831<pre><code>> db.array.update({a:3}, {$set: {"a.$": 5}})
2832> db.array.find()
2833{ "_id" : 1, "a" : [ 4, 2 ] }
2834{ "_id" : 2, "a" : [ 2, 5, 3 ] }</code></pre>
2835<p>Sinnvoll ist der $-Operator daher nur auf solchen Arrays anzuwenden, die mit $addToSet als Menge mit eindeutigen Werten verwendet werden. Wenn das Array eingebettete Dokumente enthält, kann mittels der Punktnotation über den $-Operator hinaus auf einzelne Felder in diesem Dokument weiternavigiert werden:</p>
2836<pre><code>> db.array.drop()
2837> db.array.insert({_id:1, a: [ {b:1}, {b:2} ] } )
2838> db.array.insert({_id:2, a: [ {b:2}, {b:3} ] } )
2839> db.array.find()
2840{ "_id" : 1, "a" : [ { "b" : 1 }, { "b" : 2 } ] }
2841{ "_id" : 2, "a" : [ { "b" : 2 }, { "b" : 3 } ] }</code></pre>
2842<p>Der Ausdruck a.$.b »trifft« dann das Feld b im jeweils passenden eingebetteten Dokument:</p>
2843<pre><code>> db.array.update({"a.b": 1}, {$inc: {"a.$.b": -2}})
2844> db.array.find()
2845{ "_id" : 1, "a" : [ { "b" : -1 }, { "b" : 2 } ] }
2846{ "_id" : 2, "a" : [ { "b" : 2 }, { "b" : 3 } ] }</code></pre>
2847<hr />
2848<hr />
2849<ol start="96" class="example" style="list-style-type: decimal">
2850<li>Erläutern Sie die Kombination von Operatoren des UPDATE-Kommandos!</li>
2851</ol>
2852<hr />
2853<p>Mehrere Operatoren können miteinander kombiniert werden, sofern sie sich nicht widersprechen (z. B. $set in Verbindung mit $unset). Das folgende Beispiel demonstriert dies:</p>
2854<pre><code>> db.kombi.drop()
2855> db.kombi.insert({_id:1, a:1, b: [1,2], v:0})
2856> db.kombi.update({_id:1}, {$set: {a:2, c:1}, $pushAll: {b: [3,4]}, $inc:
2857{v:1}})
2858> db.kombi.find()
2859{ "_id" : 1, "a" : 2, "b" : [ 1, 2, 3, 4 ], "c" : 1, "v" : 1 }</code></pre>
2860<p>Zwei Operatoren, die das gleiche Feld betreffen, sind hingegen nicht zulässig:</p>
2861<pre><code>> db.kombi.update({_id:1}, {$set: {a:2}, $unset: {a:1}})</code></pre>
2862<p>Field name duplication not allowed with modifiers</p>
2863<hr />
2864<hr />
2865<ol start="97" class="example" style="list-style-type: decimal">
2866<li>Beschreiben Sie das UPSERT-Kommando!</li>
2867</ol>
2868<hr />
2869<p>MongoDB bietet die Möglichkeit, Dokumente, die nicht existieren, vor Durchführung einer Änderung implizit anzulegen. So kann bequem mit einem Befehl das Suchen und (bei Nichtexistenz) das Einfügen eines Dokuments durchgeführt werden. Dies passiert mit dem Kommando upsert(...), was einer Kombination von insert(...) und update(...) entspricht. Dabei spielen die ersten drei Parameter des update- Kommandos eine Rolle:</p>
2870<pre><code>db.<collection>.update(query,update,upsert,multi)</code></pre>
2871<p>Wenn upsert = true ist (Default ist false), wird zunächst die Abfrage query ausgeführt. Liefert diese ein oder mehrere Dokumente, werden die Änderungen wie bislang beschrieben ausgeführt. Falls keine passenden Dokumente gefunden werden, wird ein neues Dokument angelegt, dessen Felder sich aus der Vereinigungsmenge von query und den Änderungen aus update zusammensetzen.</p>
2872<pre><code>> db.upsert.drop()
2873> db.upsert.insert({_id:1,a:1,b:2})
2874> db.upsert.update({_id:2,a:2}, {$inc: {a:1}, $set: {c:3, p:"o"}}, true)
2875> db.upsert.find()
2876{ "_id" : 1, "a" : 1, "b" : 2 }
2877{ "_id" : 2, "a" : 3, "c" : 3, "p" : "o" }</code></pre>
2878<p>Zunächst besteht das neue Dokument aus den Feldern der query = {_id:2, a:2 }. Anschließend wird darauf update angewandt, was zum einen zur Erhöhung des nun bereits bestehenden Feldes a, zum anderen zum Anlegen der Feldes c und p führt. Mit dieser Variante von update() lassen sich mit einem Kommando relativ elegant Dinge wie Zähler o. Ä. implementieren.</p>
2879<hr />
2880<hr />
2881<ol start="98" class="example" style="list-style-type: decimal">
2882<li>Erläutern Sie den $setOnInsert-Operator des UPSERT-Kommandos!</li>
2883</ol>
2884<hr />
2885<p>Wenn Sie bestimmte Felder nur dann setzen wollen, wenn beim Upsert ein neues Dokument eingefügt wird, können Sie den Operator $setOnInsert verwenden. Dieser hat die gleiche Syntax wie $set, wird aber nur dann berücksichtigt, wenn auch ein neues Dokument angelegt wird.</p>
2886<pre><code>> db.upsert.drop()
2887> db.upsert.insert({_id:1, alt:true})</code></pre>
2888<p>Falls nun ein neues Dokument eingefügt wird, werden mit $setOnInsert bestimmte Felder initialisiert:</p>
2889<pre><code>> db.upsert.update({_id:2}, {$setOnInsert: {neu:true}}, true)
2890> db.upsert.find()
2891{ "_id" : 1, "alt" : true }
2892{ "_id" : 2, "neu" : true }</code></pre>
2893<p>Wenn aber eine Änderung eines bestehenden Dokuments ausgeführt wird, bewirkt $setOnInsert nichts:</p>
2894<pre><code>> db.upsert.update({_id:1}, {$setOnInsert: {neu:true}}, true)
2895> db.upsert.find()
2896{ "_id" : 1, "alt" : true }
2897{ "_id" : 2, "neu" : true }</code></pre>
2898<hr />
2899<hr />
2900<ol start="99" class="example" style="list-style-type: decimal">
2901<li>Beschreiben Sie das Kommando "FindAndModify"!</li>
2902</ol>
2903<hr />
2904<p>Mit dem Kommando findAndModify() lassen sich Änderungen in Verbindung mit einer Abfrage auf einem einzelnen Dokument durchführen. Das Kommando hat folgende Syntax:</p>
2905<pre><code>db.<collection>.findAndModify(args)</code></pre>
2906<p>wobei args aus einem Dokument mit folgenden, optionalen Feldern besteht:</p>
2907<ul>
2908<li>query: Definiert die Abfrage. Sollte die Abfrage mehr als ein Dokument liefern, betrachtet findAndModify() immer nur das erste dieser Dokumente.</li>
2909<li>sort</li>
2910<li>fields: Definiert eine Projektion, d. h. eine Einschränkung auf eine Untermenge aller Felder.</li>
2911<li>update:</li>
2912<li>remove: Falls true, wird das gefundene Dokument zurückgegeben und danach gelöscht.</li>
2913<li>new: Falls true, wird das geänderte Dokument zurückgegeben, ansonsten das gefundene.</li>
2914<li>upsert:</li>
2915</ul>
2916<p>Das folgende Beispiel kann Ihnen als Grundlage weiterer, eigener Experimente dienen:</p>
2917<pre><code>> db.fam.drop()
2918> db.fam.findAndModify({
2919 query: {_id:1},
2920 update: {$inc: {a:1}},
2921 new:false,
2922 upsert:true})
2923null
2924> db.fam.find()
2925{ "_id" : 1, "a" : 1 }
2926> db.fam.findAndModify({
2927 query: {_id:1},
2928 update: {$inc: {a:1}},
2929 new:true,
2930 upsert:true})
2931{ "_id" : 1, "a" : 2 }</code></pre>
2932<hr />
2933<hr />
2934<ol start="100" class="example" style="list-style-type: decimal">
2935<li>Beschreiben Sie Änderungen an mehreren Dokumenten.</li>
2936</ol>
2937<hr />
2938<p>Alle bisherigen Änderungen haben sich immer auf ein einzelnes Dokument bezogen. Wenn Änderungen an mehreren Dokumenten durchgeführt werden sollen, kommt der vierte Parameter des insert()-Kommandos multi ins Spiel. Wird dieser auf true gesetzt (Default ist false), wirken sich die Änderungen auf mehrere Dokumente aus, sofern die entsprechende Abfrage diese auch liefert.</p>
2939<pre><code>> db.viele.drop()
2940> db.viele.insert({_id:1,a:1, b:2})
2941> db.viele.insert({_id:2,a:1, b:3})
2942> db.viele.find()
2943{ "_id" : 1, "a" : 1, "b" : 2 }
2944{ "_id" : 2, "a" : 1, "b" : 3 }</code></pre>
2945<p>Eine Änderung mit multi = false ändert nur das erste gefundene Dokument:</p>
2946<pre><code>> db.viele.update({a:1}, {$set: {c:4}})
2947> db.viele.find()
2948{ "_id" : 2, "a" : 1, "b" : 3 }
2949{ "_id" : 1, "a" : 1, "b" : 2, "c" : 4 }</code></pre>
2950<p>Sollen hingegen alle Dokumente geändert werden, die der Abfrage entsprechen, kann dies wie folgt durchgeführt werden:</p>
2951<pre><code>> db.viele.update({a:1}, {$set: {c:5}}, false, true)
2952> db.viele.find()
2953{ "_id" : 1, "a" : 1, "b" : 2, "c" : 5 }
2954{ "_id" : 2, "a" : 1, "b" : 3, "c" : 5 }</code></pre>
2955<p>Änderungen an mehreren Dokumenten werden nicht atomar durchgeführt. Bricht ein Update-Vorgang zwischendurch ab, haben Sie ggf. einen fachlich inkonsistenten Datenbestand. Es ist allerdings möglich, die Änderungen in Isolation von anderen konkurrierenden Schreiboperationen durchzuführen, indem der Operator $isolated innerhalb der Abfrage verwendet wird:</p>
2956<pre><code>> db.viele.update({a:1, $isolated:1}, {$set: {c:6}}, false ,true)</code></pre>
2957<p>Dies bewirkt, dass sich die Treffermenge, die den Suchkriterien entspricht, während der Dauer des Update-Vorgangs auch dann nicht ändert, wenn durch konkurrierende Schreibvorgänge neue Dokumente hinzukommen, die ebenfalls den Suchkriterien entsprechen. In Verbindung mit Sharding kann der Operator $isolated allerdings nicht verwendet werden.</p>
2958<hr />
2959<hr />
2960<ol start="101" class="example" style="list-style-type: decimal">
2961<li>Beschreiben Sie Optimistisches Sperren.</li>
2962</ol>
2963<hr />
2964<p>Um konkurrierende Schreibzugriffe auf dieselben Dokumente zu vermeiden, kann man (unabhängig von der konkreten Datenbank) das sogenannte Optimistische Sperren5, 6 verwenden. In MongoDB lässt sich dies auch vergleichsweise einfach realisieren. Nehmen wir an, Sie haben ein Dokument produkt aus der Collection produkte gelesen und wollen nun eine partielle Änderung auf den Feldern {f1 ... fn} durchführen. Der Einfachhalt halber nehmen wir an, dass Sie die Felder f1 ... fn mittels des Operators $set ersetzen wollen. Wenn Sie nun ein Update der Form</p>
2965<pre><code>> db.produkte.update(
2966 {_id: produkt._id},
2967 {$set: {f1:v1, ..., fn:vn}},
2968 true, false )</code></pre>
2969<p>durchführen, könnte durch die Anwendung mittlerweile bereits eine konkurrierende Änderung an produkt durchgeführt worden sein, die Sie dann überschreiben würden. Dies lässt sich leicht vermeiden, indem Sie die Abfrage um die Feldgruppe f1 ... fn erweitern:</p>
2970<pre><code>> db.produkte.update(
2971 {_id: produkt._id, f1:produkt.v1, ..., fn:produkt.vn },
2972 {$set: {f1:v1, ..., fn:vn}},
2973 true, false )</code></pre>
2974<p>Wenn in der Zwischenzeit eine Änderung an den Feldern f1 ... fn stattgefunden haben sollte, scheitert diese Änderung und Sie können in Ihrer Anwendung entsprechend reagieren, etwa indem Sie eine Rückmeldung geben, das Dokument erneut lesen usw. Alternativ zu einer Feldgruppe kann man ein rein technisches Feld, z. B. ein Integer-Feld version verwenden, in dem dann die Version des Dokuments abgelegt und bei jeder Änderung inkrementiert wird:</p>
2975<pre><code>> produkt = db.produkte.findOne(...)</code></pre>
2976<p>und später:</p>
2977<pre><code>> db.produkte.update(
2978 {_id:produkt._id, version: produkt.version},
2979 {$inc: {version: 1},
2980 {$set: {f1:v1, ..., fn:vn}},
2981 true, false)</code></pre>
2982<p>Dieses Verfahren ist nicht mit einer Historisierung zu verwechseln, es gibt immer nur genau ein Dokument, in dem die Versionsnummer hochgezählt wird. Bei einer Historisierung hingegen gibt es mehrere Dokumente, die (oft an einer zeitlichen Dimension orientiert) verschiedene Stände eines Geschäftsobjekts repräsentieren.</p>
2983<hr />
2984<hr />
2985<ol start="102" class="example" style="list-style-type: decimal">
2986<li>Beschreiben Sie das Kommando "save"!</li>
2987</ol>
2988<hr />
2989<p>Wenn Änderungen an Dokumenten nicht mit den zuvor beschriebenen Operatoren durchgeführt werden können, muss die Anwendung das Dokument laden, verändern und das Dokument wieder speichern. In der Mongo Shell sähe dies in etwa so aus:</p>
2990<pre><code>> db.dokumente.drop()
2991> db.dokumente.insert({_id:1,a:1,b:2})
2992> doc = db.foo.findOne()
2993{ "_id" : 1, "a" : 1, "b" : 2 }
2994> doc.sum = doc.a + doc.b
29953</code></pre>
2996<p>Um dieses veränderte Dokument zu speichern, kann das Kommando save() verwendet werden:</p>
2997<pre><code>> db.dokumente.save(doc)
2998> db.dokumente.find()
2999{ "_id" : 1, "a" : 1, "b" : 2, "sum" : 3 }</code></pre>
3000<p>Die interne Verarbeitung sieht so aus, dass in Abhängigkeit vom Vorhandensein des Feldes _id entweder ein insert() oder ein update() ausgeführt wird. Geben Sie dazu folgenden Befehl ein (ohne die Klammer), um die Implementierung von save() anzusehen:</p>
3001<pre><code>> db.dokumente.save</code></pre>
3002<p>Zwischen dem Suchen und einem späteren Ändern mittels save() vergeht Zeit, in der konkurrierende Schreiboperationen das Dokument ebenfalls verändern oder gar löschen könnten. Daher sollten Sie save() nur dann verwenden, wenn es unbedingt nötig ist. Wenn immer möglich, sollten Sie mit partiellen Änderungen arbeiten oder ein upsert() verwenden.</p>
3003<hr />
3004<hr />
3005<ol start="103" class="example" style="list-style-type: decimal">
3006<li>Beschreiben Sie das Kommando "remove"!</li>
3007</ol>
3008<hr />
3009<p>Zum Löschen von Dokumenten kann das Kommando</p>
3010<pre><code>> db.<collection>.remove( query )</code></pre>
3011<p>verwendet werden, wobei query eine Abfrage wie beim Kommando find() beinhalten kann. Wenn Sie nur bestimmte Dokumente löschen möchten, kann eine Abfrage wie z. B. diese hier übergeben werden:</p>
3012<pre><code>> db.dokumente.remove( {a: {$gt:10}} )</code></pre>
3013<p>Zum Löschen aller Dokumente einer Collection kann die Abfrage einfach leer bleiben:</p>
3014<pre><code>> db.dokumente.remove( {} )</code></pre>
3015<p>Wenn Sie auf diese Weise alle Dokumente löschen, wird intern über die gesamte Collection iteriert und jedes Dokument samt aller Indexeinträge einzeln gelöscht. Daher kann es deutlich schneller sein, die Collection komplett zu löschen:</p>
3016<pre><code>> db.dokumente.drop()
3017true</code></pre>
3018<dl>
3019<dt>.</dt>
3020<dd><img src="/home/user/acha/www-img/db/trigger.jpg" />
3021</dd>
3022</dl>
3023<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="co">-- create trigger, which logs inserts in dept</span>
3024<span class="kw">CREATE</span> <span class="kw">TRIGGER</span> log_insert_dept
3025<span class="kw">BEFORE</span> <span class="kw">INSERT</span> <span class="kw">ON</span> dept
3026<span class="kw">FOR</span> <span class="kw">EACH</span> <span class="kw">ROW</span>
3027<span class="kw">BEGIN</span>
3028 <span class="kw">INSERT</span> <span class="kw">INTO</span> <span class="fu">log</span> <span class="kw">VALUES</span>(NEW.deptno, datetime());
3029<span class="kw">END</span>;
3030
3031<span class="co">-- test log</span>
3032<span class="kw">INSERT</span> <span class="kw">INTO</span> dept <span class="kw">VALUES</span>(<span class="dv">50</span>, <span class="st">'CONTROLLING'</span>, <span class="st">'MIAMI'</span>);</code></pre></div>
3033<p><em>Ergebnis:</em></p>
3034<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql">sqlite> <span class="kw">SELECT</span> * <span class="kw">FROM</span> <span class="fu">log</span>;
3035
3036deptno <span class="dt">timestamp</span>
3037<span class="co">---------- -------------------</span>
3038<span class="dv">50</span> <span class="dv">2018-02-26</span> <span class="dv">13</span><span class="ch">:46:52</span></code></pre></div>
3039<h1 id="g.-datenbankanwendungen-..."><span class="header-section-number">7</span> G. Datenbankanwendungen <a href="#TOC">...</a></h1>
3040<h2 id="trigger-..."><span class="header-section-number">7.1</span> Trigger <a href="#TOC">...</a></h2>
3041<hr />
3042<hr />
3043<p>Ein Kleinunternehmen hat sich dazu entschieden, ihre Angestellten- und Filialdaten in einer relationalen Datenbank zu verwalten. Dadurch kann das Unternehmen besonders einfach den Datenbestand auswerten.</p>
3044<ol start="104" class="example" style="list-style-type: decimal">
3045<li>Erstellen Sie einen Trigger, der mitprotokolliert, an welchem Datum neue Datensätze in die Tabelle dept eingefügt werden!</li>
3046</ol>
3047<hr />
3048<pre><code>Die Tabellen wurden so erzeugt:
3049
3050 CREATE TABLE log (deptno INT, timestamp TEXT NOT NULL);
3051
3052 CREATE TABLE dept (
3053 deptno INTEGER PRIMARY KEY,
3054 dname TEXT UNIQUE NOT NULL,
3055 loc TEXT NOT NULL
3056 );
3057
3058 CREATE TABLE emp(
3059 empno INTEGER PRIMARY KEY,
3060 ename TEXT NOT NULL,
3061 job TEXT,
3062 mgr INT,
3063 hiredate TEXT,
3064 sal REAL,
3065 comm REAL,
3066 deptno INT,
3067 FOREIGN KEY(mgr) REFERENCES emp (empno),
3068 FOREIGN KEY(deptno) REFERENCES dept (deptno)
3069 );</code></pre>
3070<hr />
3071<hr />
3072<ol start="105" class="example" style="list-style-type: decimal">
3073<li>Erläutern Sie, wie in Triggern auf die Daten zugreifen werden kann.</li>
3074</ol>
3075<hr />
3076<p>Um in den ausgelösten Aktionen auf die Daten zugreifen zu können, werden symbolische Namen für die Werte vor (OLD) bzw. nach (NEW) der auslösenden Anweisung verwendet.</p>
3077<ul>
3078<li>Bei einem UPDATE stehen somit die alten Werte des Datensatzes wie auch die neuen zur Verfügung.</li>
3079<li>Bei einer INSERT Anweisung kann nicht auf die alten Werte zugegriffen werden,</li>
3080<li>ebenso wie bei einem DELETE nicht auf die neuen Werte zugegriffen werden kann.</li>
3081</ul>
3082<hr />
3083<hr />
3084<ol start="106" class="example" style="list-style-type: decimal">
3085<li><p>Erstellen Sie Trigger, die die referentielle Integrität ihrer Datenbank gewährleisten:</p>
3086<ol style="list-style-type: lower-alpha">
3087<li><p>Wenn ein Datensatz gelöscht wird, dann sollen alle davon abhängigen Datensätze automatisch gelöscht werden.</p></li>
3088<li><p>Wenn es abhängige Datensätze gibt, dann soll eine Fehlermeldung ausgegeben werden.</p></li>
3089</ol></li>
3090</ol>
3091<hr />
3092<ol style="list-style-type: lower-alpha">
3093<li><p>abhängige Datensätze löschen</p>
3094<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">CREATE</span> <span class="kw">TRIGGER</span> dept_delete
3095<span class="kw">BEFORE</span> <span class="kw">DELETE</span> <span class="kw">ON</span> dept
3096<span class="kw">FOR</span> <span class="kw">EACH</span> <span class="kw">ROW</span>
3097<span class="kw">BEGIN</span>
3098 <span class="kw">DELETE</span> <span class="kw">FROM</span> emp <span class="kw">WHERE</span> deptno = OLD.deptno;
3099<span class="kw">END</span>;</code></pre></div></li>
3100<li><p>Fehlermeldung ausgeben</p>
3101<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">CREATE</span> <span class="kw">TRIGGER</span> dept_no_delete
3102<span class="kw">BEFORE</span> <span class="kw">DELETE</span> <span class="kw">ON</span> dept
3103<span class="kw">FOR</span> <span class="kw">EACH</span> <span class="kw">ROW</span>
3104<span class="kw">WHEN</span> <span class="kw">EXISTS</span> (<span class="kw">SELECT</span> * <span class="kw">FROM</span> emp <span class="kw">WHERE</span> deptno = OLD.deptno)
3105<span class="kw">BEGIN</span>
3106 <span class="kw">SELECT</span> RAISE(<span class="kw">ROLLBACK</span>, <span class="st">'Delete of dept forbidden'</span>);
3107<span class="kw">END</span>;</code></pre></div></li>
3108</ol>
3109<p>Anmerkung: In der WHEN-Klausel kann ein beliebiger Ausdruck stehen: ZB "NEW.name != OLD.name"</p>
3110<hr />
3111<hr />
3112<ol start="107" class="example" style="list-style-type: decimal">
3113<li>Nennen Sie die Ereignisse, die einen Trigger auslösen können.</li>
3114</ol>
3115<hr />
3116<p>Mögliche Ereignisse sind:</p>
3117<ul>
3118<li>Einfügen neuer Datensätze (INSERT)</li>
3119<li>Löschen von Datensätzen (DELETE)</li>
3120<li>Ändern von Datensätzen (UPDATE)</li>
3121</ul>
3122<hr />
3123<hr />
3124<ol start="108" class="example" style="list-style-type: decimal">
3125<li><p>Nennen Sie die Zeitpunkte, zu denen ein Trigger ausgelöst werden kann.</p></li>
3126<li><p>Erläutern Sie den Unterschied zwischen Row-level und Statement-level Triggern.</p></li>
3127</ol>
3128<hr />
3129<p>Ebenso wie das Ereignis festgelegt wird, das einen Trigger auslöst, muß auch der Zeitpunkt festgelegt werden, zu dem die Aktionen gestartet werden sollen.</p>
3130<p>Dabei gibt es sechs verschiedene Möglichkeiten:</p>
3131<ul>
3132<li><strong>Einmalig</strong> vor Ausführung der auslösenden Anweisung ( BEFORE / FOR EACH STATEMENT)</li>
3133<li><strong>Einmalig</strong> anstatt der auslösenden Anweisung (INSTEAD / FOR EACH STATEMENT)</li>
3134<li><strong>Einmalig</strong> nach Ausführung der auslösenden Anweisung (AFTER / FOR EACH STATEMENT)</li>
3135</ul>
3136<hr />
3137<ul>
3138<li>Vor jeder Manipulation eines Datensatzes der zugrundeliegenden Tabelle (BEFORE / FOR EACH ROW)</li>
3139<li>Anstatt jeder Manipulation eines Datensatzes der zugrundeliegenden Tabelle (INSTEAD / FOR EACH ROW)</li>
3140<li>Nach jeder Manipulation eines Datensatzes der zugrundeliegenden Tabelle (AFTER / FOR EACH ROW)</li>
3141</ul>
3142<h2 id="skriptsprachen-..."><span class="header-section-number">7.2</span> Skriptsprachen <a href="#TOC">...</a></h2>
3143<ol start="110" class="example" style="list-style-type: decimal">
3144<li><p>Das Unternehmen "Best of Portugal" möchte seine Datenbank von SQLite nach MySQL portieren.</p>
3145<ol style="list-style-type: lower-alpha">
3146<li><p>Entwerfen Sie ein Script für diese Aufgabe.</p></li>
3147<li><p>Erörtern Sie mögliche Probleme.</p></li>
3148<li><p>Ermitteln Sie welche Datenbankschemata davon betroffen sind.</p></li>
3149</ol></li>
3150</ol>
3151<hr />
3152<ol style="list-style-type: lower-alpha">
3153<li><p>Das Script <strong>exportiert</strong> das konzeptionelle und externe Datenbankschema und die Datensätze in Form von <strong>"INSERT"-Statements</strong> aus der SQLite-Datenbank.</p>
3154<p>Danach werden diese Statements in MySQL <strong>importiert</strong>.</p></li>
3155<li><p>Die Implementierung des SQL-Standards unterscheidet sich in den DBMS voneinander. Eventuell müssen die Statements vor den Import noch <strong>geringfügig konvertiert</strong> werden.</p></li>
3156<li><p>Das interne Schema.</p></li>
3157</ol>
3158<p><strong>Das vollständige Script</strong></p>
3159<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="bu">:</span> Datenbank anlegen
3160<span class="ex">sqlite3</span> /tmp/emp.db <span class="op"><</span> /home/user/my/acha/etc/create_employee.sql.txt
3161
3162<span class="bu">:</span> Datenbank exportieren
3163<span class="bu">echo</span> .dump <span class="kw">|</span> <span class="ex">sqlite3</span> /tmp/emp.db <span class="op">></span> /tmp/export.sql
3164
3165<span class="bu">:</span> SQL-Script an MySQL anpassen
3166<span class="bu">echo</span> <span class="st">'CREATE DATABASE emp;'</span> <span class="op">></span> /tmp/modified.sql
3167<span class="bu">echo</span> <span class="st">'USE emp;'</span> <span class="op">>></span> /tmp/modified.sql
3168<span class="fu">sed</span> <span class="st">'/^PRAGMA\|^BEGIN/ d; s/"//g'</span> <span class="op"><</span> /tmp/export.sql <span class="op">>></span> /tmp/modified.sql
3169
3170<span class="bu">:</span> Datenbank importieren
3171<span class="fu">sudo</span> mysql <span class="op"><</span> /tmp/modified.sql</code></pre></div>
3172<!--
3173~~~ bash
3174cat > /tmp/port << 'EOF'
3175
3176 #!/bin/bash
3177
3178echo "USE $2;" > /tmp/x.sql
3179sqlite3 $1 <<< .dump | egrep -v '^PRAGMA|^BEGIN' | sed 's/"//g' >> /tmp/x.sql
3180
3181mysql -u root <<< "DROP DATABASE $2;" 2> /dev/null
3182mysql -u root <<< "CREATE DATABASE $2;"
3183mysql -u root < /tmp/x.sql
3184
3185EOF
3186
3187sqlite3 /tmp/x.db < /home/user/_my/my/zzz/zzz/www/etc/create_employee.sql.txt
3188chmod +x /tmp/port
3189/tmp/port /tmp/x.db emp
3190sudo mysqldump emp | grep -c PRESIDENT
3191~~~
3192-->
3193<h1 id="h.-administration-von-datenbanksystemen-..."><span class="header-section-number">8</span> H. Administration von Datenbanksystemen <a href="#TOC">...</a></h1>
3194<h2 id="installation-konfiguration-..."><span class="header-section-number">8.1</span> Installation, Konfiguration <a href="#TOC">...</a></h2>
3195<ol start="111" class="example" style="list-style-type: decimal">
3196<li>Der Systemadministrator eines Kleinunternehmens wurde damit beauftragt MongoDB zu installieren.</li>
3197</ol>
3198<blockquote>
3199<ul>
3200<li>Entwerfen Sie ein Verfahren, das dies ermöglicht.</li>
3201<li>Erläutern Sie die dazu notwendigen Kommandos.</li>
3202</ul>
3203</blockquote>
3204<hr />
3205<ol style="list-style-type: lower-alpha">
3206<li>Das Softwarepaket für den Server suchen: <code>apt-cache search [PAKET]</code></li>
3207<li>Überprüfen, ob das Paket bereits installiert wurde: <code>dpkg -l [PAKET]</code></li>
3208<li>Die Verbreitung des Pakets recherchieren: <a href="https://popcon.debian.org/stable/by_vote" class="uri">https://popcon.debian.org/stable/by_vote</a></li>
3209<li>Die Beschreibung des Pakets anzeigen: <code>apt-cache show [PAKET]</code></li>
3210<li>Das Verzeichnis der Softwarepakete aktualisieren: <code>sudo apt-get update</code></li>
3211<li>Das Paket installieren: <code>sudo apt-get install [PAKET]</code></li>
3212<li>Die installierten Dateien eines Pakets anzeigen: <code>dpkg -L [PAKET]</code></li>
3213</ol>
3214<hr />
3215<hr />
3216<ol start="112" class="example" style="list-style-type: decimal">
3217<li>Erläutern Sie die Installation, Konfiguration und Nutzung von mongodb.</li>
3218</ol>
3219<hr />
3220<p><strong>MongoDB installieren</strong></p>
3221<pre><code>sudo apt-get install -y mongodb-server</code></pre>
3222<p><strong>MongoDB-Shell konfigurieren</strong></p>
3223<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">---</span>~$ grep <span class="st">'^[^#]'</span> /etc/mongodb.conf
3224
3225<span class="va">dbpath=</span>/var/lib/mongodb
3226<span class="va">logpath=</span>/var/log/mongodb/mongodb.log
3227<span class="va">logappend=</span>true
3228<span class="ex">bind_ip</span> = 127.0.0.1
3229<span class="va">journal=</span>true</code></pre></div>
3230<p><strong>MongoDB-Shell starten</strong></p>
3231<pre><code>mongo</code></pre>
3232<p>Damit befinden wir uns in der interaktiven Konsole, ähnlich <code>sqlite3</code>, mit welcher wir zum Server und seinen Datenbanken verbunden sind.</p>
3233<p>Die Abfragesprache bei MongoDB ist dabei <code>JavaScript</code> und die Datensätze werden dementsprechend mit JSON erstellt und abgefragt.</p>
3234<hr />
3235<hr />
3236<ol start="113" class="example" style="list-style-type: decimal">
3237<li><p>Zeigen Sie die Nutzung von mongodb.</p>
3238<ul>
3239<li>Zeigen Sie alle Datenbanken.</li>
3240<li>Legen Sie eine Datenbank an.</li>
3241<li>Zeigen Sie deren Collections.</li>
3242<li>Legen Sie eine Collection an.</li>
3243<li>Fügen Sie zwei Dokumente ein.</li>
3244<li>Suchen Sie nach allen Dokumenten.</li>
3245<li>Suchen Sie ein einzelnes Dokument.</li>
3246<li>Löschen Sie ein Dokument.</li>
3247<li>Verändern Sie ein Dokument.</li>
3248</ul></li>
3249</ol>
3250<hr />
3251<div class="sourceCode"><pre class="sourceCode json"><code class="sourceCode json"><span class="er">show</span> <span class="er">dbs;</span>
3252
3253<span class="er">//</span> <span class="er">Neue</span> <span class="er">DB</span> <span class="er">anlegen</span> <span class="er">(implizit</span> <span class="er">durch</span> <span class="er">benutzen):</span>
3254<span class="er">use</span> <span class="er">test;</span>
3255
3256<span class="er">show</span> <span class="er">collections;</span>
3257<span class="er">//</span> <span class="er">Collections</span> <span class="er">entstehen</span> <span class="er">implizit,</span> <span class="er">indem</span> <span class="er">Dokumente</span> <span class="er">angelegt</span> <span class="er">werden.</span>
3258
3259<span class="er">//</span> <span class="er">Dokumente</span> <span class="er">einfügen:</span>
3260<span class="er">db.col.insert(</span><span class="fu">{</span><span class="er">a</span><span class="fu">:</span><span class="dv">1</span><span class="fu">,</span> <span class="er">b</span><span class="fu">:</span><span class="dv">2</span><span class="fu">,</span> <span class="er">c</span><span class="fu">:</span><span class="ot">[</span><span class="dv">1</span><span class="ot">,</span><span class="dv">2</span><span class="ot">,</span><span class="dv">3</span><span class="ot">]</span><span class="fu">}</span><span class="er">);</span>
3261<span class="er">db.col.insert(</span><span class="fu">{</span><span class="er">a</span><span class="fu">:</span><span class="dv">2</span><span class="fu">,</span> <span class="er">b</span><span class="fu">:</span><span class="dv">2</span><span class="fu">,</span> <span class="er">c</span><span class="fu">:</span><span class="st">"hallo"</span><span class="fu">}</span><span class="er">);</span>
3262
3263<span class="er">//</span> <span class="er">Alle</span> <span class="er">Dokumente</span> <span class="er">auflisten:</span>
3264<span class="er">db.col.find();</span>
3265
3266<span class="er">//</span> <span class="er">Dokumente</span> <span class="er">nach</span> <span class="er">Muster</span> <span class="er">finden:</span>
3267<span class="er">db.col.find(</span><span class="fu">{</span><span class="er">a</span><span class="fu">:</span><span class="dv">1</span><span class="fu">}</span><span class="er">);</span>
3268
3269<span class="er">//</span> <span class="er">Dokumente</span> <span class="er">löschen:</span>
3270<span class="er">db.col.remove(</span><span class="fu">{</span><span class="er">a</span><span class="fu">:</span><span class="dv">2</span><span class="fu">}</span><span class="er">);</span>
3271
3272<span class="er">//</span> <span class="er">Dokument</span> <span class="er">verändern:</span>
3273<span class="er">db.col.update(</span><span class="fu">{</span><span class="er">a</span><span class="fu">:</span><span class="dv">1</span><span class="fu">}</span><span class="er">,</span> <span class="fu">{</span><span class="er">b</span><span class="fu">:</span><span class="dv">3</span><span class="fu">,</span> <span class="er">c</span><span class="fu">:</span><span class="ot">[</span><span class="dv">1</span><span class="ot">]</span><span class="fu">}</span><span class="er">);</span>
3274
3275<span class="er">//</span> <span class="er">Hilfe</span> <span class="er">anzeigen:</span>
3276<span class="er">help</span></code></pre></div>
3277<hr />
3278<hr />
3279<ol start="114" class="example" style="list-style-type: decimal">
3280<li><p>Zeigen Sie die Nutzung von SQLite.</p>
3281<ul>
3282<li>Legen Sie eine Datenbank an.</li>
3283<li>Legen Sie eine Tabelle an.</li>
3284<li>Fügen Sie zwei Datensätze ein.</li>
3285<li>Suchen Sie nach allen Datensätzen.</li>
3286<li>Erstellen Sie eine View.</li>
3287<li>Löschen Sie eine View.</li>
3288<li>Verändern Sie einen Datensatz.</li>
3289<li>Löschen Sie einen Datensatz.</li>
3290<li>Erstellen Sei einen Index.</li>
3291</ul></li>
3292</ol>
3293<hr />
3294<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql">user@debian:~$ sqlite3 x.db # Legt die Datenbank an
3295<span class="co">-- Loading resources from /home/user/.sqliterc</span>
3296SQLite version <span class="fl">3.16.2</span> <span class="dv">2017-01-06</span> <span class="dv">16</span><span class="ch">:32:41</span>
3297Enter <span class="ot">".help"</span> <span class="kw">for</span> <span class="kw">usage</span> hints.
3298sqlite> <span class="kw">CREATE</span> <span class="kw">TABLE</span> t(f,g);
3299sqlite> .schema
3300<span class="kw">CREATE</span> <span class="kw">TABLE</span> t(f,g);
3301sqlite> <span class="kw">INSERT</span> <span class="kw">INTO</span> t <span class="kw">VALUES</span> (<span class="dv">1</span>, <span class="st">'hallo'</span>);
3302sqlite> <span class="kw">INSERT</span> <span class="kw">INTO</span> t (g, f) <span class="kw">VALUES</span> (<span class="st">'hi'</span>, <span class="dv">2</span>);
3303sqlite> <span class="kw">SELECT</span> * <span class="kw">FROM</span> t;
3304f g
3305<span class="co">------- ----------</span>
3306<span class="dv">1</span> hallo
3307<span class="dv">2</span> hi
3308
3309sqlite> <span class="kw">CREATE</span> <span class="kw">VIEW</span> v <span class="kw">AS</span> <span class="kw">SELECT</span> g <span class="kw">FROM</span> t;
3310g
3311<span class="co">-------</span>
3312hallo
3313hi
3314
3315sqlite> <span class="kw">DROP</span> <span class="kw">VIEW</span> v;
3316
3317sqlite> <span class="kw">UPDATE</span> t <span class="kw">SET</span> g=<span class="st">'bye'</span> <span class="kw">WHERE</span> f=<span class="dv">1</span>;
3318sqlite> <span class="kw">DELETE</span> <span class="kw">FROM</span> t <span class="kw">WHERE</span> f=<span class="dv">2</span>;
3319sqlite> <span class="kw">SELECT</span> * <span class="kw">FROM</span> t;
3320f g
3321<span class="co">------- ----------</span>
3322<span class="dv">1</span> bye
3323
3324sqlite> <span class="kw">CREATE</span> <span class="kw">INDEX</span> i <span class="kw">ON</span> t(f);</code></pre></div>
3325<h2 id="export-backup-..."><span class="header-section-number">8.2</span> Export, Backup <a href="#TOC">...</a></h2>
3326<!-- Alternative: sharding, start-stop-daemon, syslogd, pkill -->
3327<hr />
3328<hr />
3329<ol start="115" class="example" style="list-style-type: decimal">
3330<li><p>Der Datenbankadministrator möchte die Geschwindigkeit des DBMS erhöhen. Deshalb weist er SQLite an:</p>
3331<ul>
3332<li>temporäre Tabellen im Arbeitsspeicher abzulegen.</li>
3333<li>das Transaktionsprotokoll zu deaktivieren.</li>
3334</ul></li>
3335</ol>
3336<blockquote>
3337<ul>
3338<li>Entwerfen Sie ein Verfahren, das dies ermöglicht.</li>
3339<li>Erläutern Sie die dazu notwendigen Kommandos.</li>
3340</ul>
3341</blockquote>
3342<hr />
3343<pre><code> PRAGMA temp_store = MEMORY;
3344 PRAGMA journal_mode = OFF;</code></pre>
3345<ul>
3346<li><code>PRAGMA temp_store;</code> zeigt den aktuellen Wert an: 0 (Default, Meistens FILE), 1 (oder FILE), 2 (oder MEMORY)</li>
3347</ul>
3348<hr />
3349<hr />
3350<ol start="116" class="example" style="list-style-type: decimal">
3351<li>Beschreiben Sie die PRAGMA-Anweisung.</li>
3352</ol>
3353<hr />
3354<p>Die PRAGMA-Anweisung ist eine SQL-Erweiterung, die für SQLite spezifisch ist und verwendet wird,</p>
3355<ul>
3356<li>um die Arbeitsweise des DBMS zu beeinflussen</li>
3357<li>oder das DMBS nach internen Daten (ohne die normalen Tabellen) abzufragen.</li>
3358</ul>
3359<hr />
3360<hr />
3361<ol start="117" class="example" style="list-style-type: decimal">
3362<li>Erklären Sie das <strong>Logging und Recovery</strong> in DBMS.</li>
3363</ol>
3364<hr />
3365<p><strong>Logging und Recovery</strong> bezeichnet eine Sammlung von Maßnahmen und Techniken, um bei Datenbanksystemen nach einem Fehlerfall (z. B. nach einem Systemabsturz oder einem Ausfall von Festplatten) den Datenverlust zu verhindern und die Fehlerfreiheit (Konsistenz) der Datenbank weiterhin zu garantieren.</p>
3366<p>Das <strong>Transaktionsprotokoll</strong> schreibt im laufenden Betrieb alle Änderungen auf der Datenbank mit, und das <strong>Recovery</strong> stellt nach dem Fehlerfall (z. B. nach dem Reboot sofern ein Systemabsturz für den Fehler verantwortlich war) den letzten aktuellen (Verhinderung von Datenverlust) und fehlerfreien (konsistenten) Zustand der Datenbank wieder her.</p>
3367<p>Das Logging und Recovery ist somit verantwortlich für die Einhaltung der <strong>Konsistenz, Dauerhaftigkeit und Atomizität</strong> in einer Datenbank, drei der ACID-Eigenschaften.</p>
3368<hr />
3369<hr />
3370<ol start="118" class="example" style="list-style-type: decimal">
3371<li>Beschreiben Sie den Datenimport und Export in SQLite.</li>
3372</ol>
3373<hr />
3374<ul>
3375<li>Datenexport: <code>echo .dump | sqlite3 DB > FILE</code>
3376<ul>
3377<li>Exportiert werden Schema und Datensätze</li>
3378<li><code>.schema</code> zeigt nur das Schema</li>
3379<li>Man kann mit <code>.dump TABLE</code> auch einzelne Tabellen exportieren.</li>
3380</ul></li>
3381<li>Datenimport: <code>sqlite3 DB < FILE</code></li>
3382</ul>
3383<hr />
3384<hr />
3385<ol start="119" class="example" style="list-style-type: decimal">
3386<li>Beschreiben Sie Archivierung und den Wiederanlauf des DBMS SQLite.</li>
3387</ol>
3388<hr />
3389<ul>
3390<li>Archivierung: Sie müssen nur eine einzige Datei (die Datenbasis) kopieren.</li>
3391<li>Wiederanlauf: Zum Betrieb von SQLite müssen Sie nichts administrieren. Die Anwendungsprogramme greifen direkt über APIs auf die Datenbasis zu.</li>
3392</ul>
3393<hr />
3394<hr />
3395<ol start="120" class="example" style="list-style-type: decimal">
3396<li>Erläutern Sie die Besonderheiten von SQLite im Gegensatz zu einem Client-Server-DBMS.</li>
3397</ol>
3398<hr />
3399<dl>
3400<dt>.</dt>
3401<dd><img src="/home/user/acha/www-img/sql/sqlite-direct.jpg" />
3402</dd>
3403</dl>
3404<ul>
3405<li>Bei der Client-Server-Architektur greifen Anwendungsprogramme nicht direkt auf die Daten zu, sondern kommunizieren mit einem separaten Prozess (dem Datenbank-Managementsystem), der seinerseits die Daten verwaltet.</li>
3406<li>Bei SQLite liest und schreiben die Anwendungsprogramme die Daten direkt über APIs in die Datenbasis.</li>
3407</ul>
3408<hr />
3409<hr />
3410<ol start="121" class="example" style="list-style-type: decimal">
3411<li>Nennen und beschreiben Sie die Merkmale des DBMS SQLite.</li>
3412</ol>
3413<hr />
3414<ul>
3415<li>benötigt keine Konfiguration</li>
3416<li>benötigt keinen administrativen Aufwand für den Betrieb</li>
3417<li>Die Datenbasis besteht aus einer einzigen Datei</li>
3418<li>unterstützt einen Großteil der im SQL-92-Standard festgelegten SQL-Sprachbefehle.</li>
3419<li>ist Public Domain</li>
3420<li>bietet keine Nutzer- und Rechteverwaltung</li>
3421<li>hat keine Stored Procedures (kann also keine Programmlogik in der Datenbank speichern)</li>
3422</ul>
3423<hr />
3424<hr />
3425<ol start="122" class="example" style="list-style-type: decimal">
3426<li>Beschreiben Sie die Begriffe Datenbanksystem, Datenbankmanagementsystem und Datenbasis.</li>
3427</ol>
3428<hr />
3429<p><strong>Datenbanksysteme</strong> sind Hilfsmittel zur rechnergestützten Verarbeitung großer Datenbestände.</p>
3430<p>Ein Datenbanksystem besteht aus</p>
3431<ul>
3432<li>der <strong>Datenbasis</strong> (in der die Daten strukturiert gespeichert werden) und</li>
3433<li>dem Datenbankmanagementsystem (=Datenbankverwaltungssystem, DBMS).</li>
3434</ul>
3435<p>Das <strong>Datenbankmanagementsystem</strong> ist ein Programmsystem</p>
3436<ul>
3437<li>zum Aufbau,</li>
3438<li>zur Kontrolle und</li>
3439<li>zur Manipulation</li>
3440</ul>
3441<p>der Datenbasis.</p>
3442<p>Der Begriff <strong>Datenbank</strong> (DB) wird sowohl für die Datenbasis, als auch für das Datenbanksystem verwendet.</p>
3443</body>
3444</html>