# Datenbanken ##### Normalisierung von Datenbanken Unter Normalisierung einer relationalen Datenbank versteht man die Aufteilung von Attributen in mehrere Relationen (Tabellen) mit Hilfe der Normalisierungsregeln. Insgesamt gibt es fünf Normalformen, aber im Alltag reicht eine Normalisierung bis zur dritten Normalform vollkommen aus. Die vierte und fünfte Normalform sind für Spezialfälle wie Atomkraftwerke usw. notwendig. Die einzelnen Normalformen bauen aufeinander auf, d.h. die dritte Normalform ist nur erfüllt wenn auch die zweite Normalform erfüllt ist und die zweite Normalform ist nur erfüllt, wenn auch die erste Normalform erfüllt ist. Ziel der Normalisierung: - Beseitigung von Redundanzen - Vermeidung von Anomalien - Erstellen eines klar strukturierten Datenbankmodells ##### Erste Normalform (1NF) Die **erste Normalform** ist dann erfüllt, wenn alle Informatione einer Tabelle **atomar** vorliegen. Atomar bedeutet, dass jede Information eine eigene Spalte bekommt. Beispiel: - nicht normalisierte Form
R-Nr | Datum | Name | Straße | Ort | Artikel | Anzahl | Preis |
187 | 01.01.2022 | Max Mustermann | Musterweg.1 | 12345 Musterstadt | Bleistift | 5 | 1.00€ |
R-Nr | Datum | Name | Vorname | Straße | Hnr | PLZ | Ort | Artikel | Preis | Währung |
187 | 01.01.2022 | Mustermann | Max | Musterstr. | 1 | 12345 | Musterstadt | 5 | 1.00 | Euro |
**Rechnung** | ||
R-Nr | Datum | Knr |
187 | 01.01.2022 | 007 |
**Kunde** | ||||||
Knr | Name | Vorname | Straße | Hnr | PLZ | Ort |
007 | Mustermann | Max | Musterstr. | 1 | 12345 | Musterstadt |
**Rechnungsposition** | |||
R-P-NR | R-Nr | Art-Nr | Anzahl |
1 | 187 | 69 | 5 |
**Artikel** | ||
Art-Nr | Artikel | Preis |
69 | Bleistift | 1.00 |
**Kunde** | |||||
Knr | Name | Vorname | Straße | Hnr | PLZ |
007 | Mustermann | Max | Musterstr. | 1 | 12345 |
**Postleitzahl** | |
PLZ | Ort |
12345 | Musterstadt |
Die `INSERT INTO` Anweisung wird verwendet, um einen neuen Datensatz (Zeile) in eine Tabelle einzufügen. Es gibt zwei Varianten: - In Spalten der Reihe nach einfügen - Einfügen in Spalten nach Namen | ```SQL -- In Spalten der Reihe nach einfügen: INSERT INTO table_name VALUES (value1, value2); -- Einfügen in Spalten nach Namen: INSERT INTO table_name (column1, column2) VALUES (value1, value2); ``` |
Die **`DELETE`** Anweisung wird verwendet, um Datensätze (Zeilen) in einer Tabelle zu löschen. Die **`WHERE`** Anweisung gibt an, welcher Datensatz oder welche Datensätze gelöscht werden sollen. Wenn **`WHERE`** weggelassen wird, werden alle Datensätze gelöscht. | ```SQL DELETE FROM table_name WHERE some_column = some_value; ``` |
Die **`UPDATE`** Anweisung wird verwendet, um Datensätze (Zeilen) in einer Tabelle zu bearbeiten. Sie enthält eine `SET` Anweisung, die die zu bearbeitende Spalte angibt, und eine **`WHERE`** Anweisung, die den oder die Datensätze spezifiziert. | ```SQL UPDATE table_name SET column1 = value1, column2 = value2 WHERE some_column = some_value; ``` |
Mit dem **`AND`** Operator können mehrere Bedingungen kombiniert werden. Die Datensätze müssen beiden Bedingungen entsprechen, die mit **`AND`** verknüpft sind, um in die Ergebnisse aufgenommen zu werden. Die angegebene Abfrage zeigt alle Autos an, die blau sind und nach 2014 hergestellt wurden. | ```SQL SELECT model FROM cars WHERE color = 'blue' AND year > 2014; ``` |
Mit dem **`OR`** Operator können mehrere Bedingungen kombiniert werden. Datensätze, die einer der beiden Bedingungen entsprechen, die durch das **`OR`** verbunden sind, werden in die Ergebnisse aufgenommen. Die angegebene Abfrage findet Kunden, deren Staat entweder „CA“ oder „NY“ ist. | ```SQL SELECT name FROM customers WHERE state = 'CA' OR state = 'NY'; ``` |
`WHERE` wird verwendet, um Datensätze (Zeilen) zu filtern, die eine bestimmte Bedingung erfüllen. Die angegebene Abfrage wählt alle Datensätze aus, bei denen das pub\_year gleich 2017 ist. | ```SQL SELECT title FROM library WHERE pub_year = 2017; ``` |
Mit **`LIKE`** kann innerhalb einer **`WHERE`** ein bestimmtes Muster abgefragt werden. Die angegebene Abfrage findet jeden Film, dessen Titel mit „Star“ beginnt. | ```SQL SELECT name FROM movies WHERE name LIKE 'Star%'; ``` |
Der Platzhalter `%` kann mit `LIKE` verwendet werden, um keine oder mehrere nicht spezifizierte Zeichen zu finden. Die angegebene Abfrage findet jeden Film, der mit „The“ beginnt, gefolgt von keinem oder mehreren beliebigen Zeichen. | ```SQL SELECT name FROM movies WHERE name LIKE 'The%'; ``` |
Der Platzhalter `_` kann mit **`LIKE`** verwendet werden, um ein beliebiges einzelnes, nicht spezifiziertes Zeichen zu finden. Die angegebene Abfrage findet jeden Film, der mit einem einzelnen Zeichen beginnt, gefolgt von „ove“. | ```SQL SELECT name FROM movies WHERE name LIKE '_ove'; ``` |
Die `SELECT *` Anweisung gibt alle Spalten aus der angegebenen Tabelle in der Trefferliste zurück. Die angegebene Abfrage holt alle Spalten und Datensätze (Zeilen) aus der Tabelle „Filme“. | ```SQL SELECT * FROM movies; ``` |
`ORDER BY` kann verwendet werden, um die Ergebnisse einer Spalte alphabetisch oder numerisch zu sortieren. Es kann auf zwei Arten sortiert werden: - Mit `DESC` werden die Ergebnisse in absteigender Reihenfolge sortiert. - Mit `ASC` werden die Ergebnisse in aufsteigender Reihenfolge sortiert (Standard). | ```SQL SELECT * FROM contacts ORDER BY birth_date DESC; ``` |
Der Operator **`BETWEEN`** kann zum Filtern nach einem Wertebereich verwendet werden. Bei dem Wertebereich kann es sich um Text, Zahlen oder Datumsdaten handeln. Die angegebene Abfrage findet alle Filme, die zwischen den Jahren 1980 und 1990 gedreht wurden. | ```SQL SELECT * FROM movies WHERE year BETWEEN 1980 AND 1990; ``` |
Die Bedingung **`LIMIT`** wird verwendet, um die Ergebnisse auf eine bestimmte Anzahl von Zeilen zu begrenzen. Die angegebene Abfrage begrenzt die Ergebnismenge auf 5 Zeilen. | ```SQL SELECT * FROM movies LIMIT 5; ``` |
Spalteninhalte können `NULL` sein oder keinen Wert haben. Diese Datensätze können mit den Operatoren `IS NULL` und `IS NOT NULL` in Kombination mit `WHERE` abgeglichen werden. Die angegebene Abfrage wird alle Adressen anzeigen, bei denen die Adresse einen Wert hat oder nicht **`NULL`** ist. | ```SQL SELECT address FROM records WHERE address IS NOT NULL; ``` |
Nach **`CREATE TABLE`** folgt der Tabellenname. Innerhalb der Klammern werden die Spalten und deren Datentyp aufgelistet. Der `PRIMARY KEY` gibt dabei an, in welcher Spalte die eindeutige Identifikationsnummer steht. Getrennt werden die einzelen Einträge mit Komma. Gibt es einen Verweis auf eine andere Tabelle, dann erfolgt dies durch den sogenannten **`FOREIGN KEY`**. Dieser gibt an in welcher Spalte die Referenz steht und auf welche Spalte einer anderen Tabelle referenziert wird. | ```sql CREATE TABLE Personen { PersonenID INTEGER PRIMARY KEY, Nachname varchar(255), Vorname varchar(255), GeburtsOrtID INTEGER, FOREIGN KEY (GeburtsOrtID) REFERENCES Ort(OrtsID) } ``` |
Bei einem Outer Join werden Zeilen aus verschiedenen Tabellen kombiniert, auch wenn die Join-Bedingung nicht erfüllt ist. Bei einem `LEFT JOIN` wird jede Zeile der linken Tabelle in die Ergebnismenge zurückgegeben. Wenn die Join-Bedingung nicht erfüllt ist, wird `NULL` verwendet, um die Spalten der rechten Tabelle aufzufüllen. | ```SQL SELECT column_name(s) FROM table1 LEFT JOIN table2 ON table1.column_name = table2.column_name; ``` |
`JOIN` ermöglicht die Rückgabe von Ergebnissen aus mehr als einer Tabelle, indem sie diese mit anderen Ergebnissen auf der Grundlage gemeinsamer Spaltenwerte verbindet, die mit `ON` angegeben werden. `INNER JOIN` ist der Standard `JOIN` und gibt nur Ergebnisse zurück, die der durch `ON` angegebenen Bedingung entsprechen. | ```SQL SELECT * FROM books JOIN authors ON books.author_id = authors.id; ``` |