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 +![image_891.png](image_891.png) + +#### Variante 2: Super- und Subtypen als Tabellen +![image_892.png](image_892.png) + +#### Variante 3: Super- und Subtypen als Tabellen mit Redundanz +![image_893.png](image_893.png) + +#### Variante 4: Supertyp als Tabelle mit Typ-Attribut +![image_894.png](image_894.png) + +### 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 +- ![image_895.png](image_895.png) +### 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 +- ![image_896.png](image_896.png) + +### 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 +- ![image_897.png](image_897.png) + +#### 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 + - ![image_899.png](image_899.png) + - ```sql + SELECT spaltenname1, spaltenname2 + FROM tabellenname1 + EXCEPT + SELECT spaltenname1, spaltenname2 + FROM tabellenname2; + ``` +- **INTERSECT** + - Schnittmenge zweier Tabellen + - ![image_900.png](image_900.png) + - ```sql + SELECT spaltenname1, spaltenname2 + FROM tabellenname1 + INTERSECT + SELECT spaltenname1, spaltenname2 + FROM tabellenname2; + ``` +- **UNION** + - Tabellen zusammenführen + - ![image_898.png](image_898.png) + - ```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