12 KiB
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
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
-- 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:
-- 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)
SELECT column1, column2
FROM table1, table2
WHERE condition
GROUP BY column1, column2
HAVING condition
ORDER BY column1, column2;
4. Erweiterungen (Folien 12–14)
Sortieren
SELECT PersNr, Name, Rang FROM Professoren
ORDER BY Rang DESC, Name ASC;
Duplikate eliminieren
SELECT DISTINCT Rang FROM Professoren;
Platzhalter (nur mit LIKE)
_— genau ein Zeichen%— beliebig viele Zeichen (auch keines)
SELECT * FROM Professoren WHERE Rang LIKE 'W_';
SELECT * FROM Professoren WHERE Name LIKE 'T%eophrastos';
IN / NOT IN
SELECT Name FROM Studenten WHERE Semester IN (1, 2, 3);
SELECT Name FROM Professoren
WHERE PersNr NOT IN (SELECT gelesenVon FROM Vorlesungen);
ALL / ANY
-- 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:
- Kreuzprodukt aus Tabellen bilden
- Relevante Zeilen und Felder ausschneiden
Wichtigste Voraussetzung: Information über Verbindung zwischen Tabellen (Join-Prädikat).
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
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
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) |
-- 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
- Parser → Syntax prüfen
- Optimizer → Optimalen Zugriffsplan erstellen
- Row Source Generator → Ausführungsplan auf physische Ressourcen
- 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:
- Für jeden Datensatz wird ein Schlüssel gebildet
- Hash-Funktion ordnet dem Schlüssel einen kurzen Hash-Wert zu
- Hash-Wert dient als Index in der Hash-Tabelle
- 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:
- Modulo: HW = Key % Basis (Primzahlen empfohlen)
- Abschneiden: Key² berechnen, dann von links/rechts kürzen
- 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 |