207 lines
8.5 KiB
TeX
207 lines
8.5 KiB
TeX
\section{Normalformen}
|
|
\subsection{1. Normalform}
|
|
Jedes Attribut der Relation muss einen atomaren Wertebereich haben, und die Relation muss frei von Wiederholungsgruppen sein. \\
|
|
\texttt{Atomar} bedeutet, dass ein Attribut nur eine Information enthalten darf, also dürfen bspw. Straße und Hausnummer nicht in einem Attribut gespeichert werden,
|
|
sondern müssen aufgeteilt werdenn.\\
|
|
Mit \texttt{Wiederholdungsgruppen} sind zum einen wiederholende Werte in einer Spalte gemeint (also bspw. in der Spalte Ort mehrmals der Wert Kirchheim) und zum anderen
|
|
sich wiederholende Spalten (bspw. Spalten Standort1, Standort2, Standort3). \\
|
|
|
|
Durch diese Normalform werden Abfragen der Datenbank überhaupt erst möglich gemacht. Ohne atomare Daten könnte nicht jeder Aspekt der Daten einzeln abgefragt werden.
|
|
|
|
\subsection{2. Normalform}
|
|
1. Normalform muss erfüllt sein. Ein Nichtprimärattribut darf nicht funktional von einer Teilmenge eines Schlüsselkandidaten abhängen. \\
|
|
Das bedeutet: Attribute die nur von einem Teil eines Schlüssels und nicht von allen Schlüsseln in einer Tabelle (bei zusammengesetzten Schlüsseln)
|
|
abhängig sind müssen ausgelagert werden, damit sie voll abhängig von ihrem Schlüssel werden. \\
|
|
|
|
Durch diese Normalform modelliert jede Relation nur einen Sachverhalt.
|
|
|
|
\subsection{3. Normalform}
|
|
2. Normalform muss erfüllt sein. Kein Nichtschlüsselattribut darf transitiv von einem Schlüsselkandidaten abhängig sein. \\
|
|
Das bedeutet: Wenn aus einem Attribut ein anderes Attribut ersichtlich wird, welches aber nicht durch den Schlüssel ersichtlich wird,
|
|
ist es transitiv von dem ersten Attribut anhängig. \\
|
|
Bsp.:
|
|
%
|
|
\begin{tabular}{| l | l | l | l |}
|
|
CD\_ID & Albumtitel & Interpret & Gründungsjahr \\
|
|
\hline
|
|
1 & Not That Kind & Anastacia & 1999 \\
|
|
2 & Wish you were here & Pink Floyd & 1965 \\
|
|
3 & Freak of Nature & Anastacia & 1999 \\
|
|
\end{tabular} \\
|
|
%
|
|
Das Gründungsjahr ist durch den Interpreten ersichtlich und nicht durch die CD\_ID. Das heißt, Interpret und Gründungsjahr sollten in eine Tabelle ausgelagert werden.
|
|
|
|
\section{SQL Befehle}
|
|
\subsection{Tabelle erstellen}
|
|
\begin{lstlisting}[frame=single]
|
|
CREATE TABLE tabellenname
|
|
(id INT NOT NULL AUTO_INCREMENT,
|
|
wert VARCHAR(255) NOT NULL, PRIMARY (id));
|
|
\end{lstlisting}
|
|
|
|
\subsection{Werte eintragen}
|
|
\begin{lstlisting}[frame=single]
|
|
INSERT INTO tabellenname (id, wert)
|
|
VALUES (1, 'Test');
|
|
\end{lstlisting}
|
|
|
|
\subsection{Bestehende Werte ändern}
|
|
\begin{lstlisting}[frame=single]
|
|
UPDATE tabellenname
|
|
SET wert = 'Update TEST'
|
|
WHERE id = 1;
|
|
\end{lstlisting}
|
|
|
|
\subsection{Werte aus Tabelle löschen}
|
|
\begin{lstlisting}[frame=single]
|
|
DELETE FROM tabellenname
|
|
WHERE id = 1;
|
|
\end{lstlisting}
|
|
|
|
\subsection{Komplette Tabelle löschen}
|
|
\begin{lstlisting}[frame=single]
|
|
DROP tabellenname;
|
|
\end{lstlisting}
|
|
|
|
\subsection{Alle Werte aus Tabelle löschen}
|
|
\begin{lstlisting}[frame=single]
|
|
TRUNCATE tabellenname;
|
|
\end{lstlisting}
|
|
|
|
\subsection{Werte anzeigen}
|
|
\subsubsection{Alle anzeigen}
|
|
\begin{lstlisting}[frame=single]
|
|
SELECT * FROM tabellenname;
|
|
\end{lstlisting}
|
|
|
|
\subsubsection{Nur bestimmte Spalten anzeigen}
|
|
\begin{lstlisting}[frame=single]
|
|
SELECT werte FROM tabellenname;
|
|
\end{lstlisting}
|
|
|
|
\subsubsection{Spalten Beschriftungen}
|
|
\begin{lstlisting}[frame=single]
|
|
SELECT werte AS "Text"
|
|
FROM tabellenname;
|
|
\end{lstlisting}
|
|
|
|
\subsubsection{Zeilen zählen}
|
|
Bei 3 Einträgen in Werte:
|
|
\begin{lstlisting}[frame=single]
|
|
SELECT COUNT(werte) AS "Anzahl Texte"
|
|
FROM tabellenname;
|
|
\end{lstlisting}
|
|
Ergebnis: Anzahl Texte 3
|
|
|
|
\subsubsection{Werte aufsummieren}
|
|
Angenommen die Tabelle enthält in der Spalte anzahl
|
|
die Werte: 1, 3, 3, 7
|
|
\begin{lstlisting}[frame=single]
|
|
SELECT SUM(anzahl) AS "Summe Anzahl"
|
|
FROM tabellenname;
|
|
\end{lstlisting}
|
|
Ergebnis wäre dann: Summe Anzahl 14
|
|
|
|
\subsubsection{Weitere Rechenfunktionen}
|
|
Außer COUNT() und SUM() gibt es noch:
|
|
\begin{itemize}
|
|
\item AVG: Average, Durchschnitt über Werte bilden
|
|
\item MIN: Den kleinsten Wert ausgeben
|
|
\item MAX: Den größten Wert ausgeben
|
|
\item ROUND(spalte, dezimalstellen): Gerundete Werte ausgeben
|
|
\end{itemize}
|
|
|
|
|
|
\subsubsection{Werte miteinander verrechnen}
|
|
Angenommen die Tabelle enthält in der Spalte anzahl
|
|
die Werte: 4, 2 und in der Spalte preis die Werte
|
|
5, 4.
|
|
\begin{lstlisting}[frame=single]
|
|
SELECT (anzahl * preis) AS "Preis gesamt"
|
|
FROM tabellenname;
|
|
\end{lstlisting}
|
|
Die Ergebnisse wären dann: 20, 8
|
|
|
|
|
|
|
|
\subsection{Werte sortieren}
|
|
Eine unsortierte Liste bspw.: 7, 3, 1, 3
|
|
\begin{lstlisting}[frame=single]
|
|
SELECT werteunsortiert
|
|
FROM tabellenname
|
|
ORDER BY werteunsortiert ASC;
|
|
\end{lstlisting}
|
|
Aufsteigend sortiert wird mit \texttt{ASC}. \\
|
|
Absteigend sortiert wird mit \texttt{DESC}. \\
|
|
Ergibt nach dem sortieren mit ASC: 1, 3, 3, 7 \\
|
|
Nach dem sortieren mit DESC: 7, 3, 3, 1 \\
|
|
|
|
\subsubsection{Werte zufällig anordnen}
|
|
Manchmal kann es sinnvoll sein,
|
|
Werte in eine zuällige Reihenfolge zu bringen.
|
|
\begin{lstlisting}[frame=single]
|
|
SELECT werteunsortiert
|
|
FROM tabellenname
|
|
ORDER BY RAND();
|
|
\end{lstlisting}
|
|
|
|
\subsection{Werte gruppieren}
|
|
Angenommen es gibt die Kategorien: 1, 3, 3, 7.
|
|
Es sollen die einzelnen Kategorien und ihre Häufigkeit angezeigt werden (optional).
|
|
\begin{lstlisting}[frame=single]
|
|
SELECT werte, COUNT(werte)
|
|
FROM tabellenname
|
|
GROUP BY werte;
|
|
\end{lstlisting}
|
|
Die Ergebnisse: 1 $\Rightarrow$ 1x, 3 $\Rightarrow$ 2x, 7 $\Rightarrow$ 1x
|
|
|
|
\subsubsection{HAVING bei GROUP BY}
|
|
Mit WHERE kann man vor einer Gruppierung filtern.
|
|
Soll aber nach einem GROUP BY gefiltert werden
|
|
(damit die Gruppierung nicht verfälscht wird)
|
|
geht das nicht mit WHERE sondern nur mit HAVING.
|
|
Die Syntax für das filtern bleibt dabei die gleiche wie bei WHERE.
|
|
\begin{lstlisting}[frame=single]
|
|
SELECT werte, COUNT(werte)
|
|
FROM tabellenname
|
|
GROUP BY werte
|
|
HAVING werte > 1;
|
|
\end{lstlisting}
|
|
|
|
\subsection{Die ersten X Zeilen ausgeben}
|
|
Wenn bspw. bei einer Highscore Liste nur die ersten
|
|
5 Kandidaten relevant sind, können diese mit LIMIT beschränkt werden.
|
|
\begin{lstlisting}[frame=single]
|
|
SELECT werte
|
|
FROM tabellenname
|
|
ORDER BY werteunsortiert DESC
|
|
LIMIT 5;
|
|
\end{lstlisting}
|
|
Hiermit werden die 5 größsten Werte ausgegeben.
|
|
|
|
\subsection{Tabellen miteinander verknüpfen - JOINS}
|
|
\subsubsection{INNER JOIN}
|
|
Tabelle Person (id, name, fk\_ort) \\
|
|
Tabelle Ort (id, name, plz) \\
|
|
|
|
\begin{lstlisting}[frame=single]
|
|
SELECT Person.name, Ort.plz
|
|
FROM Person INNER JOIN Ort
|
|
ON Person.fk_ort = Ort.id;
|
|
\end{lstlisting}
|
|
Jetzt werden alle Personen ausgegeben,
|
|
die einen Ort zugewiesen haben. Personen die keinen Ort
|
|
zugewiesen werden, fallen weg.
|
|
\subsubsection{LEFT JOIN}
|
|
Funktioniert genau gleich wie INNER JOIN, jedoch wird die linke
|
|
Schnittmenge verwendet. Das bedeutet bei FROM Person LEFT JOIN Ort
|
|
ist Person die linke Tabelle. Das heißt es werden alle Personen angezeigt,
|
|
auch wenn diese keinen Ort eingetragen haben.
|
|
\subsubsection{RIGHT JOIN}
|
|
Genau das selbe Prinzip wie LEFT JOIN, bloß diesesmal wird die rechte
|
|
Schnittmenge verwendet. Es würden in diesem Beispiel also alle Orte angezeigt
|
|
werden, auch wenn dazu keine Personen zugeordnet sind (in diesem Beispiel eher
|
|
weniger sinnvoll). Jedes RIGHT JOIN kann in ein LEFT JOIN umgeschrieben und umgekehrt.
|
|
Es ist nur eine Darstellungssache, wenn man bspw. aus einem ERM Modell die Darstellung
|
|
beibehalten möchte.
|