\documentclass{schuleit}
\usepackage[utf8]{inputenc}
\usepackage{schulinf}
\usepackage{fancybox}

% Dieses Dokument ist in der Zusammenarbeit von Informatikreferendaren und
% ehemaligen Informatikreferendaren der Studienseminare (heute ZfsL) Arnsberg,
% Hamm und Solingen entstanden.
%
% Das Dokument steht unter der Lizenz: Creative Commons by-nc-sa Version 4.0
% http://creativecommons.org/licenses/by-nc-sa/4.0/deed.de
%
% Nach dieser Lizenz darf das Dokument beliebig kopiert und bearbeitet werden,
% sofern das Folgeprodukt wiederum unter gleichen Lizenzbedingungen vertrieben
% und auf die ursprünglichen Urheber verwiesen wird.
% Eine kommerzielle Nutzung ist ausdrücklich ausgeschlossen.
%
% Die Namensnennung durch einen Verweis und die Lizenzangabe der ursprünglichen
% Urheber auf den Materialien für Schülerinnen und Schüler ist erforderlich.
%
% Die Sammlung der Dokumente steht unter
% http://ddi.uni-wuppertal.de/material/materialsammlung/
% zur Verfügung.
%
% Das LaTeX-Paket zum Setzen der Dokumente der Sammlung steht
% unter  http://www.ctan.org/pkg/schule
% zur Verfügung.

\usepackage[pdfauthor={Referendare Informatikfachseminare Arnsberg und Hamm}]{hyperref}
\includexmp{lizenz}
\cclizenz{byncsaeu}
\footerQRLink{materialsammlung_qr_url.pdf}

\svnid{$Id: leitprogramm_datenbanken.tex 1570 2016-09-24 11:04:22Z pieper $}

\usepackage{todonotes}
\usepackage{comment}

%% das Gymnasium
\def\schule{König-Joseph-Gymnasium\xspace}
\def\aschule{das \schule}
\def\Aschule{Das \schule}
\def\dsschule{des \schule{}s\xspace}
\def\seineihre{seine\xspace}

\begin{comment}
%% die Gesamtschule
\def\schule{Willy-Brandt-Gesamtschule\xspace}
\def\aschule{die \schule}
\def\Aschule{Die \schule}
\def\dsschule{der \schule}
\def\seineihre{ihre\xspace}
\end{comment}

\usepackage{natbib}
\bibpunct{[}{]}{}{a}{}{,~}
\bibliographystyle{dinat}

\usepackage{colortbl, hhline}

% \jahrgang{Q2}

% \renewcommand\sectionmark[1]{\markboth{#1}{}}
% \chead{\leftmark}
% \ohead{Datenbanken}

% \renewcommand{\ttdefault}{pcr}
\usepackage{inconsolata}
\lstset{% 
	breaklines=true, % Zeilenumbrüche
	language=SQL, % Sprache
	basicstyle=\ttfamily,
	breakindent=1pt,
	breakatwhitespace=true,
	breakautoindent=false,
	tabsize=2,
	morekeywords={double,text,show,tables,use,is,truncate,rename,to,after,change},
	% numbers=left, numberstyle=\tiny,  numbersep=5pt,
	prebreak={} % Zeichen am Zeilenende (Umbruch)
}

\definecolor{Gray}{gray}{0.9}

% \makeatletter% siehe FAQ (aber wirklich nachsehen!)
% \newcommand*{\headingpar}{\par\nobreak\@afterheading}
% \makeatother% siehe FAQ

\newcommand{\monatWort}[1]{%
\ifcase #1
 Monat 0 \or Januar \or Februar \or März  \or April \or Mai \or Juni \or Juli%
 \or August \or September \or Oktober \or November \or Dezember\fi}

\begin{document}
	\begin{titlepage}
		\begin{center}
			\begin{Large}
				Leitprogramm
			\end{Large}
		\end{center}

		\begin{center}
			\begin{huge}
				\textbf{Datenbanken}
			\end{huge}
		\end{center}

		\begin{center}
			Stand \svnday. \monatWort{\svnmonth} \svnyear 
		\end{center}

		\tableofcontents

	\end{titlepage}

\chapter{Vorwort}

Im deutschen Sprachgebrauch wird der Computer oft als Rechner bezeichnet. Doch anstatt mathematische Probleme zu lösen, dient der heimische Computer vielen Menschen als bessere Schreibmaschine und Abspielgerät von digitalen Werken. Die weitere Aufgabe, die  Computern zukommt, nehmen viele Menschen nur indirekt wahr: Das Verwalten von Daten. Diese Aufgabe beherrschen Computer so gut, dass sie an immer mehr Stellen zum Einsatz kommen und schon allgemein von einer \enquote{Datensammelwut} gesprochen wird.

Daher ist es angebracht, einen Blick hinter die Kulissen dieser Sammler und Verwalter von Daten zu werfen. Es gilt, die Methoden und Werkzeuge kennen zu lernen, sie selber in eigene Programme einzubauen und die Risiken und Auswirkungen auf uns als Person und unsere Gesellschaft abzuschätzen. 

Begonnen wird mit einer Problemstellung, die mit bekannten Methoden aus der Objektorientierung analysiert wird. Dafür wird eine eigene Datenbank aufgebaut, mit der gearbeitet werden soll, so dass sich die Problemstellung als roter Faden durch das Thema zieht. Doch zu Beginn gibt es erst ein paar Fragen zur eigenen Einschätzung und zum eigenen Vorwissen:

\begin{Aufgaben} \label{Vorwort}
	\item Da Datenbanken anscheinend so gegenwärtig sein sollen, sind Sie hier dazu aufgefordert, anzugeben, wo Sie direkt oder indirekt mit Datenbanken in Berührung kommen oder gekommen sind.
	\TextFeld{4cm}

	\item Erläutern Sie, welche Aufgaben und welchen Zweck die verwendeten Datenbanken aus den oben aufgezählten Punkten haben.
	\TextFeld{4cm}

	\item Geben Sie an, wie Sie die Nützlichkeit der Datenbanken einschätzen und für wen dieser Nutzen besteht.
	\TextFeld{4cm}

	\item Jede Technologie hat auch ihre Schattenseiten. Führen Sie die Gefahren von Datenbanken an, die Sie bereits kennen.
	\TextFeld{4cm}

\end{Aufgaben}

\section*{Datenstrukturen und Datenbanken}
\addcontentsline{toc}{section}{Datenstrukturen und Datenbanken}

Im Unterricht wurden verschiedene Datenstrukturen aufgezeigt, mit denen sich Daten verwalten lassen: Lineare Strukturen, wie die Liste oder der Stapel, und komplexere wie Bäume und Graphen. Ähnlich verhält es sich mit Datenbanken. Sie strukturieren Daten und erlauben es, in ihnen die Daten zu suchen, einzufügen oder sie zu löschen.

\begin{Aufgaben}
	\item Zählen Sie die Punkte auf, in denen sich ihrer Meinung nach die bisherigen Datenstrukturen von Datenbanken unterscheiden.
	\TextFeld{4cm}

\end{Aufgaben}

\chapter{Verwaltung von Schülern} %Nicht Gendermäßig korrekt, aber sorgt für passende Umbrüche

\Aschule möchte \seineihre \SuS nicht mehr nur auf Papier erfassen, sondern endlich dem Fortschritt folgen und dieses elektronisch machen. Bei diesem Schritt sollen auch gleich ein paar andere Sachen mit erfasst werden. Um die Anforderungen besser fassen zu können, haben Sie eine Situation schriftlich festgehalten, die mit der Verwaltung umsetzbar sein muss:

\vspace{-0.4cm}
\begin{center}
	\fbox{\parbox{0.96\textwidth}{
		Die beiden Schülerinnen Eva Meier und Claudia Görtz kommen nach einem Umzug zum 2.~Halbjahr an \aschule. Bei der Erfassung ihrer Daten gibt Eva an, dass sie am 24.~Januar~1998 geboren wurde und in der Holzgasse~42 in 98\,765~Posbed wohnt. Da sie in die Stufe Q1 geht, wird sie von der Jahrgangsstufenbetreuerin Frau Umardo in Empfang genommen. Diese teilt Eva unter anderem dem Informatikkurs Q1-IF2 bei Frau Petermann, dem Pädagogikkurs Q1-PA1 bei Herrn Küsters und dem Mathematikkurs Q1-M4 bei ihr selbst zu. Außerdem erhält Eva einen Stundenplan. In diesem erkennt sie die Kürzel ihrer Lehrer: Pet, Kue und Uma.

		Auch Claudia gibt ihre Daten an. Sie ist am 17.~April~1999 geboren und wohnt nun auf dem Holzpfad~23 in 98\,789 Umsstadt. Sie wird vom Stufenbegleiter der Einführungsphase, Herrn Hospital (Hos), begrüßt. Auf ihrem Stundenplan sieht sie, dass sie im Mathematikkurs E-M2 bei Frau Umardo und im Physikkurs E-PH1 von Frau Hellfeuer (Hel) ist.
	}}
\end{center}\vspace{-0.4cm}

Um von dieser Situationsbeschreibung über eine Modellierung zu einer konkreten Datenbankstruktur zu gelangen, bedient man sich z.\,B. des Verfahrens von Abbott, das aus dem Unterricht bekannt ist. Dabei werden aus dem Text Kandidaten für Objekte, Methoden und Attributwerte herausgesucht, um diese anschließend verschiedenen Objekten zuzuordnen.

\begin{Hinweis}
	Neben der Methode von Abbott gibt es auch andere Möglichkeiten, eine Modellierung anzugehen. Sollte Ihnen diese Methode nicht bekannt sein, so wenden Sie ihre Methode an, um an die nötigen Objekte und Klassen zu gelangen, die für eine Realisierung der oberen Situationsbeschreibung nötig sind.
\end{Hinweis}

\begin{Aufgaben}
	\item Beschreiben Sie den genauen Ablauf des Verfahrens von Abbott inklusive der Erstellung der Objektkarten.
	\TextFeld{2cm}

	\item Füllen Sie die folgende Tabelle mit Kandidaten.\\
	\begin{tabular}{l|l|l}
		Objekte & Methoden & Attributwerte \\ \hline
		\makebox(120,180)[b]{\TextField[width=.28\textwidth, height=6cm,multiline=true,borderwidth=0]{}} &
		\makebox(120,180)[b]{\TextField[width=.28\textwidth, height=6cm,multiline=true,borderwidth=0]{}} &
		\makebox(120,180)[b]{\TextField[width=.28\textwidth, height=6cm,multiline=true,borderwidth=0]{}} \\
	\end{tabular}

	\item Erstellen Sie aus den Kandidaten Objektkarten und fügen Sie diese zu einem Objektdiagramm zusammen.
\end{Aufgaben}

\section{Sequenzdiagramm}
Im nächsten Schritt wird zum Objektdiagramm ein Sequenzdiagramm erstellt, das alle Interaktionen zwischen den Objekten wiedergibt. Damit lässt sich genauer analysieren, ob alle benötigten Methoden und Attribute vorhanden sind und welche Beziehungen die Objekte untereinander eingehen müssen. 

\begin{Aufgaben}
	\item Erstellen Sie für die Situationsbeschreibung ein Sequenzdiagramm. Nutzen Sie dabei das Objektdiagramm als Grundlage, die sie an den notwendigen Stellen ergänzen.
\end{Aufgaben}

\section{Klassendiagramm}\label{Klassendiagramm}
Objekte, die sich in den Methoden und Attributen überschneiden, lassen sich zu Klassen zusammenfassen, die einen gemeinsamen Bauplan darstellen. Zu beachten dabei ist, dass die im Objektdiagramm vorhanden Beziehungen als Beziehungsattribute zwischen den Klassen erhalten bleiben. Dabei gilt es auch, die Anzahl der beteiligten Objekte auf den beiden Seiten einer Beziehung zwischen zwei Klassen zu ermitteln. Diese sind als Kardinalzahlen mit im Diagramm anzugeben.

\begin{Aufgaben}
	\item Fertigen Sie ein Klassendiagramm auf der Grundlage Ihres Objektdiagramms an, mit der sich die Situationsbeschreibung umsetzen lässt.
\end{Aufgaben}

\section[ER-Modell]{Entity-Relationship-Modell}
Das Entity-Relationship-Modell (kurz ER-Modell) ist eine Möglichkeit zur Darstellung der Struktur von Daten. Ein solches Modell wird für Projekte erstellt, damit sie als Grundlage für das Design einer relationalen Datenbank dienen können. Es kann als Vorläufer des Klassenmodells bezeichnet werden, das erst wesentlich später entstanden ist. 

\begin{center}
	\input{er_beispiel.cir}
\end{center}

Hier dargestellt ist das Beispiel eines ER-Modells für ein Geschäft. Es besteht aus Attributen, Entitätstypen und Beziehungen (Relationships). 

\section{Entitäten}
Die Entitäten aus dem ER-Modell sind am besten mit Objekten zu vergleichen. Innerhalb der Zeichnung werden die Entitätstypen in Rechtecken gezeichnet. Die zu einem Entitätstyp gehörenden Attribute (Eigenschaften) stehen in Ellipsen, die mit dem Entitätstyp verbunden sind. Im oberen Beispiel ist also \enquote{produkt} ein Entitätstyp mit den Attributen \enquote{name}, \enquote{bestellnr} und \enquote{preis}.

\section{Beziehungen}
Zwischen diesen Entitätstypen sind mit Rauten die Beziehungen eingezeichnet. Wie auch in Klassendiagrammen lassen sich hier  Kardinalzahlen angeben. Im oberen Beispiel gibt es die \enquote{gehört zu}-Beziehung zwischen Produkt und Kategorie. Dabei ist jedes Produkt mindestens einer Kategorie zugeordnet. Es kann aber auch Kategorien geben, zu denen es kein Produkt gibt. Natürlich sind auch Beziehungen zum gleichen Entitätstyp möglich.

\section{Schlüssel im ER-Modell}
Im Beispiel ist zu erkennen, dass einige Attribute unterstrichen sind. Dieses bedeutet, dass es sich hierbei um Schlüsselattribute handelt. Ein Schlüsselattribut ist dadurch gekennzeichnet, dass sich dadurch eine einzelne Entität von allen anderen Entitäten des gleichen Typs unterscheiden lässt. Die Werte müssen also eindeutig sein. Dieses könnte z.\,B. bei einem Produkt die Bestellnummer sein, unter der es in einem Laden zu bekommen ist. Außerdem soll für ein solches Schlüsselattribut sichergestellt sein, dass sich dieses Attribut nicht ändert.

Es ist aber auch möglich, dass ein solcher eindeutiger Schlüssel erst durch die Kombination von mehreren Attributen entsteht. So geht man z.\,B. davon aus, dass die Kombination aus Geburtsname, Vorname, Geburtstag und Geburtsort eindeutig für eine einzelne Person ist, während jedes Attribut für sich alleine auf viele Personen zutreffen würde. Da ein solcher Schlüssel sich nicht in jedem Fall finden lässt, wird häufig ein weiteres Attribut als künstlicher Schlüssel hinzugenommen. Eine Möglichkeit dafür wäre eine fortlaufende Nummer, die dann als Identifikationsnummer oder kurz ID bezeichnet wird.

\begin{Aufgaben}
	\item Zählen Sie fünf frei wählbare Beispiele für Entitätstypen auf, bei denen Sie die Schlüs\-sel\-attribute angeben. Unter den Beispielen sollen alle drei Formen (einfacher, zusammengesetzter und künstlicher) Schlüssels vorkommen. Begründen Sie die Wahl des Schlüsselattributs und geben Sie die Schlüsselform mit an.
	\TextFeld{2cm}

	\item Überführen Sie das im Abschnitt \ref{Klassendiagramm} erstellt Klassendiagramm für die Verwaltung von \SuSn in ein ER-Modell.
\end{Aufgaben}



\chapter{Relationale Datenbanken}
Aufgrund des Schemas, wie Daten zusammengefasst und geordnet sind, unterscheidet man die Arten von Datenbanksystemen. Neben relationalen Datenbanksystemen gibt es auch noch objektorientierte und hierarchische Datenbanksysteme. Im Unterricht werden aber nur relationale Datenbanken behandelt, da die Systeme dafür sehr ausgereift und schnell sind. Zusätzlich gibt es die grundlegende Sprache \enquote{Structured Query Language} oder kurz SQL, die bei fast allen Datenbankanwendungen Verwendung findet.

Ein Relationenschema setzt sich aus mehreren Attributen zusammen. Eine Relation zu einem Relationenschema ist eine Menge von Tupeln, die zu dem Relationenschema passen. Hier ein Beispiel: Ein Relationenschema zur Speicherung von Kundendaten bekommt den Namen \texttt{kunde} und hat die Attribute kundennr, passwort, name, adresse, telefon, geburtsdatum und eMail, wobei kundennr als Schlüssel dient. Das Relationenschema wird wie folgt aufgeschrieben:

\begin{center}
  \texttt{kunde(\underline{kundennr}, passwort, name, adresse, telefon, geburtsdatum, eMail)}
\end{center}

Relationen können auch als Tabellen dargestellt werden. Die Attribute des Relationenschemas bilden bei der Relation die Spaltenüberschriften und die Zeilen sind die Tupel.

\begin{tabular}{l|l|l|l|l|l}
	\multicolumn{1}{c}{\textbf{Relationenname}} & \multicolumn{1}{c}{\textbf{Schlüssel}} & \multicolumn{1}{c}{} & \multicolumn{1}{c}{\textbf{Attribut}} & \multicolumn{1}{c}{} & \multicolumn{1}{c}{} \tabularnewline

	\hhline{*{5}{-}}
	
	\multicolumn{1}{|r|}{\cellcolor[gray]{0.9}kunde} & \multicolumn{1}{c|}{\fcolorbox{Gray}{Gray}{\underline{kundennr}}} & \multicolumn{1}{c|}{passwort} & \multicolumn{1}{c|}{\fcolorbox{Gray}{Gray}{name}} & \ldots & \textbf{Relationenschema} \tabularnewline
	
	\hhline{*{5}{-}}

	& BT02 & saibot & Tobias Bayer & \ldots & \tabularnewline

	\hhline{~*{4}{-}} 
	& \fcolorbox{Gray}{Gray}{MK07} & \fcolorbox{Gray}{Gray}{nairolf} & \fcolorbox{Gray}{Gray}{Knut Maier} & \ldots & \textbf{Tupel} \tabularnewline
	
	\cline{2-5} 
	& \ldots & \ldots & \ldots & \ldots & \tabularnewline
	\cline{2-5} 
\end{tabular}

Eine komplette Datenbank setzt sich aus mehreren Relationen bzw. Tabellen zusammen, die jeweils einem Relationenschema entsprechen. Die Relationenschemata bilden dabei das Datenbankschema für die gesamte Datenbank.

Hinter diesem Aufbau durch Relationen gibt es auch eine theoretische Grundlage. Diese wird durch die Relationale Algebra bzw. das Relationenkalkül beschrieben. 

\section{Die Sprache SQL und MySQL} \label{Sprache_SQL}
Die Datenbanksprache SQL unterscheidet sich in ihrer Struktur vollkommen von den bisher kennengelernten Programmiersprachen. Daher ist es nötig, eine komplett neue Sprache zu lernen. SQL ist aber im Bereich der relationalen Datenbanken die Standard-Sprache,
so dass sie sowohl bei dem hier eingesetzten System MySQL als auch bei anderen relationalen Datanbanksystemen genutzt werden kann. Die möglichen geringfügigen Unterschiede sind in den hier thematisierten Bereichen nicht relevant.

Die Grundbefehle von SQL lassen sich nach drei verschiedenen Aufgabenbereichen sortieren: Die Struktur der Tabellen festlegen, Daten in den Tabellen beeinflussen und Daten aus den Tabellen abfragen. Zur Struktur der Tabellen gehören die Befehle \lstinline|CREATE| (erzeugen), \lstinline|ALTER| (verändern) und \lstinline|DROP| (entfernen). Das Verändern der Daten funktioniert mit \lstinline|INSERT INTO| (einfügen), \lstinline|UPDATE| (aktualisieren) und \lstinline|DELETE| (löschen). Für das Abfragen der Daten gibt es nur den Befehl \lstinline|SELECT| (auswählen), dessen Aufbau aber sehr komplex gestaltet werden kann. 

Das Prinzip des Aufbaus von SQL-Befehlen lässt sich an einer einfachen \lstinline|SELECT|-Abfrage verdeutlichen: Es werden die Namen und Preise aller Produkte vom Hersteller Augusto gesucht. Dazu nimmt man die einfachste Form der Abfrage: \lstinline|SELECT <spalten> FROM <tabelle> WHERE <bedingung>;|. Für eine Datenbank, die nach dem ER-Modell aus dem Beispiel aufgebaut ist, müsste man nun also die Spalten \enquote{name} und \enquote{preis} aus der Tabelle \enquote{Produkt} wählen. Mit der entsprechenden Bedingung sieht dann die Anfrage so aus: \lstinline|SELECT name, preis FROM produkt WHERE hersteller = 'Augusto';|. 

Genauso wie in der Sprache Java wird auch in SQL jeder Befehl mit einem Semikolon beendet. Die schrägen Hochkommata sind bei den Spaltenbezeichnern und Tabellen nur dann nötig, wenn diese Sonderzeichen oder Leerzeichen enthalten. Die Zeichenkette in der Bedingung muss aber in jedem Fall mit Hochkommata abgegrenzt werden. Anstatt bei einer größeren Tabelle alle Spalten einzeln aufzuzählen, kann man auch ein Asterix (\(\ast\)) verwenden, wie in der folgenden Abfrage: \lstinline|SELECT * FROM produkt WHERE hersteller = 'Augusto';|. Der genauere Aufbau, auch der anderen Befehle, wird nun schrittweise erarbeitet. 


\section{Das Hilfsmittel phpMyAdmin}
Um mit der Datenbank arbeiten zu können, benötigt man Hilfsmittel, mit denen man auf sie zugreift. Ein übersichtliches aber auch mächtiges Hilfsmittel ist phpMyAdmin, das auf einem Server installiert sein muss und über einen Webbrowser bedient wird. Hiermit kann man sich leicht den Inhalt der Tabellen anzeigen lassen, sowie Tabellen und Daten erstellen, ändern und löschen. Dazu sind keine Kenntnisse von SQL nötig, da die meisten Funktionen sich über einfache Formulare erledigen lassen. Dabei wird nach dem Absenden des Formulars der zur Anweisung gehörende SQL-Befehl angezeigt. Gleichzeitig bietet phpMyAdmin die Möglichkeit SQL-Befehle selbst anzugeben und auszuführen.

Nach dem Einloggen in phpMyAdmin hat man auf der linken Seite ein Menü, mit dem man die Datenbank und ggf. die Tabelle auswählen kann, mit der man arbeiten möchte. Je nach Auswahl ändert sich der rechte Inhaltsbereich und bietet einem über die oberen Reiter verschiedene fast selbsterklärende Optionen. Im Schulnetzwerk ist phpMyAdmin unter \url{http://db-server/phpmyadmin} zu erreichen.

\begin{Aufgaben}
	\item Lassen Sie sich in der Datenbank \enquote{sportverein} die Tabellen \enquote{mitglieder} und \enquote{sportart} anzeigen und schreiben Sie für beide jeweils das Relationenschema auf.
	\AufgabenLoesung{\texttt{sportverein (\underline{id}, name, anschrift, eintrittsjahr, geschlecht, \textuparrow zahlt)}\\ \texttt{sportart (\underline{name}, bemerkung)}\\}
	\TextFeld{2cm}

	\item Geben Sie den SQL-Befehl an, mit dem phpMyAdmin die Inhalte von Tabellen anzeigt und erläutern Sie seinen Aufbau.
	\AufgabenLoesung{\lstinline|SELECT * FROM mitglieder LIMIT 0 , 30|\\ Er wählt so alle Attribute der Tabelle mitglieder aus. Es werden aber nur die ersten dreißig dargestellt.}
	\TextFeld{2cm}
\end{Aufgaben}


\section{Die Bedienung in der MySQL-Konsole}
Neben aufwendigen Oberflächen ist es auch möglich, direkt über die Konsole mit dem Datenbanksystem zu kommunizieren. Dazu dient das Programm mysql, dass auf dem entsprechenden Rechner installiert sein muss. Eine Installationsanleitung dazu können Sie auch im Anhang \ref{installation_mysql} finden. Über die Programmparameter lässt sich angeben, mit welchem Datenbanksystem gearbeitet werden soll, welcher Benutzer sich einloggt und auch, welche Datenbank genutzt wird. Der Aufruf mit allen aufgezählten Parametern ist so aufgebaut: \lstinline[language=bash]|mysql -u <benutzer> -p -D <datenbankname> -h <MYSQL-Server>|. Dieses sieht dann so aus: \lstinline|mysql -u q2mustermann -p -D q2 -h db-server|. Das \lstinline|-p| ohne weitere Angabe des Passworts sorgt dafür, dass man dieses geschützt eingeben kann. Wenn man mit der Konsole arbeitet sind folgende Befehle nützlich:
\begin{smallitemize}
	\item \lstinline|USE <datenbank>;| Wechselt die Datenbank, in der gearbeitet wird.
	\item \lstinline|SHOW TABLES;| Zeigt an, welche Tabellen in der aktuellen Datenbank vorhanden sind.
	\item \lstinline|DESCRIBE <tabelle>;| Zeigt das Schema der Tabelle an.
\end{smallitemize}

Die Konsole wird auch genutzt um viele Befehle auf einmal, wie z.\,B. bei einem Import durchzuführen. Alle Anweisungen stehen dann in einer Datei, deren Inhalt wird, wie hier im Beispiel angegeben, dem Aufruf mit übergeben: \lstinline[language=bash]|mysql -u meier -p -D mitglieder -h db-server < neu_mitglieder.sql|.

\begin{Aufgaben}
	\item Lassen Sie sich das Schema der Tabelle \enquote{mitglieder} in der Datenbank \enquote{sportverein} anzeigen und geben Sie dieses hier an:
% 	\AufgabenLoesung{\begin{verbatim}
% +---------------+--------------+------+-----+---------+----------------+
% | Field         | Type         | Null | Key | Default | Extra          |
% +---------------+--------------+------+-----+---------+----------------+
% | id            | int(11)      | NO   | PRI | NULL    | auto_increment |
% | name          | varchar(100) | NO   |     | NULL    |                |
% | anschrift     | text         | NO   |     | NULL    |                |
% | eintrittsjahr | int(11)      | NO   |     | NULL    |                |
% | geschlecht    | varchar(2)   | NO   |     | NULL    |                |
% | zahlt         | varchar(30)  | NO   |     | NULL    |                |
% +---------------+--------------+------+-----+---------+----------------+
% 6 rows in set (0.00 sec)	          
% 	         \end{verbatim}
% 	}
	\TextFeld{5cm}

	\item Beschreiben Sie, wie die Ausgabe von Daten in der Konsole dargestellt wird.
	\AufgabenLoesung{Es wird mit entsprechenden ASCII-Zeichen eine Tabelle erstellt und diese mit den Inhalten gefüllt. Die Spaltenköpfe enthalten jeweils die Attributnamen}
	\TextFeld{4cm}
\end{Aufgaben}

 
\chapter{Umsetzung des ER-Modells in eine relationale Datenbank}
Bei der Überführung eines ER-Modells in eine relationale Datenbank müssen entsprechende Tabellen aufgebaut werden. Dabei gilt die Grundformel, dass sich aus jedem Entitätstyp und jeder Beziehung auch eine eigene Tabelle ergibt. Aus mehreren Gründen wird von dieser Grundformel aber bei den Beziehungen abgewichen.

\section{Anlegen der Tabellen für Entitäten}
Der SQL-Befehl \lstinline|CREATE TABLE <tabellenname> (<attribute>);| erstellt eine neue Tabelle in der Datenbank. Die Attribute werden dabei durch Kommata getrennt und das Schlüsselattribut mit \lstinline|PRIMARY KEY| gekennzeichnet. Zusätzlich muss man für jedes Attribut den Typ in der Datenbank auswählen. Die wichtigsten Typen sind folgende:
\begin{smallitemize}
	\item \lstinline|INT| eine Ganzzahl.
	\item \lstinline|DOUBLE| eine Gleitkommazahl.
	\item \lstinline|VARCHAR| eine Zeichenkette, deren maximale Länge man angeben muss.
	\item \lstinline|TEXT| ein Textblock in dem auch Umbrüche möglich sind.
	\item \lstinline|TIME| eine Uhrzeit.
	\item \lstinline|DATE| ein Datum.
\end{smallitemize}

Für den Entitätstyp "`Produkt"' aus dem Beispiel ER-Modell würde dann die Erzeugung der Tabelle so aussehen:
\begin{lstlisting}
CREATE TABLE produkt (
  bestellnr INT,
  name VARCHAR(50),
  preis DOUBLE,
	PRIMARY KEY (bestellnr)
);
\end{lstlisting}

\begin{Aufgaben}
	\item Erstellen Sie auf Grundlage ihres ER-Modells die nötigen Tabellen für alle Entitätstypen in ihrer eignen Datenbank.
\end{Aufgaben}

\section{Umsetzung der Beziehungen}\label{umsetzung_beziehung}
Immer dann, wenn bei einer Beziehung, wie \enquote{gehoert zu} aus dem  Beispiel, für beide Seiten mehrere Möglichkeiten bestehen, wird eine Tabelle benötigt die mindestens zwei Spalten für die Schlüssel der beteiligten Entitätstypen hat. Zusätzlich kann eine solche Beziehung noch eigene Attribute haben. In dem Beispiel könnte man so eintragen, wann die Zuordnung zur Kategorie getroffen wurde. 

Hat man eine Beziehung, bei der einer Entität maximal eine andere zugeordnet wird, so kann man auf diese zusätzliche Tabelle verzichten und direkt in der einen Tabelle ein Attribut für das Schlüsselattribut der anderen Tabelle eintragen. Für die Beziehung \enquote{produziert von} aus dem Beispiel bedeutet dieses, dass die Tabelle \enquote{Produkt} eine weitere Spalte \enquote{hersteller} bekommt, in der immer der eindeutige Name des Herstellers eingetragen wird. Das Relationenschema sieht für Produkt so aus:
\begin{center}
	\texttt{Produkt(\underline{bestellnr}, name, preis, \textuparrow hersteller)}
\end{center}
Der Pfeil vor dem Attribut \enquote{hersteller} deutet an, dass es sich hierbei um einen Fremdschlüssel handelt, der eine Beziehung zu einer anderen Tabelle aufbaut.

Eine zusätzliche Spalte kann man mit dem SQL-Befehl \lstinline|ALTER TABLE <tabellenname> ADD <attributname> <attributtyp>;| an das Ende der Tabelle hinzufügen. Für das obere Beispiel wäre es: \lstinline|ALTER TABLE produkt ADD hersteller VARCHAR(100);|.

\begin{Aufgaben}
	\item Geben Sie das Relationenschema für die Beziehung \enquote{gehört zu} und den Entitätstyp \enquote{kategorie} aus dem Beispiel an. 
	\AufgabenLoesung{
		\texttt{gehoertzu (\underline{\textuparrow produkt}, \underline{\textuparrow kategorie})}\\ \texttt{kategorie (\underline{name}, \textuparrow unterkategorie)}\\
	}
	\TextFeld{2cm}

	\item Ergänzen Sie ihre Datenbank so, dass auch alle Beziehungen aus dem ER-Modell darin abgebildet werden können.
\end{Aufgaben}



\chapter{Einfügen, Ändern und Löschen von Daten}

Das Einfügen in Tabellen erfolgt mit dem \lstinline|INSERT INTO| Befehl, mit dem auch gleichzeitig mehrere Datensätze eingefügt werden können:

\lstinline|INSERT INTO <tabelle> (<spaltennamen>) VALUES (<werte>),(<werte2>);|

Hierbei müssen nicht immer alle Spalten der Tabelle angegeben werden. Es ist auch möglich Datensätze anzulegen, bei denen nicht für alle Spalten Werte vorliegen. Innerhalb eines Befehls müssen aber zu jeder angegebenen Spalte auch immer ein entsprechender Wert angegeben sein, wie hier im Beispiel:
\begin{lstlisting}
INSERT INTO lehrer (name, vorname, kuerzel) VALUES 
	('Kersten', 'Annegret', 'KA'), 
	('Pichel', 'Manfred', 'PI'), 
	('Vohken', 'Tobias', 'VO');
\end{lstlisting}

\begin{Aufgaben}
	\item Fügen Sie die nötigen Datensätze in ihre Datenbank ein, damit diese die Problembeschreibung wiedergibt.

	\item Bei Fehleingaben oder Änderungen müssen auch die Datensätze korrigiert werden. Erarbeiten Sie den Aufbau des SQL-Befehls \lstinline|UPDATE|.
	\AufgabenLoesung{\lstinline|UPDATE <tabelle> SET <attribut> = <attributwert> WHERE <bedingung>;|\\
		Man gibt an, ich welcher Tabelle es Änderungen geben soll. Dann muss man die Attribute mit ihren neuen Attributwerten angeben. Sind es mehrere, so müssen sie durch Kommata getrennt werden. Anschließend muss man noch die Bedingung angeben, bei welchen Datensätzen diese Änderung überhaupt vorgenommen werden soll.
	}
	\TextFeld{4.5cm}

	\item Auch das Löschen muss eine Datenbank ermöglichen. Verfahren Sie beim SQL-Befehl \lstinline|DELETE| genauso wie beim \lstinline|UPDATE|.
	\AufgabenLoesung{\lstinline|DELETE FROM <tabelle> WHERE <bedingung>;|\\
		Hier wird die Tabelle angegeben, in der Datensätze gelöschten werden soll. Welche dieses sind, wird durch die Bedingung festgelegt.
	}
	\TextFeld{4.5cm}

	\item Fügen Sie weitere Datensätze ihrer Tabellen hinzu, um eine Grundlage für die weitere Arbeit zu haben.
\end{Aufgaben}


\chapter{Auswahl von Datensätzen} \label{auswahl}
Der Befehl für die Auswahl und Anzeige von Datensätzen ist der \lstinline|SELECT|-Befehl, der bereits in \ref{Sprache_SQL} kurz vorgestellt wurde. Dabei wurde aber nur die einfachste Möglichkeit gezeigt. Ihre Stärken spielt eine relationale Datenbank erst dann aus, wenn verschiedene Dinge miteinander kombiniert werden. Im ersten Schritt kann dieses durch die Kombination und Verneinung von Bedingungen über die Wörter \lstinline|AND|, \lstinline|OR| und \lstinline|NOT| geschehen.

\begin{Aufgaben}
	\item Erstellen Sie eine Abfrage, die ihnen alle Schüler ihrer eigenen Datenbank liefert, die nicht in der Stufe Q1 sind und geben Sie diese hier an. Überprüfen Sie diese Anfrage auch im System.
	\AufgabenLoesung{\lstinline|SELECT * FROM schueler WHERE stufe NOT LIKE 'Q1';| oder \lstinline|SELECT * FROM schueler WHERE stufe != 'Q1';|}
	\TextFeld{2cm}

	\item Es sollen nur alle Kurse ausgegeben werden, die von Herrn Hospital oder Frau Umardo unterrichtet werden. Geben Sie eine entsprechende SQL-Anweisung hier an und überprüfen Sie diese.
	\AufgabenLoesung{\lstinline|SELECT * FROM kurse WHERE lehrer = 'Hospital' OR lehrer = 'Umardo';|}
	\TextFeld{2cm}
\end{Aufgaben}

\section{Vergleichsoperatoren}
In den bisherigen Abfragen wurden nur direkte Vergleiche mit dem Gleichheitszeichen durchgeführt. Bei Zahlenwerten können aber auch Größenvergleiche durchgeführt werden. Dazu dienen die aus anderen Bereichen bekannten Vergleichsoperatoren \lstinline|>| \lstinline|<|, \lstinline|>=| und \lstinline|<=|. Um auf Ungleichheit zu testen kann sowohl \lstinline|<>| als auch \lstinline|!=| genutzt werden.

Durch die Verknüpfung mit einem \lstinline|AND| kann man so Elemente in einem Bereich auswählen. Dafür bietet MySQL die einfache Möglichkeit eines \lstinline|BETWEEN <min> AND <max>| an. Ähnlich sieht es aus, wenn man verschiedene Werte für ein Attribut zutreffen dürfen. Diese müssen nicht mit \lstinline|OR| verknüpft werden, sondern können als Aufzählung \lstinline|IN (<wert1>, <wert2>, <wert3>)| aufgeführt werden. Alle Werte sind dabei durch Komma separiert.

Ist ein Attributwert nicht gesetzt, so kann dieses mit Hilfe von \lstinline|IS NULL| überprüft werden. Bei Zeichenketten bietet der Vergleich mit \lstinline|LIKE| auch weitere Unterscheidungsmög\-lich\-kei\-ten als das Gleichheitszeichen. In dem angegeben Vergleichswert können zusätzlich auch \lstinline|%| und \lstinline|_| angegeben werden. Dabei steht das Prozentzeichen für beliebig viele Zeichen, während der Unterstrich genau für ein einzelnes Zeichen steht. So liefert eine Suche mit \lstinline|name LIKE 'B%n'| auch Namen wie Benjamin, Ben aber Bn. Bei \lstinline|name LIKE 'B_n'| würde nur Ben aus den vorherigen Beispielen in der Ergebnismenge vorkommen. Diese Steuerzeichen können innerhalb des Suchwertes auch mehrfach vorkommen und miteinander kombiniert werden. Sucht man aber das Prozentzeichen oder den Unterstrich, so muss man dieses mit \lstinline|\%| bzw. \lstinline|\_| machen.

\begin{Aufgaben}
	\item Geben Sie das Äquivalent der Anfrage \lstinline|SELECT * FROM mitglieder WHERE eintrittsjahr BETWEEN 1980 AND 2000;| an, dass nicht mit \lstinline|BETWEEN| funktioniert.
	\AufgabenLoesung{\lstinline|SELECT * FROM mitglieder WHERE eintrittsjahr >= 1980 AND eintragen <= 2000;|}
	\TextFeld{1.5cm}

	\item Schreiben Sie die Namen auf, die die Anfrage \lstinline|SELECT name  FROM mitglieder WHERE name LIKE '%a%er';| auf die Datenbank des Sportvereins liefert. Über\-prüfen Sie dieses anschließend durch das Ausführen der Abfrage.
	\AufgabenLoesung{Franziska Weber, Christina Schreiner, Alexander Beyer, Tobias Zimmer}
	\TextFeld{1.5cm}
\end{Aufgaben}

\section{Abfrage über mehrere Tabellen}
Durch das Setzen der Beziehungen liegen viele Informationen über mehrere Tabellen verteilt. Daher kann man eine Abfrage auch an mehrere Tabellen gleichzeitig stellen. Dazu müssen nur die Tabellennamen durch Komma getrennt im \lstinline|FROM|-Teil angegeben werden. Sollten dabei Attribute in den verschiedenen Tabellen die gleichen Namen tragen, so kann man vor den Attributnamen, wie bei \lstinline|Produkt.name| den Tabellennamen mitangeben.

\begin{Aufgaben}
	\item Lassen Sie sich gleichzeitig den Inhalt der Tabellen \enquote{mitglieder} und \enquote{tarif} aus der Datenbank \enquote{sportverein} anzeigen. Erläutern Sie das Ergebnis ihre Anfrage.
	\AufgabenLoesung{\lstinline|SELECT * FROM mitglieder, tarif;| Nun wird jeder Datensatz von Mitglieder mit jedem Datensatz von tarif kombiniert. Das Ergebnis nennt man auch ein Kartesisches Produkt.}
	\TextFeld{1.5cm}
	
	\item Verändern Sie durch Bedingungen ihre obige Anfrage, so dass sie sinnvolle Ergebnisse erhalten. Schreiben Sie ihre Anfrage hier auf:
	\AufgabenLoesung{\lstinline|SELECT * FROM mitglieder, tarif WHERE mitglieder.zahlt = tarif.name;|}
	\TextFeld{1cm}
\end{Aufgaben}

\section{Kartesisches Produkt}
Wird eine Abfrage über zwei Tabellen durchgeführt, so wird jede Zeile der ersten Tabelle mit jeder Zeile der zweiten Zeile verknüpft. Dieses nennt man das kartesische Produkt. Durch eine Bedingung, bei der zwei Attribute aus den beiden Tabellen übereinstimmen müssen, kann man dafür sorgen, dass nur solche Zeilen ausgewählt werden, bei denen es auch eine Übereinstimmung gibt. So würde man bei dem Verknüpfen von Mitgliedern und Tarifen die Bedingung \lstinline|mitglieder.zahlt = tarif.name| setzen. 

Da bei einigen Fällen die Abfragen sehr groß und unübersichtlich werden können, besonders wenn mehrere Bedingungen zutreffen müssen, gibt es die Möglichkeit Abkürzungen einzufügen. Mit dem Wort \lstinline|AS| kann man sowohl Tabellennamen als auch Attribute abkürzen oder auch umbenennen. So könnte die obige Abfrage auch so aussehen: \lstinline|SELECT * FROM mitglieder AS m, tarif AS t WHERE m.zahlt = t.name;|.

\begin{Aufgaben}
	\item Entwickeln Sie eine Abfrage, die ihnen zu jedem Schüler aus ihrer Datenbank den Stufenbegleiter angibt. Dabei sollen nur die Namen des Schülers und des Lehrers angegeben werden. Nutzen Sie dazu entsprechende Abkürzungen um die Attribute deutlich voneinander unterscheiden zu können und geben Sie ihre Anfrage hier an:
	\AufgabenLoesung{\lstinline|SELECT s.name AS schuelername, kurs.lehrer AS lehrername FORM schueler AS s, stufe WHERE schueler.stufe = stufe.name;|}
	\TextFeld{1cm}

\end{Aufgaben}

\section{Join}
Eine äquivalente Abfrage zu der Verknüpfung der beiden Tabellen \enquote{mitglieder} und \enquote{tarif} kann auch mit Hilfe von \lstinline|JOIN| erzielt werden: \lstinline|SELECT * FROM mitglieder JOIN tarif ON mitglieder.zahlt = tarif.name;|. Dieses ist deshalb interessant, weil der Join um weitere Eigenschaften erweitert werden kann. So liefert die Anfrage \lstinline|SELECT * FROM mitglieder LEFT JOIN vorstand ON mitglieder.id = vorstand.id;| alle Mitglieder und gibt an, wenn sie einen Vorstandsposten haben. Bei allen Mitgliedern, die keinen Vorstandsposten haben wird der Wert für den Posten in der Ergebnistabelle auf NULL gesetzt. 

Bei einer solchen Abfrage spricht man von einem Left-Join. Analog dazu gibt es auch einen Right-Join, bei dem auch alle Vorstandsposten aufgezählt würden, die nicht besetzt sind.

\begin{Aufgaben}
	\item Vollziehen Sie die oben angegeben Abfragen auf der Datenbank nach.

	\item Lassen Sie sich alle Mitglieder mit den Sportarten ausgeben und schreiben Sie diese Anfrage hier auf:
	\AufgabenLoesung{\lstinline|SELECT * FROM mitglieder LEFT JOIN teilnehmen ON mitglieder.id = teilnehmen.id;|}
	\TextFeld{3cm}

	\item Entwickeln Sie Anfragen, mit denen Sie nur die Namen der aktiven bzw. passiven Mitglieder ausgeben. Passive Mitglieder sind solche, die an keiner Sportart teilnehmen. Geben Sie die Anfragen auf und geben Sie Schönheitsfehler in den Ergebnissen mit an. Hinweis: Bedingungen bzgl. NULL müssen \lstinline|IS NULL| oder \lstinline|IS NOT NULL| lauten.
	\AufgabenLoesung{Aktive Mitglieder: \lstinline|SELECT * FROM mitglieder LEFT JOIN teilnehmen ON mitglieder.id = teilnehmen.id WHERE teilnehmen.name IS NOT NULL;| \\
		Passive Mitglieder: \lstinline|SELECT * FROM mitglieder LEFT JOIN teilnehmen ON mitglieder.id = teilnehmen.id WHERE teilnehmen.name IS NULL;|
	}
	\TextFeld{3cm}

\end{Aufgaben}

\section{Projektion}
Bei der letzten Aufgabe trifft man auf ein nicht befriedigendes Ergebnis: Bei den aktiven Mitgliedern kommen einige Namen doppelt vor. An dieser Stelle hilft die Projektion. Bei der Projektion werden Zeilen in der Ergebnistabelle, die in allen Attributen übereinstimmen, auf eine einzelne Spalte projiziert. Dieses lässt sich durch das Schlüsselwort \lstinline|DISTINCT| direkt hinter dem \lstinline|SELECT| erreichen. So taucht im Beispiel der aktiven Mitglieder jeder Name, bzw. die Kombination aus id und Name nur einmal auf, je nachdem, was in der Anfrage mit ausgegeben werden sollte.

\begin{Aufgaben}
	\item Verbessern Sie ihre Anfrage aus der letzten Aufgabenstellung.
	\TextFeld{3cm}
	
	\item Erläutern Sie, weshalb die Projektion bei einem \lstinline|SELECT DISTINCT * FROM| bei der Ausgabe der aktiven Mitglieder scheinbar keine Wirkung zeigt.
	\AufgabenLoesung{Ein \lstinline|DISTINCT| fasst nur solche Zeilen zusammen, die in allen Attributen übereinstimmen.}
	\TextFeld{5cm}
\end{Aufgaben}


\chapter{Änderungen an Tabellen}
Im Abschnitt \ref{umsetzung_beziehung} wurde bereits deutlich, dass beim Anlegen der Tabellen in der Datenbank nicht immer alle Punkte richtig beachtet wurden. In solchen Fällen kann es nötig werden, Tabellen zu entfernen oder ihre Struktur zu verändern. Dieses kann das bereits vorgestellte Hinzufügen von Attributen sein. Es ist aber auch möglich, Attribute zu entfernen, ihren Typ zu ändern oder auch den Schlüssel einer Tabelle neu zu setzen. Dabei ist aber Vorsicht geboten. Gerade bei großen Datenbanken können solche Änderungen zu Problemen führen und dauern in der Regel sehr lange.

\section{Tabellen löschen, leeren oder umbenennen}
Das Löschen von Tabellen geschieht einfach mit dem Befehlt \lstinline|DROP TABLE <tabelle>;|. Damit werden alle Daten und die Struktur der Tabelle gelöscht. Will man hingegen nur eine Tabelle leeren, so kann man \lstinline|TRUNCATE TABLE <tabelle>;| nutzen, was auch den Vorteil hat, dass ein möglicher Zähler für eine eindeutige ID wieder zurückgesetzt wird. Mit \lstinline|RENAME TABLE <altername> TO <neuername>;| erfolgt ein mögliches Umbenennen einer Tabelle. 

\section{Struktur der Tabellen bearbeiten}
Mit \lstinline|ALTER TABLE <tabelle> ADD <attributname> <attributtyp>;| wird, wie bereits geschrieben eine neues Attribut hinzugefügt. Dieses wird immer an das Ende der Relation an gehangen. Es lässt sich aber auch ein \lstinline|FIRST| oder \lstinline|AFTER <attributname>| an den Befehl anhängen, um so die Position zu beeinflussen. Das Entfernen eines Attributs geschieht mit \lstinline|ALTER TABLE <tabelle> DROP COLUMN <attributname>;|.


Sowohl das Umbenennen eines Attributs als auch das Ändern seines Typs geschieht mit Hilfe des Befehls \lstinline|ALTER TABLE <tabelle> CHANGE <altername> <neuername> <attributtyp>;|. Soll also nur der Typ geändert werden, so müssen der alte und der neue Name identisch sein. Analog muss bei einer Umbenennung immer der bisherige Typ mit angegeben werden.

\section{Schlüssel ändern}
Soll im Nachhinein ein Schlüssel für eine Tabelle gesetzt werden, so geschieht dieses mit \lstinline|ALTER TABLE <tabelle> ADD PRIMARY KEY (<attribut>);|. Sollen zwei oder mehrere Attribute gemeinsam den Schlüssel bilden, so können sie innerhalb der Klammen durch Komma getrennt aufgeführt werden. Will man den Schlüssel auf ein anders Attribut ändern, so muss dieser erst mit \lstinline|ALTER TABLE <tabelle> DROP PRIMARY KEY;| von der Tabelle entfernt werden, bevor er anschließend neu gesetzt wird.


\chapter{Normalisierung}
Bei der Arbeit mit Datenbanken besteht das Ziel darin, möglichst einfach Daten miteinander verknüpfen und  einzelne Daten abfragen zu können. Um dieses zu ermöglichen und über\-prüf\-bar zu machen, werden Datenbanken mittels der Normalisierung in eine Normalform überführt. Je nachdem, wie weit man diese Normalisierung durchführt, werden unterschiedliche aufeinander aufbauende Normalformen erreicht. Hier betrachten wir nur die drei ersten Normalformen.

\section{1.~Normalform}
Eine Datenbank liegt dann in der ersten Normalform vor, wenn folgendes auf sie zutrifft:
\begin{center}
	\fbox{\parbox{.87\textwidth}{
		Die Datenbank enthält nur atomare Attribute.
	}}
\end{center}
Dieses bedeutet, dass nur einfache und nicht zusammengesetzte Attribute erlaubt sind. Ein klassisches Beispiel ist die Adresse, die sich aus den einzelnen Attributen Straße, Postleitzahl und Ort zusammensetzt und daher für die erste Normalform in unterschiedlichen Attributen erfasst werden muss. 

Eine weitere Möglichkeit der Verletzung der ersten Normalform liegt in einer Aufzählung. Ein solcher Fall liegt in der folgenden Tabelle bei den Herstellungsangaben vor, in die angelieferten Produkte eines Ladens aufgelistet sind:

\begin{small}
	\begin{tabular}{|l|l|l|l|l|}
		\hline
		\underline{bestellnr} & name & hersteller & ort & herstellungsangaben \\
		\hline \hline
		834949 & Gulaschsuppe & Magnat & Datteln & 39232988: 14.05.13, 39232993: 15.05.13 \\
		834154 & Erbsensuppe & Magnat & Datteln & 39234540: 04.08.13, 39234546: 05.08.13 \\
		154648 & Bohnen & B \& B & Zürich & 45421544: 01.06.13 \\
		\hline 
	\end{tabular}
\end{small}

Die Herstellungsangaben beinhalten dabei die Chargennummer und das Herstellungsdatum. Die Chargennummer bezeichnet dabei die laufende Nummer, die vergeben wird, wenn in einem Topf eine neue Portion angerührt wird, aus dem dann in die Einzelverpackungen abgefüllt wird. Um diese Tabelle in die erste Normalform zu bringen, muss für jede Chargennummer eine neue Zeile eingeführt werden. Dabei wird die Chargennummer zu einem neuen Schlüssel, da die Bestellnummer nicht mehr eindeutig ist.

\begin{small}
	\begin{tabular}{|l|l|l|l|l|l|l|}
		\hline
		\underline{bestellnr} & name & hersteller & ort & \underline{chargennummer} & datum \\
		\hline \hline
		834949 & Gulaschsuppe & Magnat & Datteln & 39232988 & 14.05.13\\
		834949 & Gulaschsuppe & Magnat & Datteln & 39232993 & 15.05.13 \\
		834154 & Erbsensuppe & Magnat & Datteln & 39234540 & 04.08.13\\
		834154 & Erbsensuppe & Magnat & Datteln & 39234546 & 05.08.13 \\
		154648 & Bohnen & B \& B & Zürich & 45421544 & 01.06.13 \\
		\hline 
	\end{tabular}
\end{small}

\begin{Aufgaben}
	\item Begründen Sie, weshalb die Datenbank \enquote{sportverein} nicht in der ersten Normalform vorliegt. Geben Sie außerdem die Befehle an, mit der die Struktur der Datenbank entsprechend geändert wird.
	\TextFeld{1.7cm}

	\item Zählen Sie Vorteile auf, die sich durch die Umformung in die erste Normalform ergeben.
	\TextFeld{3cm}

	\item Überführen Sie ihre Datenbank für \aschule  in die erste Normalform.
\end{Aufgaben}


\section{2.~Normalform}
Eine Datenbank, die die obere Tabelle mit den angelieferten Waren enthält, ist nicht in der zweiten Normalform. Für sie gilt nicht die folgende Bedingung:

\begin{center}
	\fbox{\parbox{.87\textwidth}{
		Die Datenbank entspricht der 1. Normalform und jedes nicht Schlüsselattribut hängt vom ganzen Schlüssel der jeweiligen Tabelle ab (Wenn die Tabelle zwei Schlüssel enthält, müssen alle Attribute auch von beiden Schlüsseln abhängig sein).
	}}
\end{center}

Die in der Bedingung angesprochene Abhängigkeit hat folgende Bedeutung: Wenn ein Attribut A von einem anderen Attribut B abhängig ist, dann ist bei einem gleichbleibenden Wert für das Attribut B der Wert für das Attribut A immer gleich.

In dem Beispiel ist die Bedingung für die zweite Normalform durch die Spalten \enquote{name}, \enquote{hersteller} und \enquote{ort} verletzt. Dieses lässt sich daran erkennen, dass eine Änderung der Chargennummer keine Änderung in diesen Attributen nötig macht. Daher wird die einzelne Tabelle in zwei Tabellen aufgespalten:

\begin{small}
	\begin{tabular}{|l|l|l|l|l|l|l|l|l|}
		\cline{1-4}\cline{6-8}
		\underline{bestellnr} & name & hersteller & ort & & \underline{bestellnr} & \underline{chargennummer} & datum \\
		\cline{1-4}\cline{6-8}
		834949 & Gulaschsuppe & Magnat & Datteln & & 834949 & 39232988 & 14.05.13\\
		834154 & Erbsensuppe  & Magnat & Datteln & & 834949 & 39232993 & 15.05.13 \\
		154648 & Bohnen & B \& B & Zürich & & 834154 & 39234540 & 04.08.13\\
		\cline{1-4}
		\multicolumn{4}{l}{} & & 834154 &  39234546 & 05.08.13 \\
		\multicolumn{4}{l}{} & & 154648 & 45421544 & 01.06.13 \\
		\cline{6-8}
	\end{tabular}
\end{small}

\begin{Aufgaben}
	\item Bei dieser Normalform geht es besonders darum, doppelte Speicherung von Informationen zu vermeiden. Erläutern Sie die Vorteile dieser Reduzierung.
	\TextFeld{3cm}

	\item Sehr wahrscheinlich wird sich ihre Datenbank \dsschule bereits in der zweiten Normalform befinden, nachdem Sie die Regeln für die erste Normalform darauf angewandt haben. Überprüfen Sie, ob Ihre Datenbank in der zweiten Normalform vorliegt. Wenn ja, geben Sie an, an welcher Stelle Sie bereits dafür gesorgt haben.
	\TextFeld{3cm}

	\item Wenn Ihre Datenbank noch nicht in der zweiten Normalform vorliegt, ändern Sie diese entsprechend.
\end{Aufgaben}

\section{3.~Normalform}
Oft gibt es diese Mehrfachspeicherung von Daten nicht nur in Abhängigkeit von Schlüs\-sel\-attributen, wie sie mit der zweiten Normalform aufgelöst wurden, sondern auch in Abhängigkeit von anderen Attributen. Ein bekanntes Beispiel ist hier eine Postleitzahl, die in Deutschland in den meisten Fällen eindeutig einer Stadt zugeordnet ist. Um diese Mehrfachspeicherung aufzulösen wird eine Datenbank in die dritte Normalform gebracht:
\begin{center}
	\fbox{\parbox{.87\textwidth}{
		Die Datenbank entspricht der 2.~Normalform und es gibt keine Abhängigkeiten zwischen nicht Schlüsselattributen (Ein Attribut hängt nicht von einem anderen nicht Schlüsselattribut ab).
	}}
\end{center}

Das oben genannte Beispiel befindet sich auch nicht in der dritten Normalform. Die Herstellungsadresse und damit hier der Ort ist vom Hersteller abhängig. Deshalb müsste dieser aus der ersten Tabelle heraus gelöst werden:

\begin{small}
	\begin{tabular}{|l|l|l|l|l|l|l|l|}
		\cline{1-3}\cline{5-7}
		\underline{bestellnr} & name & hersteller & & \underline{bestellnr} & \underline{chargennummer} & datum \\
		\cline{1-3}\cline{5-7}
		834949 & Gulaschsuppe & Magnat & & 834949 & 39232988 & 14.05.13\\
		834154 & Erbsensuppe  & Magnat & & 834949 & 39232993 & 15.05.13 \\
		154648 & Bohnen & B \& B & & 834154 & 39234540 & 04.08.13\\
		\cline{1-3}
		\multicolumn{3}{l}{} & & 834154 &  39234546 & 05.08.13 \\
		\cline{1-2}
		\underline{hersteller} & ort & \multicolumn{2}{l|}{} & 154648 & 45421544 & 01.06.13 \\
		\cline{1-2}\cline{5-7}
		Magnat & Datteln \\
		B \& B & Zürich \\
		\cline{1-2}
	\end{tabular}
\end{small}

\begin{Aufgaben}
	\item Im oberen Beispiel wird davon ausgegangen, dass jeder Hersteller nur an einem Ort produziert. Äußern Sie sich bezüglich der Bedingung für die dritte Normalform, wenn dieses nicht der Fall ist.
	\TextFeld{3cm}

	\item Überprüfen Sie, ob ihre Datenbank in der dritten Normalform vorliegt und ändern Sie diese sonst entsprechend.
\end{Aufgaben}

\section{Grenzen der Normalisierung}
Besonders aus Effizienzgründen bei Abfragen kommt es vor, dass Datenbanken nicht bis zur dritten Form normalisiert werden. So kann es ein großer Geschwindigkeitsvorteil sein, wenn bei einer großen Anzahl von Abfragen nicht erst mehrere riesige Tabellen miteinander verknüpft werden müssen. Damit einher geht aber, dass Daten mehrfach vorliegen und es dabei auch zu Inkonsistenzen kommen kann. Diese liegen dann vor, wenn an verschiedenen Stellen die eigentlich gleichen Daten unterschiedlich sind.

Arbeitet man mit nicht normalisierten Datenbanken, so muss man in den Programmen, die auf der Datenbank agieren, durch entsprechende Strukturen dafür Sorge tragen, dass alle Daten konsistent sind. Dieses gilt besonders für das Ändern von Einträgen. Aber auch beim Löschen muss darauf geachtet werden, dass alle Einträge korrekt und entfernt werden.


\chapter{Einbinden in Java Programme}
Java bietet die Möglichkeiten, innerhalb eines Programms Anfragen an eine MySQL-Datenbank zu stellen. Innerhalb des Pakets java.sql befinden sich die nötigen Klassen um allgemein mit SQL zu arbeiten. Zusätzlich wird noch der für MySQL passende Treiber \enquote{org.gjt.mm.mysql.Driver} benötigt, der die Verbindung zur MySQL-Datenbank herstellt. Dieser ist in der Regel nicht bei Java mitgeliefert, sondern muss nachinstalliert werden.

Mit einem kleinen Programm lässt sich testen, ob dieser Treiber richtig installiert ist und sich auch laden lässt. Dabei sollten die Hinweise aus dem Anhang \ref{javatreiber} beachtet werden.
\lstinputlisting[language=Java,basicstyle=\ttfamily\small, numbers=left, numberstyle=\tiny,  numbersep=5pt]{LoadDriver.java}
Das Laden des Treibers geschieht hier in einer try-catch-Umgebung, die dafür sorgt, dass bei auftretenden Fehlern das Java-Programm nicht komplett beendet wird, sondern auf die Fehler reagiert werden kann. Dieses sollte bei allen MySQL-Befehlen durchgeführt werden, weil nicht zu jeder Zeit sichergestellt ist, ob die Verbindung zur Datenbank aufgebaut werden kann und ob z.\,B. die Datenbankstruktur mit der Abfrage übereinstimmt.

\begin{Aufgaben}
	\item Überprüfen Sie mit dem oben angegebenen Programm die Korrektheit der Treiberinstallation auf ihrem System.
\end{Aufgaben}

\section{Verbindung aufbauen}
Nach dem Laden des Treibers muss eine Verbindung mit der Datenbank aufgebaut werden. Mit folgenden Zeilen, die auch wieder in einem try-catch-Block stehen sollten, bekommt man ein Connection-Objekt:
\begin{lstlisting}[language=java, numbers=left, numberstyle=\tiny,  numbersep=5pt]
String url = "jdbc:mysql://"+hostname+":"+port+"/"+dbname;
Connection conn = DriverManager.getConnection(url, user, password); 
Statement stmt = conn.createStatement(); 
\end{lstlisting}
Mit Hilfe dieses Connection-Objekts kann man, wie in der dritten Zeile angegeben, ein Statement-Objekt bekommen. Dieses ist nötig um Abfragen und Anweisungen an die Datenbank zu senden. Dabei ist zu beachten, dass beim oberen Beispiel die Variablen für z.\,B. den Hostname zuvor entsprechend gesetzt sein müssen.

\section{Abfrage absetzen und auswerten}
Mit dem Statement-Objekt, lassen sich die MySQL-Anweisungen auf der Datenbank ausführen. Dazu übergibt man die Anweisung der Methode \lstinline[language=Java]{executeQuery(String Query)} als Zeichenkette, wie im folgenden Beispiel:
\begin{lstlisting}[language=java, numbers=left, numberstyle=\tiny,  numbersep=5pt]
String sqlCommand = "SELECT * FROM mitglieder;"; 
ResultSet rs = stmt.executeQuery(sqlCommand); 
\end{lstlisting}

Die Antwort auf die Anfrage wird in einem ResultSet-Objekt zurückgegeben. Liefert die Anfrage eine Tabelle, so kann diese mithilfe einer internen Referenz wie eine Liste durchwandert werden. Zu Beginn steht diese Referenz immer vor der ersten Zeile und kann mit den Methoden \lstinline[language=Java]{next()} und \lstinline[language=Java]{previous()} vor und zurück bewegt werden.

Wie im folgenden Beispiel zu erkennen ist, kann man mit verschiedenen get-Methoden auf die Elemente in den gewünschten Typen zugreifen. Dabei kann die Angabe der Spalte sowohl über den Namen, als auch ihre Nummer geschehen. Dabei ist zu beachten, dass die Spalten von eins an durchnummeriert sind. So werden nacheinander alle Zeilen des Resultats durchlaufen.

\begin{lstlisting}[language=java, numbers=left, numberstyle=\tiny,  numbersep=5pt]
while (rs.next()) { 
	int id = rs.getInt(1);
	String name = rs.getString(2); 
	String anschrift = rs.getString("anschrift"); 
	System.out.println(id + " " + name + " " + anschrift); 
} 
\end{lstlisting}

\begin{Aufgaben}
	\item Erstellen Sie ein Java-Programm, mit dem Sie zuerst immer die Betreuungslehrer und andere Informationen über eine Stufe ausgegeben werden. Daran anschließend sollen die Schüler einer jeden Stufe ausgeben werden.
\end{Aufgaben}

\section{Beispielprogramm}
Ein komplettes Java-Programm, dass alle beschriebenen Element beinhaltet sieht dann wie folgt aus:
\lstinputlisting[language=java, numbers=left, numberstyle=\tiny,  numbersep=5pt, basicstyle=\ttfamily\small]{SimpleDbExample.java}


\chapter{Weitere Abfragen}
Die in Abschnitt \ref{auswahl} gezeigten Möglichkeiten für Datenbankanfragen stellen nur einen kleinen Ausschnitt der Möglichkeiten dar. Besondere Stärke spielt SQL dann aus, wenn man Abfragen miteinander kombiniert oder auch eingebaute Funktionen nutzt, mit denen man Ergebnisse manipulieren oder ausrechnen lassen kann. Diese Möglichkeiten werden in diesem Abschnitt gezeigt. 

\section{Zusammenfassen von Anfragen}
Es kommt vor, dass man verschiedene Tabellen in einer Datenbank hat, die eine sehr ähnliche Relation besitzen. Dieses ist zum Beispiel bei den Lehrern und den Schülern der Fall. Gibt es Fälle, in denen man auf beide gleichzeitig zugreifen will, so muss man die Ergebnisse der Anfragen zusammensetzen. Dieses könnte der Fall sein, wenn man eine Gesamtliste der Schulgemeinschaft erhalten will. In MySQL gelingt dieses Zusammenfügen mit dem Schlüsselwort \lstinline|UNION|, das zwischen zwei Abfragen gesetzt werden muss wie hier: \lstinline|SElECT name FROM lehrer UNION SELECT name FROM schueler;|. Wichtig ist dabei, dass beide Anfragen die gleiche Anzahl an Attributen besitzen und auch die Reihenfolge übereinstimmt.

\begin{Aufgaben}
	\item Lassen Sie sich alle Mitglieder und Trainer des Vereins gemeinsam angeben. Schreiben Sie die dazu nötige Abfrage hier auf und geben Sie an, was mit Personen passiert, die gleichzeitig Mitglied und als Trainer tätig sind.
	\AufgabenLoesung{\lstinline|SELECT name, anschrift, geschlecht FROM mitglieder UNION SELECT name, anschrift, geschlecht FROM trainer;|} 
	\TextFeld{3cm}
\end{Aufgaben}

\section{Anfragen auf Ergebnisse von Anfragen (Unterabfragen)}
Eine Stärke von SQL ist es, dass das Ergebnis einer Anfrage auch direkt wieder in einer nächsten Anweisung eingesetzt werden kann. So kann die Tabelle, die eine Anfrage liefert auch direkt mit einer anderen verknüpft werden oder darauf auch wieder eine andere Anfrage gestartet werden. Das häufigste Beispiel ist aber, dass die Anfrage mehrere Werte liefert, die für eine Bereichsabfrage mit \lstinline|IN| durchgeführt werden soll. So möchte man z.\,B. alle Mitglieder des Sportvereins haben, die einen Posten im Vorstand haben. Auf den Join soll verzichtet werden. Daher liefert \lstinline|SELECT id FROM vorstand| eine Liste mit den ID-Nummern, der Mitglieder die einen solchen Posten haben. Zusammengesetzt zur Abfrage \lstinline|SELECT name FROM mitglieder WHERE id IN (SELECT id FROM vorstand);| bekommt man nun alle Namen der Vorstandsmitglieder aufgelistet.

\begin{Aufgaben}
	\item Das Mitglied \enquote{Christina Schreiner} will an der Sportart \enquote{Schwimmen} teilnehmen. Geben Sie die entsprechende Anweisung an, mit dem dieses in die Datenbank des Sportvereins aufgenommen wird. Verzichten Sie dabei auf direkte Angaben weiterer Werte, wie z.\,B. der ID.
	\AufgabenLoesung{\lstinline|INSERT INTO teilnehmen (id, name) VALUES ((SELECT id FROM mitglieder WHERE name = "Christina Schreiner"),"Schwimmen")|}
	\TextFeld{1cm}
\end{Aufgaben}

\section{Sortieren}
Bei alle Anfragen die an das Datenbanksystem gestellt werden, sind die Elemente in der Antwort in der Reihenfolge aufgeführt, wie sie auch in der Datenbank selber vorliegen. Da dieses aber nicht immer den eigenen Wünschen entspricht, kann man die \lstinline|SELECT|-Anweisung um ein \lstinline|ORDER BY <spaltenname>| ergänzen. Dabei wird standardmäßig aufsteigend sortiert. Dieses kann man aber auch mit dem Schlüsselwort \lstinline|ASC| zusätzlich festlegen. Die Gegenrichtung erfolgt mit \lstinline|DESC|. 

Eine Sortierung alle Mitglieder nach ihrem Eintrittsjahr erfolgt daher mit \lstinline|SELECT * FROM mitglieder ORDER BY eintrittsjahr ASC;|. Möchte man mehrere Sortierungskriterien anwenden, so können diese wieder mit Komma getrennt hintereinander geschrieben werden. So sortiert \lstinline|SELECT * FROM mitglieder ORDER BY eintrittsjahr DESC, name ASC| erst absteigend nach dem Eintrittsjahr und dann als zweites nach dem Namen.

\section{Funktionen}
Bei jeder Anfrage, die man an das Datenbanksystem stellt, wird auch immer die Anzahl der betroffen Zeilen mit angegeben. Dafür wird intern die Zählfunktion \lstinline|COUNT(*)| genutzt, die auch direkt genutzt werden kann. Jede Funktion wird bei einer Abfrage anstelle eines ausgewählten Attributs angegeben. So zählt \lstinline|SELECT COUNT(*) FROM mitglieder;| die Mitglieder und gibt die Anzahl aus.

Weitere Funktionen sind \lstinline|SUM(<spalte>)| um die Werte der übergebenen Spalte zu summieren, \lstinline|MAX(<spalte>)| und \lstinline|MIN(<spalte>)| um das Maximum oder das Minimum einer Spalte zu finden.

\begin{Aufgaben}
	\item Bestimmen Sie die Einnahmen, die der Sportverein laut Datenbank durch die Mitgliedsbeiträge erhält.
	\AufgabenLoesung{Die Abfrage \lstinline|SELECT SUM(tarif.preis) FROM mitglieder JOIN tarif ON mitglieder.zahlt = tarif.name;| liefert 1868.}
	\TextFeld{1cm}
\end{Aufgaben}

\section{Arithmetik}
Neben dem Ausführen von Funktionen kann man innerhalb von Abfragen auch Rechnungen mit \lstinline|+|,\lstinline|-|,\lstinline|*| und \lstinline|/|. Auch lassen sich Klammern setzen, um die Reihenfolge zu beeinflussen. So liefert die Abfrage \lstinline|SELECT SUM(preis) / COUNT(*) FROM tarif;| den durchschnittlichen Preis aller Tarife des Sportvereins. Gleiches würde aber auch die Funktion \lstinline|AVG(<spalte>)| liefern.

\section{Gruppieren}
Mit der Möglichkeit durch \lstinline|GROUP BY <spalte>| innerhalb einer Abfrage Gruppen zu erstellen, werden besonders die Möglichkeiten der eingebauten Funktionen erweitert. Dabei werden Zeilen bei denen das zu gruppierende Element gleich ist zu einer Gruppe zusammengestellt und nur die jeweils erste Zeile ausgegeben. Es lassen sich aber auch die Elemente einer Gruppe zählen und so gibt \lstinline|SELECT name, COUNT(*) FROM teilnehmen GROUP BY name;| zu jeder Sportart an, wie viele Mitglieder daran teilnehmen.


\chapter{Sicherheit}
\todo[inline]{Es fehlen noch etwas zum Stichwort SQL-Injection.}

% \chapter{Was man alles mit den Daten noch machen kann}

\chapter{Nachwort}

Im Vorwort (\ref{Vorwort}) haben Sie zu verschiedenen Punkten Stellung genommen. Äußern Sie sich erneut zu den Punkten und vergleichen Sie diese anschließend mit ihren Angaben aus dem Vorwort.


\chapter{Sammlung von Aufgaben}
Zur Übung und Vertiefung sind hier verschiedene Aufgaben angegeben.

\begin{Aufgaben}
	\item Lassen Sie sich zu jedem Mitgliedsnamen des Sportvereins angeben, an wie vielen Sportarten die Mitglieder jeweils teilnehmen und geben Sie ihre Anfrage hier an.
	\AufgabenLoesung{\lstinline|SELECT mitglieder.name, COUNT(*) FROM mitglieder JOIN teilnehmen ON mitglieder.id = teilnehmen.id GROUP BY teilnehmen.id;|}
	\TextFeld{1cm}

\end{Aufgaben}

\todo[inline]{Weitere Aufgaben zur Vertiefung benötigt}

\appendix

\chapter{Installation von MySQL}\label{installation_mysql}
Die Installation eines MySQL-Servers ist auf allen drei gebräuchlichen Plattformen (Linux, Windows, Mac) möglich. Soll zusätzlich auch phpMyAdmin genutzt werden, muss zum MySQL-Server auch ein Webserver mit PHP Unterstützung installiert werden. Dazu gibt es bereits viele Anleitungen im Internet, auf die an dieser Stelle verwiesen wird:

\section{Debian/Ubuntu}
Unter Debian/Ubuntu müssen nur die Pakete mysql-server, mysql-client und phpmyadmin mit den zugehörigen Abhängigkeiten installiert werden. Dann steht eine entsprechende Grundinstallation zur Verfügung. Weitergehende Hilfe findet man auch auf den Seiten \url{http://wiki.ubuntuusers.de/MySQL} und \url{http://wiki.ubuntuusers.de/MySQL/Werkzeuge}.

\section{Windows}
Für die Installation von MySQL unter Windows gibt es passende Quellen unter \url{http://www.mysql.de/why-mysql/windows/}. Es bietet sich aber auch an XAMPP zu installieren. Dann hat man ein Komplettsystem aus dem Apachewebserver, PHP und MySQL. Auch phpMyAdmin ist direkt mit installiert. Zu finden ist XAMPP auf \url{http://www.apachefriends.org/de/index.html}.

\chapter{Installieren des MySQL-Treibers für Java}\label{javatreiber}
\section{Debian/Ubuntu}
Der benötigte Treiber kann unter Debian bzw. Ubuntu mit dem Paket libmysql-java installiert werden. Er befindet sich dann in einer .jar-Datei im Verzeichnis \lstinline[language=bash]{/usr/share/java/}. Je nach Installation kann es dann vorkommen, dass beim Ausführen des Java-Programms der Classpath explizit mit angegeben werden muss. Ein Aufruf würde dann so aussehen: \lstinline[language=bash]{java -cp /usr/share/java/*:. SimpleDbExample}

Es ist auch möglich, den Classpath in der Enviroment fest mit anzugeben. Dazu fügt man der Datei \lstinline{.profile} im Homeverzeichnis die Zeile \lstinline[language=bash]{export CLASSPATH="/usr/share/java/*:."} hinzu bzw. ändert sie so ab, dass sie \lstinline[language=bash]{/usr/share/java/*} enthält. Will man dieses für alle Benutzer machen, so sollte dieses in die Datei \lstinline{/etc/enviroment} übernommen werden.

\chapter{Lösungen}
\loesungzeigen

\bibliography{../../zusatz/projekt}

\nocite{MSWNW2012}
\nocite{Loeffler2010}
\nocite{MYSQL2013}

\listoftodos
\todototoc


\end{document}
