diff --git a/Writerside/images/image_891.png b/Writerside/images/image_891.png
new file mode 100644
index 0000000..1b853f5
Binary files /dev/null and b/Writerside/images/image_891.png differ
diff --git a/Writerside/images/image_892.png b/Writerside/images/image_892.png
new file mode 100644
index 0000000..5d39b01
Binary files /dev/null and b/Writerside/images/image_892.png differ
diff --git a/Writerside/images/image_893.png b/Writerside/images/image_893.png
new file mode 100644
index 0000000..5794e70
Binary files /dev/null and b/Writerside/images/image_893.png differ
diff --git a/Writerside/images/image_894.png b/Writerside/images/image_894.png
new file mode 100644
index 0000000..99be6bb
Binary files /dev/null and b/Writerside/images/image_894.png differ
diff --git a/Writerside/images/image_895.png b/Writerside/images/image_895.png
new file mode 100644
index 0000000..e7b0e5d
Binary files /dev/null and b/Writerside/images/image_895.png differ
diff --git a/Writerside/images/image_896.png b/Writerside/images/image_896.png
new file mode 100644
index 0000000..283eee2
Binary files /dev/null and b/Writerside/images/image_896.png differ
diff --git a/Writerside/images/image_897.png b/Writerside/images/image_897.png
new file mode 100644
index 0000000..78bace6
Binary files /dev/null and b/Writerside/images/image_897.png differ
diff --git a/Writerside/images/image_898.png b/Writerside/images/image_898.png
new file mode 100644
index 0000000..7695c09
Binary files /dev/null and b/Writerside/images/image_898.png differ
diff --git a/Writerside/images/image_899.png b/Writerside/images/image_899.png
new file mode 100644
index 0000000..4070b55
Binary files /dev/null and b/Writerside/images/image_899.png differ
diff --git a/Writerside/images/image_900.png b/Writerside/images/image_900.png
new file mode 100644
index 0000000..27a1527
Binary files /dev/null and b/Writerside/images/image_900.png differ
diff --git a/Writerside/in.tree b/Writerside/in.tree
index cac40f1..036e1dc 100644
--- a/Writerside/in.tree
+++ b/Writerside/in.tree
@@ -78,6 +78,9 @@
+
+
+
diff --git a/Writerside/topics/04/Datenbanken/01_semantischeDatenmodellierungUndRelationenmodell.md b/Writerside/topics/04/Datenbanken/01_semantischeDatenmodellierungUndRelationenmodell.md
index e258e4b..2bbec04 100644
--- a/Writerside/topics/04/Datenbanken/01_semantischeDatenmodellierungUndRelationenmodell.md
+++ b/Writerside/topics/04/Datenbanken/01_semantischeDatenmodellierungUndRelationenmodell.md
@@ -216,3 +216,57 @@
### Abbildung Vererbungshierarchien
+> Subtyp erbt mindestens PK des Supertyps
+
+#### Variante 1: Nur Spezialisierungen als Tabellen
+
+
+#### Variante 2: Super- und Subtypen als Tabellen
+
+
+#### Variante 3: Super- und Subtypen als Tabellen mit Redundanz
+
+
+#### Variante 4: Supertyp als Tabelle mit Typ-Attribut
+
+
+### Nicht-Atomare Attribute
+- Arrays auslagern
+ - neue Klasse
+ - Zeile duplizieren
+
+## Normalisierung
+### 1. NF
+- Alle Attribute sind atomar
+ - keine Arrays, Listen, Objekte
+
+#### Anomalien
+##### Einfügeanomalie
+- Einfügen eines neuen Tupels ist nicht möglich, da kein Wert für ein Attribut vorhanden
+
+##### Änderungsanomalie
+- Änderung eines Wertes in einem Tupel erfordert Änderung in mehreren Tupeln
+ - Gefahr der Inkonsistenz
+
+##### Löschanomalie
+- Löschen eines Tupels führt zum Verlust von Informationen, die nicht gelöscht werden sollten
+ - z.B. wenn nur ein Attribut gelöscht wird, aber andere Attribute noch vorhanden sind
+
+### 2. ΝF
+- ist in 1. NF
+- Jedes Nicht-Schlüsselattribut ist voll funktional abhängig vom Primärschlüssel
+ - d.h. es gibt keine partiellen Abhängigkeiten
+ - bspw:
+ - Schüler, Klasse, Klassenlehrer (Klassenlehrer schlecht, da er nur von Klasse abhängt)
+
+### 3. NF
+- ist in 2. NF
+- Jedes Nicht-Schlüsselattribut ist transitiv abhängig vom Primärschlüssel
+ - d.h. es gibt keine transitiven Abhängigkeiten
+ - A→B B→C :(
+
+### Denormalisierung
+- Normalisierung führt zu vielen Tabellen
+ - kann Performance beeinträchtigen
+ - Nur, falls das tatsächlich ein Problem ist denormalisieren
+
diff --git a/Writerside/topics/04/Datenbanken/02_semantischeDatenmodellierung.md b/Writerside/topics/04/Datenbanken/02_semantischeDatenmodellierung.md
new file mode 100644
index 0000000..5575829
--- /dev/null
+++ b/Writerside/topics/04/Datenbanken/02_semantischeDatenmodellierung.md
@@ -0,0 +1,52 @@
+# Interne Datenorganisation
+## Index und B-Baum
+### Dünner Index
+- Indexeinträge für jede Page
+ - Indizierte Daten müssen innerhalb der Page sortiert sein und einmalig vorkommen
+- Hat weniger Datensätze als eigentliche Tabelle
+- Enthält nur die Page-Nummer und den Schlüsselwert
+ - Meistens verwendet für Primärschlüssel
+- 
+### Dichter Index
+- Indexeinträge für jeden Record
+ - Indizierte Daten müssen nicht sortiert sein
+ - Indexeinträge können mehrfach vorkommen
+- Hat gleiche Anzahl Datensätze wie die eigentliche Tabelle
+- Enthält Page-Nummer, Record-Nummer und den Schlüsselwert
+- 
+
+### Mehrstufiger Index (Baum)
+- Indexeinträge sind in einem Baum organisiert
+- Jeder Knoten enthält Schlüsselwerte und Zeiger auf die Kinderknoten
+
+### B-Baum
+- Balancierter mehrstufiger Index
+- 
+
+#### Suchen in B-Bäumen
+- Suche beginnt an der Wurzel
+- Ist x im Knoten enthalten?
+ - Ja: Suche beendet
+ - Nein: Gehe zum Kindknoten, dessen Schlüsselwert am nächsten an x liegt
+ - Ist Knoten Blattknoten?
+ - Ja: Suche erfolglos beendet
+ - Nein: Wiederhole Suche im Kindknoten
+ - Zwischen welchen Schlüsselwerten liegt x?
+ - Gehe zum jeweiligen Kindknoten (> → rechts / < → links)
+
+#### Einfügen in B-Bäume
+- Suche nach der Position, an der x eingefügt werden soll
+- Ist der Knoten voll? (Anzahl der Schlüsselwerte = 2m)
+ - Ja: Knoten teilen
+ - Mittleren Schlüsselwert in den Elternknoten einfügen
+ - Falls Elternknoten voll wiederhole Teilung nach oben
+ - Falls Elternknoten Wurzel ist, wird eine neue Wurzel erstellt
+ - B-Baum wächst um eine Stufe
+ - Nein: Einfügen des Wertes in den Knoten
+
+
+### Variante B+ Baum
+- Keine Daten in den Knoten
+ - Nur Schlüsselwerte und Zeiger auf die Kinderknoten
+ - Daten befinden sich in den Blattknoten
+- Suche, Einfügen, Löschen immer $O(log n)$
diff --git a/Writerside/topics/04/Datenbanken/03_sql.md b/Writerside/topics/04/Datenbanken/03_sql.md
new file mode 100644
index 0000000..c9091e0
--- /dev/null
+++ b/Writerside/topics/04/Datenbanken/03_sql.md
@@ -0,0 +1,259 @@
+# SQL
+## Spracharten
+### DDL (Data Definition Language)
+### DML (Data Manipulation Language)
+### DCL (Data Control Language)
+
+## SQL als DDL
+- **CREATE**
+ - ```sql
+ CREATE TABLE tabellenname (
+ spaltenname1 datentyp [Einschränkungen],
+ spaltenname2 datentyp [Einschränkungen],
+ ...
+ PRIMARY KEY (spaltenname1, spaltenname2)
+ );
+ ```
+ - ```sql
+ CREATE INDEX indexname
+ ON tabellenname (spaltenname) ASC;
+ ```
+
+
+- **ALTER**
+ - ```sql
+ ALTER TABLE tabellenname
+ ADD spaltenname datentyp [Einschränkungen];
+
+ ALTER TABLE tabellenname
+ DROP COLUMN spaltenname;
+
+ ALTER TABLE tabellenname
+ ALTER COLUMN spaltenname SET NOT NULL;
+
+ ALTER TABLE tabellenname
+ RENAME COLUMN alter_spaltenname TO neuer_spaltenname;
+
+ ALTER TABLE tabellenname
+ DROP CONSTRAINT constraint_name;
+ ```
+- **DROP**
+ - Löschen einer gesamten Tabelle/Index/View
+ - ```sql
+ DROP TABLE tabellenname;
+
+ DROP INDEX indexname;
+
+ DROP VIEW viewname;
+ ```
+
+### Datentypen
+- **integer** (oder auch integer4, int),
+- **smallint** (oder auch integer2),
+- **real** (vergleichbar zu float),
+- **decimal**(p,q) und numeric(p,q) mit jeweils p Stellen gesamt und davon q Nachkommastellen,
+- **character**(n) (oder kurz char(n), bei n = 1 auch char) für Zeichenketten (Strings) fester Länge n,
+- **character varying**(n) (oder kurz **varchar**(n) für Strings variabler Länge bis zur Maximallänge n,
+- **bit**(n) oder bit varying(n) analog für Bitfolgen, und
+- **date**, **time** bzw. **timestamp** für Datums-, Zeit- und kombinierte Datums-Zeit-Angaben
+- **blob** (binary large object) für sehr große binäre Daten
+- **text** oder clob für sehr große Strings
+
+### Constraints
+- **NOT NULL**: Spalte darf nicht leer sein
+- **DEFAULT**: Standardwert für die Spalte
+- **UNIQUE**, bzw. **PRIMARY KEY**: Spalte muss eindeutige Werte haben
+- **FOREIGN KEY**: Verweis auf eine andere Tabelle
+- **CHECK**: Bedingung, die für die Spalte gelten muss
+
+```sql
+CREATE TABLE person (
+ id SERIAL PRIMARY KEY,
+ name VARCHAR(20) NOT NULL,
+ email VARCHAR(50) UNIQUE,
+ age INT CHECK (age >= 0),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+ FOREIGN KEY (personalId) REFERENCES andere_tabelle(id)
+);
+```
+
+### Referentielle Integrität
+- **CASCADE**: Operation wird auf alle zugehörigen Datensätze angewendet
+- **SET DEFAULT**: Fremdschlüssel wird auf den Standardwert gesetzt
+- **SET NULL**: Fremdschlüssel wird auf NULL gesetzt
+- **RESTRICT**: Operation wird nur ausgeführt, wenn keine Fremdschlüsselbedingung verletzt wird
+- **NO ACTION**: Keine Aktion, wenn Fremdschlüsselbedingung verletzt wird (Standardverhalten)
+
+```sql
+CREATE TABLE bestellung (
+ id SERIAL PRIMARY KEY,
+ kunde_id INT,
+ produkt_id INT,
+ FOREIGN KEY (kunde_id) REFERENCES kunde(id) ON DELETE CASCADE,
+ FOREIGN KEY (produkt_id) REFERENCES produkt(id) ON DELETE SET NULL
+);
+```
+
+## SQL als DML
+- **Insert**
+ - ```sql
+ INSERT INTO tabellenname (spaltenname1, spaltenname2, ...)
+ VALUES (wert1, wert2, ...);
+ ```
+- **Update**
+ - ```sql
+ UPDATE tabellenname
+ SET spaltenname1 = wert1, spaltenname2 = wert2, ...
+ WHERE bedingung;
+ ```
+- **Delete**
+ - ```sql
+ DELETE FROM tabellenname
+ WHERE bedingung;
+ ```
+### Alle Tabelleninhalte löschen
+```sql
+TRUNCATE TABLE tabellenname;
+```
+
+## Relationenalgebra
+- **SELECT DISTINCT**
+ - Nur einmalige Werte auswählen
+ - ```sql
+ SELECT DISTINCT spaltenname1, spaltenname2
+ FROM tabellenname;
+ ```
+- **WHERE**
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname1, tabellenname2
+ WHERE bedingung;
+ ```
+ - **BETWEEN**
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname
+ WHERE spaltenname BETWEEN wert1 AND wert2;
+ ```
+ - **AND**
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname
+ WHERE bedingung1 AND bedingung2;
+ ```
+ - **OR**
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname
+ WHERE bedingung1 OR bedingung2;
+ ```
+ - **LIKE**
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname
+ WHERE spaltenname LIKE 'muster%';
+ ```
+ - **IS [NOT] NULL**
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname
+ WHERE spaltenname IS NULL;
+ ```
+- **[NOT] IN**
+ - geschachtelte Anfragen
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname
+ WHERE spaltenname1 IN
+ (SELECT spaltenname1 FROM tabellenname2 WHERE bedingung);
+ ```
+- **FROM**
+ - **JOIN...ON**
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname1
+ JOIN tabellenname2 ON tabellenname1.spaltenname = tabellenname2.spaltenname;
+ ```
+ - **LEFT JOIN**
+ - übernimmt alle Zeilen aus der linken Tabelle und die passenden aus der rechten
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname1
+ LEFT JOIN tabellenname2 ON tabellenname1.spaltenname = tabellenname2.spaltenname;
+ ```
+ - **RIGHT JOIN**
+ - übernimmt alle Zeilen aus der rechten Tabelle und die passenden aus der linken
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname1
+ RIGHT JOIN tabellenname2 ON tabellenname1.spaltenname = tabellenname2.spaltenname;
+ ```
+ - **FULL OUTER JOIN**
+ - übernimmt alle Zeilen aus beiden Tabellen, auch wenn keine Übereinstimmung besteht
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname1
+ FULL OUTER JOIN tabellenname2 ON tabellenname1.spaltenname = tabellenname2.spaltenname;
+ ```
+ - **NATURAL JOIN**
+ - gleiche Spaltennamen in beiden Tabellen werden automatisch verbunden (falls auch gleicher Datentyp)
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname1
+ NATURAL JOIN tabellenname2;
+ ```
+- **AS**
+ - Spalten umbenennen
+ - ```sql
+ SELECT spaltenname1 AS aliasname1, spaltenname2 AS aliasname2
+ FROM tabellenname;
+ ```
+ - ```sql
+ SELECT spaltenname1+4 AS aliasname
+ FROM tabellenname;
+ ```
+- **EXCEPT**
+ - Tabellen voneinander subtrahieren
+ - 
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname1
+ EXCEPT
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname2;
+ ```
+- **INTERSECT**
+ - Schnittmenge zweier Tabellen
+ - 
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname1
+ INTERSECT
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname2;
+ ```
+- **UNION**
+ - Tabellen zusammenführen
+ - 
+ - ```sql
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname1
+ UNION
+ SELECT spaltenname1, spaltenname2
+ FROM tabellenname2;
+ ```
+- **GROUP BY...[HAVING]**
+ - Gruppierung von Zeilen
+ - ```sql
+ SELECT spaltenname1, COUNT(*)
+ FROM tabellenname
+ GROUP BY spaltenname1;
+ HAVING COUNT(*) > 1;
+ ```
+
+- Aggregatfunktionen
+ - **COUNT**: Anzahl der Zeilen
+ - **SUM**: Summe der Werte
+ - **AVG**: Durchschnitt der Werte
+ - **MIN**: Minimalwert
+ - **MAX**: Maximalwert
\ No newline at end of file