# 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 |