🇩🇪 Grundlegende SQL-Befehle für Einsteiger
Tags: german, sql, database, beginners
Published: 2024-07-14 14:00:00


## Einführung in SQL und Datenbanken

Wie im letzten Eintrag erwähnt sind Datenbanken aus der heutigen Zeit nicht mehr wegzudenken. SQL *(Structured Query Language)* ist dabei die Basis für Datenbank Manipulationen und Abfragen. Egal ob Datenbankadministrator, oder Web-/Softwareentwickler, Kenntnisse in SQL sind unerlässlich.

### Was ist SQL

Bei SQL (_Structured Query Language_) handelt es sich um eine standardisierte Sprache für die Verwaltung und Manipulation von relationalen Datenbanken. Sie wurde in den 1970er Jahren von IBM entwickelt und hat sich zum De-facto Standard bei relationalen Datenbanken entwickelt.

SQL ermöglicht es einem Daten zu erstellen, zu lesen, zu aktualisieren und zu löschen (_CRUD_-Operationen, _CREATE-READ-UPDATE-DELETE_). Außerdem können damit auch komplexe Abfragen durchgeführt werden und die Struktur von Datenbanken verwaltet werden.

## Datenbank und Tabellen erstellen

Bevor man mit einer Datenbank arbeiten kann, muss diese aber erst erstellt und die Struktur definiert werden. Im ersten Schritt wird also die DB und die Tabellen erstellt und deren Struktur definiert.

### CREATE DATABASE

Um eine neue Datenbank zu erstellen, wird der Befehl CREATE DATABASE verwendet. Die Syntax ist dabei wie folgt:
```sql
CREATE DATABASE mein_datenbank_name;
```
Dieser Befehl erstellt eine neue, leere Datenbank namens "mein_datenbank_name". Nach dem Erstellen müssen wir die Datenbank noch auswählen, um mit ihr zu arbeiten. Das geschieht mit dem `USE` Befehl, welcher MySQL mitteilt, dass alle nachfolgenden Befehle im Kontext der gewählten Datenbank ausgeführt werden sollen.

```sql
USE mein_datenbank_name;
```

### CREATE TABLE
Da eine leere Datenbank nicht allzu sinnvoll ist, können wir nun ein paar Tabellen erstellen. Tabellen sind die grundlegenden Strukturen, in denen die Daten einer relationalen Datenbank gespeichert werden. Die Syntax sieht dabei wie folgt aus:
```sql
CREATE TABLE tabellen_name (
    spalte1 datentyp [einschränkungen],
    spalte2 datentyp [einschränkungen],
    ...
    [tabelleneinschränkungen]
);
```

Lass uns als Beispiel eine "Kunden" Tabelle erstellen:
```sql
CREATE TABLE Kunden (
    kunden_id INT PRIMARY KEY AUTO_INCREMENT,
    vorname VARCHAR(50) NOT NULL,
    nachname VARCHAR(50) NOT NULL,
    email VARCHAR(100) UNIQUE,
    geburtstag DATE,
    registrierungsdatum TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    kundenstatus ENUM('aktiv', 'inaktiv', 'gesperrt') DEFAULT 'aktiv',
    kreditlimit DECIMAL(10,2) DEFAULT 1000.00
);
```

Die einzelnen Befehle kurz erklärt:
- `kunden_id INT PRIMARY KEY AUTO_INCREMENT`: Definiert eine Ganzzahl (`Integer`)-Spalte als Primärschlüssel, deren Wert automatisch für jeden neuen Eintrag erhöht wird (`AUTO_INCREMENT`)
- `vorname VARCHAR(50) NOT NULL`: Definiert Zeichenkette mit variabler Länge (max. 50 Zeichen), die nicht leer (NULL) sein darf
- `nachname VARCHAR(50) NOT NULL`: siehe `vorname`
- `email VARCHAR(100) UNIQUE`: Definiert eine email Spalte, die eindeutig sein muss
- `geburtstag DATE`: Ein Datumswert für den Geburtstag eines Kunden
- `registrierungsdatum TIMESTAMP DEFAULT CURRENT_TIMESTAM`P: Ein Zeitstempel, welcher als Standardwert die aktuelle Zeit gesetzt hat, wenn ein neuer Datensatz eingefügt wird.
- `kundenstatus ENUM('aktiv', 'inaktiv', 'gesperrt') DEFAULT 'aktiv'`: Ein Aufzählungstyp mit vordefinierten Werten und dem Standardwert 'aktiv'
- `kreditlimit DECIMAL(10,2) DEFAULT 1000.00`: Ein Dezimalwert mit einem Standardwert

### Datentypen in MySQL
Ein paar Datentypen haben wir im Beispiel eben ja schon kennengelernt, aber MySQL bietet noch eine Vielzahl [weiterer Datentypen](https://dev.mysql.com/doc/refman/8.4/en/data-types.html). Die Wahl des richtigen Datentyps ist wichtig, um die Informationen effizient zu speichern und die Integrität der Datenbank zu gewährleisten. Ein paar der am häufigsten verwendeten Datentypen:

**Numerische Typen:**
- `TINYINT`: Für ganze Zahlen (Integers) zwischen -128 und 127
- `INT`: Für ganze Zahlen (Integers) zwischen -2.147.483.648 und 2.147.483.647 (-2<sup>31</sup> und 2<sup>31</sup> - 1)
- `BIGINT`: Für ganze Zahlen (Integers) zwischen -2<sup>63</sup> und 2<sup>63</sup> - 1
- `DECIMAL(M, D)`: Für Festkommazahlen. M ist die Gesamtzahl der Ziffern (*Präzision*); D ist die Anzahl der Dezimalstellen
- `FLOAT`: Für Gleitkommazahlen mit einfacher Genauigkeit
- `DOUBLE`: Für Gleitkommazahlen mit doppelter Genauigkeit

**Zeichenketten:**
- `CHAR(n)`: Für Zeichenketten mit fester Länge `n`
- `VARCHAR(n)`: Für Zeichenketter mit variabler Länge (max. `n` Zeichen)
- `TEXT`: Für lange Texte mit bis zu 65.535 Zeichen
- `LONGTEXT`: Für sehr lange Texte mit bis zu 4 GB

**Datum- und Zeittypen:**
- `DATE`: Für Datumswerte. Format: `YYYY-MM-DD`
- `TIME`: Für Zeitwerte. Format: `HH:MM:SS`
- `DATETIME`: Für Datums- und Zeitwerte. Format: `YYYY-MM-DD HH:MM::SS`
- `TIMESTAMP`: Ähnlich wie DATETIME; Speichert den UNIX Timestamp zwischen `1970-01-01 00:00:01` UTC bis `2038-01-19 03:14:07` UTC.

**Sonstige Typen:**
- `BOOLEAN`: Für Wahrheitswerte (`true/false`)
- `ENUM`: Für vordefinierte Listen von Werten
- `SET`: Ähnlich wie `ENUM`, erlaubt aber die Auswahl mehrerer Werte
- `BLOB`: Für binäre Daten (*binary large object*) wie zum Beispiel Bilder

Die Wahl des richtigen Datentypen kann erheblichen Einfluss auf die Leistung und Speichereffizienz der Datenbank haben. Zum Beispiel:
- Verwenden von `INT` für ganze Zahlen anstelle von `FLOAT` oder `DOUBLE`, wenn keine Dezimalstellen benötigt werden
- Benutzen von `VARCHAR` anstelle von `CHAR` für Zeichenketten variabler Länge, um Speicherplatz zu sparen
- Verwenden von `ENUM` oder `SET` für Spalten mit einer begrenzten Anzahl möglicher Werte, um Datenintegrität zu verbessern und Speicherplatz zu sparen

### Primärschlüssel und Fremdschlüssel
Primärschlüssel und Fremdschlüssel sind entscheidend für die Strukturierung relationaler Datenbanken und die Gewährleistung der Datenintegrität.

#### Primärschlüssel (Primary Key)
Bei einem Primärschlüssel handelt es sich um ein Feld (oder eine Kombination von Feldern), welches den Datensatz eindeutig identifiziert. Im obigen Beispiel mit der `Kunden`-Tabelle ist das Feld `kunden_id` der Primärschlüssel. Die Eigenschaften von Primärschlüsseln sind:

1. Eindeutigkeit (*uniqueness*) - keine zwei Datensätze können den gleichen Schlüsselwert haben
2. Sie dürfen nicht `NULL` sein
3. Unveränderbarkeit (*immutability*) - einmal zugewiesen, sollte der Wert konstant bleiben

Primärschlüssel können auf verschiedene Weise definiert werden:
```sql
-- Als Teil der Spaltendefinition
CREATE TABLE beispiel1 (
    id INT PRIMARY KEY,
    name VARCHAR(50)
);

-- Als separate Einschränkung
CREATE TABLE beispiel2 (
    id INT,
    name VARCHAR(50),
    PRIMARY KEY (id)
);

-- Zusammengesetzter Primärschlüssel
CREATE TABLE beispiel3 (
    id1 INT,
    id2 INT,
    name VARCHAR(50),
    PRIMARY KEY (id1, id2)
);
```

### Fremdschlüssel
Ein Fremdschlüssel (*FK*) ist ein Feld in der Tabelle, welches auf einen Primärschlüssel in einer anderen Tabelle verweist. Das ermöglicht es Beziehungen (Relationen) zwischen Tabellen zu erstellen und die referenzielle Integrität zu gewährleisten. Hier ein Beispiel für eine `Bestellungen`-Tabelle, welche einen Fremdschlüssel auf unsere `Kunden` Tabelle enthält. In dem Beispiel verweist `kunden_id` in der `Bestellungen` Tabelle auf `kunden_id` in der `Kunden` Tabelle. Dies stellt eine Beziehung zwischen Kunden und ihren Bestellungen her.

```sql
CREATE TABLE Bestellungen (
    bestell_id INT PRIMARY KEY AUTO_INCREMENT,
    kunden_id INT,
    bestelldatum DATE,
    gesamtbetrag DECIMAL(10,2),
    FOREIGN KEY (kunden_id) REFERENCES Kunden(kunden_id)
);
```

Fremdschlüssel haben mehrere wichtige Funktionen:
- stellen sicher, dass nur gültige Daten in die FK Spalte eingefügt werden können
- ermöglichen das Löschen und Aktualisieren von verknüpften Datensätzen in mehreren Tabellen (*kaskasierende Aktionen*)
- verbessern die Datenintegrität und -konsitenz

Das Verhalten von Fremdschlüsseln bei Aktualisierungen oder Löschungen kann mit den Klauseln `ON UPDATE` und `ON DELETE` gesteuert werden:

```sql
CREATE TABLE Bestellungen (
    bestell_id INT PRIMARY KEY AUTO_INCREMENT,
    kunden_id INT,
    bestelldatum DATE,
    gesamtbetrag DECIMAL(10,2),
    FOREIGN KEY (kunden_id) REFERENCES Kunden(kunden_id)
 		ON DELETE CASCADE
        ON UPDATE RESTRICT
);
```
Hier würde das Löschen eines Kunden automatisch alle seine Bestellungen löschen (`CASCADE`), während eine Änderung der `kunden_id` verhindert würde (`RESTRICT`).

## Daten einfügen und abfragen
Daten einfügen und abfragen gehört zu den grundlegendsten Operation, da man Sie am häufigsten nutzt.

### INSERT INTO
Mit dem `INSERT INTO` Befehl können neue Datensätze in eine Tabelle eingefügt werden. Die grundlegende Syntax sieht dabei wie folgt aus:

```sql
INSERT INTO tabellen_name (spalte1, spalte2, spalte3, ...)
VALUES (wert1, wert2, wert3);
```

Hier einige Beispiele für unsere `Kunden`-Tabelle

```sql
-- Einzelnen Datensatz hinzufügen
INSERT INTO Kunden (vorname, nachname, email, geburtstag)
VALUES ('Max', 'Mustermann', 'max@example.com', '1990-01-01');

-- Mehrere Datensätze gleichzeitig einfügen
INSERT INTO Kunden (vorname, nachname, email, geburtstag)
VALUES 
	('John', 'Doe', 'john.doe@example.com', '1970-01-01'),
	('Jane', 'Doe', 'jane.doe@example.com', '1980-01-01'),
    ('Maria', 'Musterfrau', 'maria@example.com', '1990-11-11');
    
-- Alle Spalten in der definierten Reihenfolge (nicht empfohlen !)
INSERT INTO Kunden
VALUES (NULL, 'Peter', 'Meier', '2000-01-01', CURRENT_TIMESTAMP, 'aktiv', 1000.00);
```

Wichtige Punkte die man beachten sollte:
1. Wenn nicht alle Spalten angegeben werden, werden die ausgelassenen Spalten mit den Standardwerten oder `NULL` befüllt
2. Die Reihenfolge der Spalten in der `INSERT`-Anweisung muss mit der Reihenfolge der Werte übereinstimmen
3. Für Spalten mit `AUTO_INCREMENT` (z.B. `kunden_id`) kann `NULL` oder `0` eingegeben werden, um den nächsten verfügbaren Wert zu benutzen
4. Datum- und Zeitwerte sollten im Format `YYYY-MM-DD` bzw `YYYY-MM-DD HH:MM:SS` angegeben werden

### SELECT Abfragen
Der `SELECT`-Befehl ist der Grundstein für das Abfragen von Daten in einer Datenbank. Die grundlegende Syntax sieht wie folgt aus:
```sql
SELECT spalte1, spalte2, ...
FROM tabellen_name
[WHERE bedingung]
[ORDER BY spalte1 [ASC|DESC], ...]
[LIMIT anzahl];
```

Einige Beispiele mit unserer `Kunden`-Tabelle:
```sql
-- Alle Spalten aller Kunden abrufen
SELECT * FROM Kunden;

-- Nur bestimmte Spalten abrufen
SELECT vorname, nachname, email FROM Kunden;

-- Daten sortieren (ORDER BY spalte1 [ASC|DESC], spalte2 [ASC|DESC], ...)
SELECT * FROM Kunden ORDER BY nachname ASC, vorname DESC;

-- Begrenzte Anzahl von Ergebnissen
SELECT * FROM Kunden LIMIT 10;
```

### WHERE-Bedingungen
Die `WHERE` Klausel ermöglicht es die `SELECT`-Abfrage zu filtern und nur bestimmte Datensätze zurückzugeben. Dabei können verschiedene Operatoren und logische Ausdrücke verwendet werden:

```sql
-- Einfache Vergleiche
SELECT * FROM Kunden WHERE geburtstag < '1990-01-01';
SELECT * FROM Kunden WHERE kundenstatus = 'aktiv';

-- Logische Operatoren
SELECT * FROM Kunden WHERE geburtstag < '1990-01-01' AND kreditlimit > 2000;
SELECT * FROM Kunden WHERE kundenstatus = 'aktiv' OR kreditlimit > 5000;

-- IN-Operator -> überprüft ob der Wert in einer Liste aus Werten ist
-- Bsp: Selektiert alle Kunden, deren kundenstatus entweder 'aktiv' oder 'inaktiv' ist
SELECT * FROM Kunden WHERE kundenstatus IN ('aktiv', 'inaktiv');

-- BETWEEN-Operator -> überprüft ob ein Datums-/Zeitwert zwischen zwei Werten ist
-- Bsp: Selektiert alle Kunden die in den 1980ern geboren wurden
SELECT * FROM Kunden WHERE geburtstag BETWEEN '1980-01-01' AND '1989-12-31';

-- NULL-Werte prüfen
SELECT * FROM Kunden WHERE geburtstag IS NULL;

-- Komplexe Bedingungen
-- Bsp: Selektiert alle Kunden, die 'aktiv' sind und ein Kreditlimit > 1000 haben 
-- ODER die inaktiv sind mit einem Kreditlimit > 5000
SELECT * FROM Kunden
WHERE (kundenstatus = 'aktiv' AND kreditlimit > 1000)
   OR (kundenstatus = 'inaktiv' AND kreditlimit > 5000);
```

#### LIKE-Operator
Der `LIKE`-Operator wird für Mustervergleiche in Zeichenketten verwendet. Das `%` ist dabei als Platzhalter zu verwenden:

```sql
-- Kunden, deren Nachname mit 'M' beginnt, zb Mustermann
SELECT * FROM Kunden WHERE nachname LIKE 'M%';

-- Kunden, deren Nachname mit 'er' endet, zb Becker, Müller
SELECT * FROM Kunden WHERE nachname LIKE '%er';

-- Kunden mit 'ei' irgendwo im Nachnamen, zb Meier, oder Schneider
SELECT * FROM Kunden WHERE nachname LIKE '%ei%';
```

## Übungen

- **Übung 1**: Erstelle eine neue Tabelle `Benutzer` in der `Bibliothek`-Datenbank mit den Feldern `user_id` (Primärschlüssel), `name`, `adresse`, `geburtstag`, `eMail` und `telefonnummer`.
- **Übung 2**: Füge mindestens 10 Benutzer in die `Benutzer` Tabelle ein, mit verschiedenen Namen, Adressen und Geburtstagen.
- **Übung 3**: Schreibe eine `SELECT`-Abfrage, die alle Benutzer zurückgibt die mindestens 18 Jahre alt sind.
- **Übung 4**: Schreibe eine `SELECT`-Abfrage, die alle Benutzer zurückgibt die eine E-Mail-Adresse von Googlemail haben (`...@googlemail.com` oder `...@gmail.com`)
- **Übung 5**: Schreibe eine `SELECT`-Abfrage, die die 10 ältestens Benutzer zurückgibt.

Diese Übungen decken die wichtigsten Konzepte ab, die wir in diesem Tutorial behandelt haben. Versuche sie selbstständig zu lösen, bevor du nach Lösungen suchst. Die praktische Anwendung ist der beste Weg, um SQL zu lernen und zu beherrschen.

Die Lösungen zu den Übungen findest du in unserem [GitHub Repository](https://github.com/InformatikNinja/einfuehrung-in-datenbanken/blob/master/grundlegende-sql-befehle.md)


## Fazit
In diesem Eintrag haben wir die grundlegenden SQL-Befehle und Konzepte kennengelernt, die für die Arbeit mit relationalen Datenbanksystemen unerlässlich sind. Wir haben uns angeschaut, wie man Datenbanken und Tabellen erstellt und wie man Daten einfügt und abfragt.

Die beste Art, SQL zu lernen, ist durch praktische Übung. Versuche also die Übungsaufgaben selbständig zu lösen und experimentiere selbst mit verschiedenen Abfragen. Je mehr Übung man hat, desto vertrauter wird man mit der Sprache.

## Referenzen
- [Die offizielle MySQL-Dokumentation - Eine umfassende Quelle für alle MySQL-spezifischen Details.](https://dev.mysql.com/doc/refman/8.4/en/)
- [SQL Tutorial von W3Schools mit Übungen zum selber ausprobieren](https://www.w3schools.com/sql/default.asp)