mirror of
https://github.com/theoleuthardt/hwr-notes.git
synced 2026-06-06 01:01:08 +00:00
406 lines
12 KiB
Markdown
406 lines
12 KiB
Markdown
# SQL – Zusammenfassung
|
||
**Dozent:** A. Zimmermann | HWR Berlin | 2026 | **Folien 1–96**
|
||
|
||
---
|
||
|
||
## 1. Überblick (Folie 2)
|
||
|
||
SQL-Befehle sind in vier Kategorien unterteilt:
|
||
|
||
| Kategorie | Abkürzung | Befehle |
|
||
|---|---|---|
|
||
| **Data Definition Language** | DDL | ALTER, COMMENT, CREATE, DROP, RENAME, TRUNCATE |
|
||
| **Data Manipulation Language** | DML | CALL, DELETE, EXPLAIN, INSERT, LOCK, MERGE, SELECT, UPDATE |
|
||
| **Data Control Language** | DCL | GRANT, REVOKE |
|
||
| **Transaction Control Language** | TCL | COMMIT, ROLLBACK, SAVEPOINT, SET TRANSACTION |
|
||
|
||
---
|
||
|
||
## 2. Datentypen (Folien 3–5)
|
||
|
||
**Datentyp = Werte + Operationen**
|
||
|
||
### Oracle-Datentypen
|
||
|
||
| Datentyp | Beschreibung |
|
||
|---|---|
|
||
| **VARCHAR(n) / VARCHAR2(n)** | Zeichenkette variabler Länge |
|
||
| **CHAR(n)** | Zeichenkette fester Länge |
|
||
| **NUMBER(p, s)** | Dezimale Zahl, p=Stellen (1–38), s=Nachkomma (-84–127), Werte bis ±10^125 |
|
||
| **DECIMAL(p, s)** | Dezimale Zahl, Werte bis ±10^308 |
|
||
| **INTEGER** | Ganze Zahl, -2.147.483.648 bis 2.147.483.647 |
|
||
| **DATE** | Datum/Uhrzeit (sekundengenau) |
|
||
| **RAW(n)** | Binärdaten, 1–2000 Bytes |
|
||
| **LONG RAW** | Binärdaten bis 2 GiB |
|
||
| **CLOB** | Zeichenketten bis 4 GiB |
|
||
| **BLOB** | Binärdaten bis 4 GiB |
|
||
| **CFILE / BFILE** | Zeiger auf externe Dateien (Text/Binär) |
|
||
|
||
---
|
||
|
||
## 3. Einfache Befehle (Folien 6–11)
|
||
|
||
### DDL – Tabellen anlegen und löschen
|
||
|
||
```sql
|
||
CREATE TABLE Professoren (
|
||
PersNr INTEGER NOT NULL,
|
||
Name VARCHAR(30) NOT NULL,
|
||
Rang CHARACTER(2),
|
||
PRIMARY KEY(PersNr)
|
||
);
|
||
|
||
DROP TABLE Professoren;
|
||
```
|
||
|
||
### DML – Einfügen, Löschen, Ändern
|
||
|
||
```sql
|
||
-- Einzelnes Tupel einfügen
|
||
INSERT INTO Professoren (PersNr, Name, Rang)
|
||
VALUES (30314, 'Cantor', 'W2');
|
||
|
||
-- Mehrere Tupel gleichzeitig
|
||
INSERT INTO Professoren (PersNr, Name, Rang) VALUES
|
||
(30314, 'Cantor', 'W2'),
|
||
(30315, 'Leibniz', 'W1'),
|
||
(30316, 'Plank', 'W1');
|
||
|
||
-- Einfügen mit verschachtelter Abfrage
|
||
INSERT INTO hoeren
|
||
SELECT MatrNr, VorlNr
|
||
FROM Studenten, Vorlesungen
|
||
WHERE Titel = 'Datenbanken';
|
||
|
||
-- Teilweises Einfügen (Rang wird NULL)
|
||
INSERT INTO Professoren (PersNr, Name)
|
||
VALUES (30317, 'Feuerbach');
|
||
|
||
-- Löschen
|
||
DELETE FROM Professoren;
|
||
DELETE FROM Professoren WHERE Rang = 'W3';
|
||
|
||
-- Ändern
|
||
UPDATE Studenten SET Semester = Semester + 1;
|
||
```
|
||
|
||
### Inline-View
|
||
|
||
Eine SELECT-Anweisung mit einer weiteren SELECT-Anweisung in der FROM-Klausel:
|
||
|
||
```sql
|
||
-- Professoren, die Assistenten haben
|
||
SELECT p.Name, p.Raum
|
||
FROM Professoren p,
|
||
(SELECT DISTINCT Boss FROM Assistenten) a
|
||
WHERE p.PersNr = a.Boss;
|
||
```
|
||
|
||
### Allgemeine SELECT-Syntax (Folie 11)
|
||
|
||
```sql
|
||
SELECT column1, column2
|
||
FROM table1, table2
|
||
WHERE condition
|
||
GROUP BY column1, column2
|
||
HAVING condition
|
||
ORDER BY column1, column2;
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Erweiterungen (Folien 12–14)
|
||
|
||
### Sortieren
|
||
```sql
|
||
SELECT PersNr, Name, Rang FROM Professoren
|
||
ORDER BY Rang DESC, Name ASC;
|
||
```
|
||
|
||
### Duplikate eliminieren
|
||
```sql
|
||
SELECT DISTINCT Rang FROM Professoren;
|
||
```
|
||
|
||
### Platzhalter (nur mit LIKE)
|
||
- `_` — genau ein Zeichen
|
||
- `%` — beliebig viele Zeichen (auch keines)
|
||
|
||
```sql
|
||
SELECT * FROM Professoren WHERE Rang LIKE 'W_';
|
||
SELECT * FROM Professoren WHERE Name LIKE 'T%eophrastos';
|
||
```
|
||
|
||
### IN / NOT IN
|
||
```sql
|
||
SELECT Name FROM Studenten WHERE Semester IN (1, 2, 3);
|
||
|
||
SELECT Name FROM Professoren
|
||
WHERE PersNr NOT IN (SELECT gelesenVon FROM Vorlesungen);
|
||
```
|
||
|
||
### ALL / ANY
|
||
```sql
|
||
-- ALL: Alle Bedingungen müssen erfüllt sein (AND)
|
||
SELECT Name FROM Studenten WHERE Semester >= ALL (7, 8, 9);
|
||
|
||
-- ANY: Mindestens eine Bedingung (OR)
|
||
SELECT Name FROM Studenten WHERE Semester >= ANY (7, 8, 9);
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Anfragen über mehrere Relationen (Folien 15–20)
|
||
|
||
**Vorgehensweise:**
|
||
1. Kreuzprodukt aus Tabellen bilden
|
||
2. Relevante Zeilen und Felder ausschneiden
|
||
|
||
**Wichtigste Voraussetzung:** Information über Verbindung zwischen Tabellen (Join-Prädikat).
|
||
|
||
```sql
|
||
SELECT p.Name Professor, a.Name Assistent
|
||
FROM Professoren p, Assistenten a
|
||
WHERE p.PersNr = a.Boss; -- join-Prädikat (access-Prädikat)
|
||
```
|
||
|
||
**Aliasse** sind praktikabel und notwendig, wenn Felder mit gleichen Namen aus verschiedenen Tabellen involviert sind.
|
||
|
||
---
|
||
|
||
## 6. Operator JOIN (Folien 21–53)
|
||
|
||
### 6.1 Motivation (Folie 21)
|
||
|
||
Ohne JOIN stehen Join- und Filter-Prädikate zusammen in WHERE. Der JOIN-Operator **trennt** diese:
|
||
- **JOIN ... ON**: Join-Prädikat
|
||
- **WHERE**: Filter-Prädikat
|
||
|
||
→ Erleichtert dem Optimizer die Arbeit.
|
||
|
||
### 6.2 Innere JOINs (Folien 23–30)
|
||
|
||
Tupel **ohne Partner gehen verloren**.
|
||
|
||
#### Natürlicher Verbund (NATURAL JOIN)
|
||
- Voraussetzung: Gleich benannte Attribute mit gleichem Datentyp
|
||
- Verknüpft automatisch über gleichnamige Spalten
|
||
- Join-Attribute erscheinen nur einmal im Ergebnis
|
||
|
||
```sql
|
||
SELECT MatrNr, Name, Titel
|
||
FROM Studenten NATURAL JOIN hoeren NATURAL JOIN Vorlesungen;
|
||
```
|
||
|
||
#### Allgemeiner Verbund (Theta-JOIN / INNER JOIN)
|
||
- Beliebige Attribute und Bedingungen
|
||
- Keine Attribute werden eliminiert
|
||
|
||
```sql
|
||
SELECT p.Name Professor, a.Name Assistent
|
||
FROM Professoren p JOIN Assistenten a ON p.PersNr = a.Boss;
|
||
```
|
||
|
||
### 6.3 Äußere JOINs (Folien 31–37)
|
||
|
||
Tupel **ohne Partner werden mit NULL ergänzt** und bleiben im Ergebnis.
|
||
|
||
| Typ | Beschreibung | SQL |
|
||
|---|---|---|
|
||
| **LEFT OUTER JOIN** | Alle Tupel der **linken** Relation bleiben, rechts ggf. NULL | `L LEFT OUTER JOIN R ON ...` |
|
||
| **RIGHT OUTER JOIN** | Alle Tupel der **rechten** Relation bleiben, links ggf. NULL | `L RIGHT OUTER JOIN R ON ...` |
|
||
| **FULL OUTER JOIN** | Alle Tupel **beider** Relationen bleiben, ggf. NULL | `L FULL OUTER JOIN R ON ...` |
|
||
|
||
**Beispiel LEFT OUTER JOIN:**
|
||
|
||
| L.A | L.B | L.C | R.D | R.E |
|
||
|---|---|---|---|---|
|
||
| a1 | b1 | c1 | d1 | e1 |
|
||
| a2 | b2 | c2 | **NULL** | **NULL** |
|
||
|
||
### 6.4 Semi-JOINs (Folien 38–46)
|
||
|
||
Liefern Tupel **nur aus einer** der beiden Relationen.
|
||
|
||
| Operator | Symbol | Beschreibung | Formel |
|
||
|---|---|---|---|
|
||
| Semi-JOIN L mit R | L ⋉ R | Tupel aus L, die Partner in R haben | π_L(L ⋈ R) |
|
||
| Semi-JOIN R mit L | L ⋊ R | Tupel aus R, die Partner in L haben | π_R(L ⋈ R) |
|
||
| Anti-Semi-JOIN L | L ⊲ R | Tupel aus L **ohne** Partner in R | L — (L ⋉ R) |
|
||
| Anti-Semi-JOIN R | L ⊳ R | Tupel aus R **ohne** Partner in L | R — (L ⋊ R) |
|
||
|
||
```sql
|
||
-- Semi-JOIN
|
||
SELECT L.* FROM L INNER JOIN R ON L.x = R.x;
|
||
SELECT L.* FROM L INNER JOIN R USING (x);
|
||
```
|
||
|
||
### 6.5 SQL-Implementierung (Folien 47–53)
|
||
|
||
| SQL-Schlüsselwort | Entsprechung |
|
||
|---|---|
|
||
| CROSS JOIN | Kartesisches Produkt |
|
||
| NATURAL JOIN | Natürlicher Verbund |
|
||
| INNER JOIN | Allgemeiner Verbund (Theta-JOIN) |
|
||
| LEFT OUTER JOIN | Linker äußerer Verbund |
|
||
| RIGHT OUTER JOIN | Rechter äußerer Verbund |
|
||
| FULL OUTER JOIN | Vollständiger äußerer Verbund |
|
||
|
||
---
|
||
|
||
## 7. Anfragebearbeitung (Folien 54–58)
|
||
|
||
### Ablauf einer SQL-Anweisung
|
||
|
||
1. **Parser** → Syntax prüfen
|
||
2. **Optimizer** → Optimalen Zugriffsplan erstellen
|
||
3. **Row Source Generator** → Ausführungsplan auf physische Ressourcen
|
||
4. **Execution Engine** → Ergebnisse erzeugen
|
||
|
||
### Optimizer-Algorithmen
|
||
|
||
| Typ | Beschreibung |
|
||
|---|---|
|
||
| **RBO (Rule-Based)** | Intern festgelegte Regeln; veraltet |
|
||
| **CBO (Cost-Based)** | Interne Statistiken über Tabellen/Indizes; empfohlen |
|
||
|
||
**Wichtig:** Statistiken müssen regelmäßig aktualisiert werden (Befehl `ANALYZE`). Optimizer-Hints möglich: `/*+CHOOSE */`, `/*+ORDERED */`
|
||
|
||
### Suchverfahren
|
||
|
||
| Methode | Voraussetzung | Geschwindigkeit |
|
||
|---|---|---|
|
||
| **Full Table Scan** | Keine geeigneten Indizes | Langsamste |
|
||
| **Index-Scan** | Geeigneter Index vorhanden | Schnellste (Rückgabe: RowID) |
|
||
| **Hash-Scan** | Keine Indizes; Hash-Werte werden generiert | Mittel |
|
||
|
||
### Join-Verfahren
|
||
|
||
| Verfahren | Beschreibung |
|
||
|---|---|
|
||
| **Verschachtelte Schleifen** (Nested Loops) | Äußere Schleife + innere Schleife für jede Zeile |
|
||
| **Sort-Merge-Join** | Beide Tabellen sortieren, dann zusammenführen |
|
||
| **Hash-Join** | Hash-Tabelle für eine Tabelle, Suche mit Werten der anderen |
|
||
| **Kartesisches Produkt** | Bei fehlenden Verbindungsbedingungen |
|
||
| **Index-Join** | Indizes statt Tabellen verknüpfen (nur bei einspaltigen Indizes) |
|
||
|
||
---
|
||
|
||
## 8. Indizes (Folien 59–95)
|
||
|
||
### 8.1 Überblick (Folie 59)
|
||
|
||
| Index-Typ | Geeignet für | Beispiel |
|
||
|---|---|---|
|
||
| **Konventionell (Binärbaum)** | Spalten mit vielen unterschiedlichen Werten | PersID, Matrikelnummer |
|
||
| **Bitmap** | Spalten mit vielen gleichen Werten (geringe Kardinalität) | Geschlecht, Kategorie |
|
||
|
||
**Allgemeiner Aufbau:** `{ [ Suchfeld, RowID ] }`
|
||
|
||
### 8.2 Lineare Listen (Folien 60–64)
|
||
|
||
**Einfach verkettete Liste:** Jedes Element hat Daten + Zeiger auf nächstes Element.
|
||
|
||
**Doppelt verkettete Liste:** Zusätzlicher Rückwärts-Zeiger.
|
||
|
||
**Operationen:**
|
||
- Anhängen am Ende (keine Sortierung): O(1)
|
||
- Sortiertes Einfügen: O(n)
|
||
- Löschen: Zeiger des Vorgängers auf Nachfolger setzen, Speicher freigeben
|
||
|
||
### 8.3 Binärbäume (Folien 65–75)
|
||
|
||
**Terminologie:**
|
||
|
||
| Begriff | Bedeutung |
|
||
|---|---|
|
||
| **Wurzel (Root)** | Einziger Knoten ohne Vorgänger |
|
||
| **Blatt** | Knoten ohne Nachfolger |
|
||
| **Innerer Knoten** | Weder Wurzel noch Blatt |
|
||
| **Kante** | Gerichtete Verbindung (Vorgänger → Nachfolger) |
|
||
| **Ebene** | Knoten mit gleicher Pfadlänge zur Wurzel |
|
||
| **Tiefe** | Gesamtzahl der Ebenen |
|
||
| **Grad** | Maximale Anzahl direkter Nachfolger |
|
||
|
||
**Suchaufwand:** Logarithmisch O(log n) — aber kann zu O(n) degradieren wenn Baum entartet.
|
||
|
||
**AVL-Baum:** Höhe beider Teilbäume an jedem Knoten unterscheidet sich höchstens um 1.
|
||
|
||
**Balancierter Baum:** Höchstens letzte Ebene nicht vollständig besetzt. Jeder balancierte Baum ist ein AVL-Baum, aber nicht umgekehrt.
|
||
|
||
### Durchlauf-Reihenfolgen
|
||
|
||
| Reihenfolge | Kürzel | Verwendung |
|
||
|---|---|---|
|
||
| **Preorder** | WLR | Baum linear auf Datenträger speichern |
|
||
| **Inorder** | LWR | Sortierte Liste erstellen → balancierten Baum erzeugen |
|
||
| **Postorder** | LRW | Geräte programmieren (erst Parameter, dann Operation) |
|
||
|
||
### Balancierung
|
||
|
||
- **Offline:** Kopie → Inorder-Liste → Binär einfügen → Ausgeglichener Baum. Einfach, aber Zugriffe gesperrt.
|
||
- **Online:** Zur Laufzeit rekursiv ausgleichen. Kann kurzfristig zu Fehlern führen.
|
||
|
||
### 8.4 Hashing (Folien 76–90)
|
||
|
||
**Funktionsprinzip:**
|
||
1. Für jeden Datensatz wird ein Schlüssel gebildet
|
||
2. Hash-Funktion ordnet dem Schlüssel einen kurzen Hash-Wert zu
|
||
3. Hash-Wert dient als Index in der Hash-Tabelle
|
||
4. Hash-Tabelle enthält Verweise auf Datensätze
|
||
|
||
**Kollision:** Zwei unterschiedliche Schlüssel erzeugen denselben Hash-Wert.
|
||
|
||
**Kollisionsbehandlung:**
|
||
- **Hashing mit Verkettung:** Verkettete Listen an Hash-Tabellen-Einträgen
|
||
- **Lineares Hashing:** Dynamische Tabellenerweiterung bei hohem Belegungsfaktor
|
||
- **Sondierung:** Linear/quadratisch/zufällig in der Tabelle selbst suchen
|
||
|
||
**Anforderungen an Hash-Funktionen:**
|
||
- Effizient berechenbar, geringer Speicherbedarf
|
||
- Wenig Kollisionen (Gleichverteilung der Hash-Werte)
|
||
- Einwegfunktion (Hash → Schlüssel nicht berechenbar)
|
||
- Surjektivität (kein Hash-Wert unmöglich)
|
||
- **Lawineneffekt:** 1 Bit Unterschied → mindestens halbe Bits der Hash-Werte unterschiedlich
|
||
|
||
**Hash-Funktions-Beispiele:**
|
||
1. **Modulo:** HW = Key % Basis (Primzahlen empfohlen)
|
||
2. **Abschneiden:** Key² berechnen, dann von links/rechts kürzen
|
||
3. **Zerlegung & Addition:** Key in gleich große Teile zerlegen und addieren
|
||
|
||
**Binärbäume vs. Hashing:**
|
||
- Bäume: Garantie im Worst Case, Sortierung möglich, dynamische Größe
|
||
- Hashing: Schneller im Durchschnitt O(1) vs. O(log n)
|
||
|
||
### 8.5 Bitmap-Indizes (Folien 92–95)
|
||
|
||
**Geeignet für:**
|
||
- Geringe Kardinalität (0,1%–1% unterschiedliche Werte)
|
||
- Wenige Änderungen (Data Warehouse / OLAP)
|
||
|
||
**Aufbau:** Für jeden einzigartigen Wert eine Bit-Spalte. Pro Zeile steht 1 (Treffer) oder 0 (kein Treffer).
|
||
|
||
**Vorteile:**
|
||
- Stark komprimiert → schnell lesbar
|
||
- Mehrere Indizes kombinierbar
|
||
- Logische Operationen (AND, OR) sehr schnell im Prozessor
|
||
|
||
**Nachteile:**
|
||
- Immenser Wartungsaufwand bei Änderungen
|
||
- Bandbreite der Prozessor-Kanäle wichtig
|
||
- Können Deadlocks verursachen
|
||
|
||
---
|
||
|
||
## Zusammenfassung
|
||
|
||
| Thema | Kernaussage |
|
||
|---|---|
|
||
| SQL-Kategorien | DDL (Struktur), DML (Daten), DCL (Rechte), TCL (Transaktionen) |
|
||
| Einfache Befehle | CREATE, INSERT, UPDATE, DELETE, SELECT |
|
||
| JOINs | Inner (NATURAL, Theta), Outer (LEFT, RIGHT, FULL), Semi (⋉, ⋊, ⊲, ⊳) |
|
||
| Anfragebearbeitung | Parser → Optimizer (RBO/CBO) → Row Source Generator → Execution Engine |
|
||
| Suchverfahren | Full Table Scan, Index-Scan (schnellste), Hash-Scan |
|
||
| Binärbäume | O(log n) Suche; AVL/balanciert halten; Preorder/Inorder/Postorder |
|
||
| Hashing | O(1) Durchschnitt; Kollisionsbehandlung; Modulo/Abschneiden/Zerlegung |
|
||
| Bitmap-Indizes | Für geringe Kardinalität; Bit-Spalten pro Wert; schnelle logische Operationen |
|