diff --git a/20231130/Zeichen_123.pdf b/20231130/Zeichen_123.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..fdbc897227df059cfda790a16555e6e417682116
--- /dev/null
+++ b/20231130/Zeichen_123.pdf
@@ -0,0 +1 @@
+../common/Zeichen_123.pdf
\ No newline at end of file
diff --git a/20231130/dbs-20231130.pdf b/20231130/dbs-20231130.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..8001939dd4fe777c0849ee8b699e753090c30748
Binary files /dev/null and b/20231130/dbs-20231130.pdf differ
diff --git a/20231130/dbs-20231130.tex b/20231130/dbs-20231130.tex
new file mode 100644
index 0000000000000000000000000000000000000000..4a039d911b98ac1088d0707800db846ce3b97f45
--- /dev/null
+++ b/20231130/dbs-20231130.tex
@@ -0,0 +1,464 @@
+% dbs-20221130.pdf - Lecture Slides on Databases and Information Security
+% Copyright (C) 2023  Peter Gerwinski
+%
+% This document is free software: you can redistribute it and/or
+% modify it either under the terms of the Creative Commons
+% Attribution-ShareAlike 3.0 License, or under the terms of the
+% GNU General Public License as published by the Free Software
+% Foundation, either version 3 of the License, or (at your option)
+% any later version.
+%
+% This document is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this document.  If not, see <http://www.gnu.org/licenses/>.
+%
+% You should have received a copy of the Creative Commons
+% Attribution-ShareAlike 3.0 Unported License along with this
+% document.  If not, see <http://creativecommons.org/licenses/>.
+
+% README: Transaktionen, Indizierung, GUI-Zugriff
+
+\documentclass[10pt,t]{beamer}
+
+\usepackage{pgslides}
+
+\newcommand{\vfilll}{\vspace{0pt plus 1filll}}
+
+\newcommand{\underconstruction}{%
+  \begin{picture}(0,0)
+    \put(11,1.2){\makebox(0,0)[b]{\includegraphics[width=1.5cm]{Zeichen_123.pdf}}}
+    \put(11,0.9){\makebox(0,0)[t]{\shortstack{Änderungen\\vorbehalten}}}
+  \end{picture}}
+
+\title{Datenbanken und Datensicherheit}
+\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski}
+\date{30.\ November 2023}
+
+\begin{document}
+
+\maketitleframe
+
+\nosectionnonumber{\inserttitle}
+
+\begin{frame}
+
+  \shownosectionnonumber
+
+  \begin{itemize}
+    \item[\textbf{1}] \textbf{Einführung}
+      \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/dbs}}}%
+    \item[\textbf{2}] \textbf{Kurzeinführung Unix}
+    \item[\textbf{3}] \textbf{Kurzeinführung TCP/IP}
+    \item[\textbf{4}] \textbf{Relationale Datenbanken}
+      \begin{itemize}
+        \vspace*{-\smallskipamount}
+        \item[\textbf{\dots}]
+        \item[4.3] Normalformen
+        \color{medgreen}
+        \item[4.4] Verknüpfungen von Tabellen
+        \item[4.5] Sichten
+        \item[4.6] Schlüsselfelder
+        \item[4.7] Datensicherung
+        \color{red}
+        \item[4.8] Transaktionen
+        \item[4.9] Indizierung
+        \color{black}
+        \item[4.10] Trigger
+        \color{red}
+        \item[4.11] GUI-Zugriff
+        \color{black}
+        \item[4.12] Sonstige Datenbanken
+      \end{itemize}
+    \item[\textbf{5}] \textbf{Kryptographie}
+      \begin{itemize}
+        \item[5.1] Einführung
+        \vspace*{-\smallskipamount}
+        \item[\textbf{\dots}]
+      \end{itemize}
+    \vspace*{-\smallskipamount}
+    \item[\textbf{\dots}]
+  \end{itemize}
+
+  \vfilll
+  \underconstruction
+
+\end{frame}
+
+\setcounter{section}{3}
+\section{Relationale Datenbanken}
+\setcounter{subsection}{2}
+\subsection{Normalformen}
+
+\begin{frame}
+
+  \showsection
+  \showsubsection
+
+  Problem: Schlecht angelegte Datenbanken werden schnell inkonsistent.\\
+  Beliebte Fehler:
+  \begin{itemize}
+    \item
+      Speichern von mehreren Daten in demselben Tabelleneintrag\\
+      {\only<1->{\color{red}\textarrow\ 1.~Normalform}}
+    \item
+      Speichern von denselben Daten in verschiedenen Tabelleneinträgen\\
+      {\only<1->{\color{red}\textarrow\ 2.~Normalform}}
+    \item
+      implizite Zusammenhänge\\
+      {\only<1->{\color{red}\textarrow\ 3.~Normalform und Boyce-Codd-Normalform}}
+    \item
+      voneinander unabhängige Zusammenhänge in derselben Tabelle\\
+      {\only<1->{\color{red}\textarrow\ 4.~und 5.~Normalform}}
+  \end{itemize}
+
+  \begin{onlyenv}<1->
+    \medskip
+
+    {\color{red}Lösung: Normalformen}
+  \end{onlyenv}
+
+  \bigskip
+
+  Literatur: z.\,B.\ \url{https://de.wikipedia.org/wiki/Normalisierung_(Datenbank)}
+
+\end{frame}
+
+\subsection{Verknüpfungen von Tabellen}
+
+\begin{frame}
+
+  \showsection
+  \showsubsection
+
+  Problem: Gut angelegte Datenbanken ({\color{red}\textarrow\ Normalformen})\\
+  sind stark aufgesplittet.\\
+  Wie kann man sie weiterhin effizient benutzen?
+
+  \bigskip
+
+  Lösung: Verknüpfungen von Tabellen
+
+  \bigskip
+
+  SQL-Befehl: \lstinline[style=cmd]{JOIN}
+
+  \bigskip
+
+  Literatur: z.\,B.\ \url{https://de.wikipedia.org/wiki/SQL}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  Was machen wir mit Tabelleneinträgen,\\
+  bei denen die \lstinline[style=cmd]{ON}-Bedingung
+  nicht erfüllt ist?
+
+  \medskip
+
+  \begin{lstlisting}[style=terminal]
+    ¡SELECT <Feld[er]> FROM <Tabelle1> [INNER] JOIN <Tabelle2>
+           ON <Tabelle1>.<Feld> = <Tabelle2>.<Feld>;¿
+  \end{lstlisting}
+
+  \smallskip
+
+  \begin{itemize}
+    \arrowitem
+      weglassen: \lstinline[style=cmd]{[INNER] JOIN}
+  \end{itemize}
+
+  \medskip
+
+  \begin{lstlisting}[style=terminal]
+    ¡SELECT <Feld[er]> FROM <Tabelle1> LEFT JOIN <Tabelle2>
+           ON <Tabelle1>.<Feld> = <Tabelle2>.<Feld>;¿
+  \end{lstlisting}
+
+  \smallskip
+
+  \begin{itemize}
+    \arrowitem
+      linke Tabelle trotzdem anzeigen
+      (mit \lstinline[style=cmd]{NULL}-Einträgen):
+      \lstinline[style=cmd]{LEFT JOIN}\\
+      (analog: \lstinline[style=cmd]{RIGHT JOIN} für rechte Tabelle)
+  \end{itemize}
+
+  \medskip
+
+  \begin{lstlisting}[style=terminal]
+    ¡SELECT <Feld[er]> FROM <Tabelle1> FULL JOIN <Tabelle2>
+           ON <Tabelle1>.<Feld> = <Tabelle2>.<Feld>;¿
+  \end{lstlisting}
+
+  \smallskip
+
+  \begin{itemize}
+    \arrowitem
+      beide Tabellen trotzdem anzeigen
+      (mit \lstinline[style=cmd]{NULL}-Einträgen):
+      \lstinline[style=cmd]|FULL JOIN|
+  \end{itemize}
+
+\end{frame}
+
+\subsection{Sichten}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \begin{lstlisting}[style=terminal]
+    ¡SELECT <Feld[er]> FROM <Tabelle1> [INNER] JOIN <Tabelle2>
+           ON <Tabelle1>.<Feld> = <Tabelle2>.<Feld>;¿
+  \end{lstlisting}
+
+  \smallskip
+
+  \begin{itemize}
+    \arrowitem
+      Wir betrachten beide Tabellen zusammen als eine große Tabelle.
+  \end{itemize}
+
+  \medskip
+
+  \begin{lstlisting}[style=terminal]
+    ¡CREATE VIEW <Sicht> AS
+           SELECT <Feld[er]> FROM <Tabelle1> JOIN <Tabelle2>
+           ON <Tabelle1>.<Feld> = <Tabelle2>.<Feld>;
+    SELECT <Feld[er]> FROM <Sicht> [WHERE ...];¿
+  \end{lstlisting}
+
+  \smallskip
+
+  \begin{itemize}
+    \arrowitem
+      Wir sprechen das Ergebnis genau wie eine Tabelle an.
+    \bigskip
+    \arrowitem
+      Es ist möglich, ohne Verlust an Komfort alle Daten in Normalform zu halten.
+  \end{itemize}
+
+\end{frame}
+
+\subsection{Schlüsselfelder}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \begin{lstlisting}[style=terminal]
+    ¡CREATE TABLE tabelle1 (
+      id INT PRIMARY KEY AUTO_INCREMENT,
+      ...
+    );
+    CREATE TABLE tabelle2 (
+      ...
+      tabelle1_id INT,
+      ...
+      FOREIGN KEY(tabelle1_id) REFERENCES tabelle1(id)
+    );
+  \end{lstlisting}
+
+  \smallskip
+
+  \begin{itemize}
+    \arrowitem
+      Dem DBMS mitteilen, welche Felder für \lstinline[style=cmd]{JOIN}
+      vorgesehen sind.
+    \arrowitem
+      Das DBMS kann mit auf Konsistenz achten.
+  \end{itemize}
+
+\end{frame}
+
+\subsection{Datensicherung}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \begin{lstlisting}[style=terminal]
+    $ ¡pg_dump --clean -h <Rechner> -U <User> -W <Datenbank>¿
+  \end{lstlisting}
+
+  \smallskip
+
+  \begin{itemize}
+    \item
+      Ausgabe des gesamten Datenbankinhalts\\
+      als SQL-Quelltext zur Standardausgabe
+    \arrowitem
+      keine Probleme mit sich evtl.\ ändernden Binärformaten
+    \item
+      Es ist möglich, den Inhalt direkt in einer Pipe weiterzuverarbeiten\\
+      (z.\,B.\ zu komprimieren).
+    \item
+      Zurückspielen: mit \lstinline[style=cmd]{psql}
+  \end{itemize}
+
+  \smallskip
+
+  \begin{lstlisting}[style=terminal]
+    $ ¡psql -h <Rechner> -U <User> -W <Datenbank> \
+           < <Ausgabe von pg_dump>¿
+  \end{lstlisting}
+
+  \smallskip
+
+  \begin{itemize}
+    \item
+      analog für \file{MariaDB}: \lstinline[style=cmd]{mariadb-dump}
+  \end{itemize}
+
+\end{frame}
+
+\subsection{Transaktionen}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \begin{itemize}
+    \item
+      Ziel: Wahrung der Konsistenz
+    \item
+      Methode: zusammengehörige Aktionen zu einer \newterm{Transaktion} zusammenfassen
+    \item
+      Beispiel: Überweisung\\
+      Betrag von einem Konto subtrahieren\\
+      und "`gleichzeitig"' zu einem anderen Konto addieren
+    \item
+      Realisierung in PostgreSQL:
+      \lstinline[style=cmd]{BEGIN;} \dots\ \lstinline[style=cmd]{COMMIT;}
+    \item
+      Realisierung in MariaDB:
+      \lstinline[style=cmd]{START TRANSACTION;} \dots\ \lstinline[style=cmd]{COMMIT;}
+    \item
+      Abbruch einer Transaktion:
+      \lstinline[style=cmd]{ROLLBACK;} statt \lstinline[style=cmd]{COMMIT;}
+  \end{itemize}
+
+\end{frame}
+
+\subsection{Indizierung}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \begin{itemize}
+    \item
+      Ziel: Performanzgewinn
+    \item
+      Methode: Spalten, in denen häufig gesucht wird, sortieren
+    \item
+      Beispiel: Datenbank mit Kontaktdaten\\
+      Suche nach Name, Adresse, Telefonnummer
+    \item
+      Realisierung in PostgreSQL und MariaDB:
+      \begin{lstlisting}[style=cmd,gobble=8]
+        CREATE INDEX <Indexname> ON <Tabellenname>
+        (
+          <Spaltenname>,
+          ...
+        );
+      \end{lstlisting}
+    \item
+      Vorteil: schnellere Suche (\lstinline[style=cmd]{SELECT}) in indizierten Spalten
+    \pause
+    \item
+      Nachteil: langsameres Einfügen/Ändern/Löschen
+  \end{itemize}
+
+\end{frame}
+
+\addtocounter{subsection}{1}
+
+\subsection{GUI-Zugriff}
+
+\begin{frame}
+
+  \showsection
+  \showsubsection
+
+  \begin{itemize}
+    \item
+      Anwendung nutzt DBMS-Client-Bibliothek\\
+      GUI-Programmierung: wie gewohnt
+    \item
+      Spezialfall: Web-Anwendung
+  \end{itemize}
+
+  \bigskip
+
+  Beispiel: Programmiersprache PHP
+  \begin{itemize}
+    \item
+      Integration in HTML-Quelltext: \lstinline{<?php ... ?>}
+    \item
+      Objekt zur Kommunikation mit Datenbanken: \lstinline{PDO}
+  \end{itemize}
+
+\end{frame}
+
+\iffalse
+
+\subsection{Sonstige Datenbanken}
+
+\begin{frame}
+
+  \showsection
+  \showsubsection
+
+  \begin{itemize}
+    \item
+      Eingebettete Datenbanken:\\
+      Berkeley DB, SQLite\\
+      Software-Bibliothek, keine Client-Server-Struktur
+    \item
+      Nicht-relationale Datenbanken:\\
+      dokumentenorientierte Datenbanken, noSQL\\
+      Performanz wichtiger als Konsistenz\\
+      \textarrow\ Applikationen stärker in Konsistenzprüfung eingebunden
+  \end{itemize}
+
+\end{frame}
+
+\section{Kryptographie}
+\subsection{Einführung}
+
+\begin{frame}
+
+  \showsection
+  \showsubsection
+
+  \begin{itemize}
+    \item
+      Verschlüsselung: symmetrisch, asymmetrisch, hybrid
+    \item
+      Hashes: Einwegfunktionen, Salt
+    \item
+      Signaturen, Zertifikate
+    \item
+      Schlüsselaustausch
+  \end{itemize}
+
+\end{frame}
+
+\fi
+
+\end{document}
diff --git a/20231130/indexing-01.txt b/20231130/indexing-01.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2e27969ccee94ed14bb66785ee3acf197e04afaa
--- /dev/null
+++ b/20231130/indexing-01.txt
@@ -0,0 +1,28 @@
+testdb=> SELECT * FROM account where number = 'DE12 3456 7890 ABCD EFGH IJ';
+ id |           number            | balance
+----+-----------------------------+---------
+  1 | DE12 3456 7890 ABCD EFGH IJ | 1000001
+(1 Zeile)
+
+testdb=> CREATE INDEX index_account_number ON account ( number );
+CREATE INDEX
+testdb=> \d account
+                                Tabelle »public.account«
+ Spalte  |   Typ   | Sortierfolge | NULL erlaubt? |             Vorgabewert
+---------+---------+--------------+---------------+-------------------------------------
+ id      | integer |              | not null      | nextval('account_id_seq'::regclass)
+ number  | text    |              |               |
+ balance | integer |              |               |
+Indexe:
+    "account_pkey" PRIMARY KEY, btree (id)
+    "index_account_number" btree (number)
+Fremdschlüsselverweise von:
+    TABLE "customer" CONSTRAINT "customer_fkey_account_id" FOREIGN KEY (account_id) REFERENCES account(id)
+
+testdb=> SELECT * FROM account where number = 'DE12 3456 7890 ABCD EFGH IJ';
+ id |           number            | balance
+----+-----------------------------+---------
+  1 | DE12 3456 7890 ABCD EFGH IJ | 1000001
+(1 Zeile)
+
+testdb=>
diff --git a/20231130/logo-hochschule-bochum-cvh-text-v2.pdf b/20231130/logo-hochschule-bochum-cvh-text-v2.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8
--- /dev/null
+++ b/20231130/logo-hochschule-bochum-cvh-text-v2.pdf
@@ -0,0 +1 @@
+../common/logo-hochschule-bochum-cvh-text-v2.pdf
\ No newline at end of file
diff --git a/20231130/logo-hochschule-bochum.pdf b/20231130/logo-hochschule-bochum.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1
--- /dev/null
+++ b/20231130/logo-hochschule-bochum.pdf
@@ -0,0 +1 @@
+../common/logo-hochschule-bochum.pdf
\ No newline at end of file
diff --git a/20231130/pgslides.sty b/20231130/pgslides.sty
new file mode 120000
index 0000000000000000000000000000000000000000..5be1416f4216f076aa268901f52a15d775e43f64
--- /dev/null
+++ b/20231130/pgslides.sty
@@ -0,0 +1 @@
+../common/pgslides.sty
\ No newline at end of file
diff --git a/20231130/transactions-01.txt b/20231130/transactions-01.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0271a02accab36fb3afece1884a188daa87b9a7c
--- /dev/null
+++ b/20231130/transactions-01.txt
@@ -0,0 +1,33 @@
+cassini/home/peter/bo/2023ws/dbs/20231130> psql -h localhost -U dbs -W testdb
+Passwort:
+psql (15.5 (Debian 15.5-0+deb12u1))
+SSL-Verbindung (Protokoll: TLSv1.3, Verschlüsselungsmethode: TLS_AES_256_GCM_SHA384, Komprimierung: aus)
+Geben Sie »help« für Hilfe ein.
+
+testdb=> CREATE TABLE IF NOT EXISTS customer VALUES(id PRIMARY KEY AUTO_INCEMENR, lastname TEXT, firstname TEXT, account TEXT);
+FEHLER:  Syntaxfehler bei »VALUES«
+ZEILE 1: CREATE TABLE IF NOT EXISTS customer VALUES(id PRIMARY KEY AU...
+                                             ^
+testdb=> CREATE TABLE IF NOT EXISTS customer VALUES(id AUTO_INCEMENR, lastname TEXT, firstname TEXT, account TEXT);
+FEHLER:  Syntaxfehler bei »VALUES«
+ZEILE 1: CREATE TABLE IF NOT EXISTS customer VALUES(id AUTO_INCEMENR,...
+                                             ^
+testdb=> CREATE TABLE IF NOT EXISTS customer VALUES(id AUTO_INCREMENT, lastname TEXT, firstname TEXT, account TEXT);
+FEHLER:  Syntaxfehler bei »VALUES«
+ZEILE 1: CREATE TABLE IF NOT EXISTS customer VALUES(id AUTO_INCREMENT...
+                                             ^
+testdb=> CREATE TABLE IF NOT EXISTS customer VALUES(id PRIMARY KEY AUTO_INCREMENT, lastname TEXT, firstname TEXT, account TEXT);
+FEHLER:  Syntaxfehler bei »VALUES«
+ZEILE 1: CREATE TABLE IF NOT EXISTS customer VALUES(id PRIMARY KEY AU...
+                                             ^
+testdb=> CREATE TABLE IF NOT EXISTS customer (id PRIMARY KEY AUTO_INCREMENT, lastname TEXT, firstname TEXT, account TEXT);
+FEHLER:  Syntaxfehler bei »PRIMARY«
+ZEILE 1: CREATE TABLE IF NOT EXISTS customer (id PRIMARY KEY AUTO_INC...
+                                                 ^
+testdb=> CREATE TABLE IF NOT EXISTS customer (id INTEGER PRIMARY KEY AUTO_INCREMENT, lastname TEXT, firstname TEXT, account TEXT);
+FEHLER:  Syntaxfehler bei »AUTO_INCREMENT«
+ZEILE 1: ...LE IF NOT EXISTS customer (id INTEGER PRIMARY KEY AUTO_INCRE...
+                                                              ^
+testdb=> CREATE TABLE IF NOT EXISTS customer (id SERIAL PRIMARY KEY, lastname TEXT, firstname TEXT, account TEXT);
+CREATE TABLE
+testdb=>
diff --git a/20231130/transactions-02.txt b/20231130/transactions-02.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1e3c82b9e45f6a72c28c37d9edc4f9615bf63779
--- /dev/null
+++ b/20231130/transactions-02.txt
@@ -0,0 +1,37 @@
+testdb=> ALTER TABLE customer DELETE COLUMN account;
+FEHLER:  Syntaxfehler bei »DELETE«
+ZEILE 1: ALTER TABLE customer DELETE COLUMN account;
+                              ^
+testdb=> ALTER TABLE customer DROP COLUMN account;
+ALTER TABLE
+testdb=> ALTER TABLE customer ADD COLUMN account_id INTEGER;
+ALTER TABLE
+testdb=> \d
+               Liste der Relationen
+ Schema |       Name       |   Typ   | Eigentümer
+--------+------------------+---------+------------
+ public | cd               | Tabelle | dbs
+ public | cd_cd_id_seq     | Sequenz | dbs
+ public | customer         | Tabelle | dbs
+ public | customer_id_seq  | Sequenz | dbs
+ public | interpret        | Tabelle | dbs
+ public | interpret_id_seq | Sequenz | dbs
+ public | lied             | Tabelle | dbs
+ public | lied_auf_cd      | Sicht   | dbs
+ public | test             | Tabelle | dbs
+ public | tier             | Tabelle | dbs
+ public | tier_id_seq      | Sequenz | dbs
+(11 Zeilen)
+
+testdb=> \d customer
+                                 Tabelle »public.customer«
+   Spalte   |   Typ   | Sortierfolge | NULL erlaubt? |             Vorgabewert
+------------+---------+--------------+---------------+--------------------------------------
+ id         | integer |              | not null      | nextval('customer_id_seq'::regclass)
+ lastname   | text    |              |               |
+ firstname  | text    |              |               |
+ account_id | integer |              |               |
+Indexe:
+    "customer_pkey" PRIMARY KEY, btree (id)
+
+testdb=>
diff --git a/20231130/transactions-03.txt b/20231130/transactions-03.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4081b2bf54be65b1cfcd13cd1d754fce35ce5ca7
--- /dev/null
+++ b/20231130/transactions-03.txt
@@ -0,0 +1,28 @@
+testdb=> \d customer
+                                 Tabelle »public.customer«
+   Spalte   |   Typ   | Sortierfolge | NULL erlaubt? |             Vorgabewert
+------------+---------+--------------+---------------+--------------------------------------
+ id         | integer |              | not null      | nextval('customer_id_seq'::regclass)
+ lastname   | text    |              |               |
+ firstname  | text    |              |               |
+ account_id | integer |              |               |
+Indexe:
+    "customer_pkey" PRIMARY KEY, btree (id)
+
+testdb=> \d account
+                                Tabelle »public.account«
+ Spalte  |   Typ   | Sortierfolge | NULL erlaubt? |             Vorgabewert
+---------+---------+--------------+---------------+-------------------------------------
+ id      | integer |              | not null      | nextval('account_id_seq'::regclass)
+ number  | text    |              |               |
+ balance | integer |              |               |
+Indexe:
+    "account_pkey" PRIMARY KEY, btree (id)
+
+testdb=> ALTER TABLE customer ADD CONSTRAINT customer_fkey_account_id FOREIGN KEY accoun
+
+testdb=> ALTER TABLE customer ADD CONSTRAINT customer_fkey_account_id FOREIGN KEY account_id REFER
+
+testdb=> ALTER TABLE customer ADD CONSTRAINT customer_fkey_account_id FOREIGN KEY(account_id) REFERENCES account(id);
+ALTER TABLE
+testdb=>
diff --git a/20231130/transactions-04.txt b/20231130/transactions-04.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f14d3cb16e744b0b51eacce11ceaa3f92ca79792
--- /dev/null
+++ b/20231130/transactions-04.txt
@@ -0,0 +1,35 @@
+testdb=> INSERT INTO customer (lastname, firstname, account_id) VALUES ('Mustermann', 'Erika', 1);
+FEHLER:  Einfügen oder Aktualisieren in Tabelle »customer« verletzt Fremdschlüssel-Constraint »customer_fkey_account_id«
+DETAIL:  Schlüssel (account_id)=(1) ist nicht in Tabelle »account« vorhanden.
+testdb=> SELECT * FROM account;                                                               id | number | balance
+----+--------+---------
+(0 Zeilen)
+
+testdb=> SELECT * FROM customer;
+ id | lastname | firstname | account_id
+----+----------+-----------+------------
+(0 Zeilen)
+
+testdb=> INSERT INTO account (number, balance) VALUES ('DE12 3456 7890 ABCD EFGH IJ', 0);
+INSERT 0 1
+testdb=> SELECT * FROM account;
+ id |           number            | balance
+----+-----------------------------+---------
+  1 | DE12 3456 7890 ABCD EFGH IJ |       0
+(1 Zeile)
+
+testdb=> INSERT INTO customer (lastname, firstname, account_id) VALUES ('Mustermann', 'Erika', 1);
+INSERT 0 1
+testdb=> SELECT * FROM customer;
+ id |  lastname  | firstname | account_id
+----+------------+-----------+------------
+  2 | Mustermann | Erika     |          1
+(1 Zeile)
+
+testdb=> SELECT * FROM account;
+ id |           number            | balance
+----+-----------------------------+---------
+  1 | DE12 3456 7890 ABCD EFGH IJ |       0
+(1 Zeile)
+
+testdb=>
diff --git a/20231130/transactions-05.txt b/20231130/transactions-05.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ce4d61e98c839f8f7fbd29d04a727416ea0534e3
--- /dev/null
+++ b/20231130/transactions-05.txt
@@ -0,0 +1,15 @@
+testdb=> UPDATE customer SET balance = 5000000 WHERE lastname = 'Rich';
+FEHLER:  Spalte »balance« von Relation »customer« existiert nicht
+ZEILE 1: UPDATE customer SET balance = 5000000 WHERE lastname = 'Rich...
+                             ^
+testdb=> UPDATE account SET balance = 5000000 WHERE lastname = 'Rich';
+FEHLER:  Spalte »lastname« existiert nicht
+ZEILE 1: UPDATE account SET balance = 5000000 WHERE lastname = 'Rich'...
+                                                    ^
+testdb=> UPDATE account SET balance = 5000000 WHERE (SELECT account_id FROM customer WHERE lastname = 'Rich');
+FEHLER:  Argument von WHERE muss Typ boolean haben, nicht Typ integer
+ZEILE 1: UPDATE account SET balance = 5000000 WHERE (SELECT account_i...
+                                                    ^
+testdb=> UPDATE account SET balance = 5000000 WHERE id = (SELECT account_id FROM customer WHERE lastname = 'Rich');
+UPDATE 1
+testdb=>
diff --git a/20231130/transactions-06.txt b/20231130/transactions-06.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bd01808a61dc47d4dbb0290ecfcc67ef48a0e926
--- /dev/null
+++ b/20231130/transactions-06.txt
@@ -0,0 +1,19 @@
+testdb=> UPDATE customer SET balance = 5000000 WHERE lastname = 'Rich';
+FEHLER:  Spalte »balance« von Relation »customer« existiert nicht
+ZEILE 1: UPDATE customer SET balance = 5000000 WHERE lastname = 'Rich...
+                             ^
+testdb=> UPDATE account SET balance = 5000000 WHERE lastname = 'Rich';
+FEHLER:  Spalte »lastname« existiert nicht
+ZEILE 1: UPDATE account SET balance = 5000000 WHERE lastname = 'Rich'...
+                                                    ^
+testdb=> UPDATE account SET balance = 5000000 WHERE (SELECT account_id FROM customer WHERE lastname = 'Rich');
+FEHLER:  Argument von WHERE muss Typ boolean haben, nicht Typ integer
+ZEILE 1: UPDATE account SET balance = 5000000 WHERE (SELECT account_i...
+                                                    ^
+testdb=> UPDATE account SET balance = 5000000 WHERE id = (SELECT account_id FROM customer WHERE lastname = 'Rich');
+UPDATE 1
+testdb=> UPDATE account JOIN customer ON customer.account_id = account.id SET account.balance = 5000001 WHERE customer.lastname = 'Rich';
+FEHLER:  Syntaxfehler bei »JOIN«
+ZEILE 1: UPDATE account JOIN customer ON customer.account_id = accoun...
+                        ^
+testdb=>
diff --git a/20231130/transactions-07.txt b/20231130/transactions-07.txt
new file mode 100644
index 0000000000000000000000000000000000000000..954568e9767eacc7512ddc9e0b9fa45eaa038020
--- /dev/null
+++ b/20231130/transactions-07.txt
@@ -0,0 +1,31 @@
+testdb=> SELECT * FROM customer;
+ id |  lastname  | firstname | account_id
+----+------------+-----------+------------
+  2 | Mustermann | Erika     |          1
+  4 | Rich       | Richie    |          2
+(2 Zeilen)
+
+testdb=> SELECT * FROM account;
+ id |           number            | balance
+----+-----------------------------+---------
+  1 | DE12 3456 7890 ABCD EFGH IJ |       0
+  2 | DE98 7654 3210 ABCD EFGH IJ | 5000000
+(2 Zeilen)
+
+testdb=> UPDATE account SET balance = balance + 1000000 WHERE id = (SELECT account_id FROM customer WHERE lastname = 'Mustermann');
+UPDATE 1
+testdb=> UPDATE account SET balance = balance - 1000000 WHERE id = (SELECT account_id FROM customer WHERE lastname = 'Rich');
+UPDATE 1
+testdb=> SELECT * FROM customer;                                                              id |  lastname  | firstname | account_id
+----+------------+-----------+------------
+  2 | Mustermann | Erika     |          1
+  4 | Rich       | Richie    |          2
+(2 Zeilen)
+
+testdb=> SELECT * FROM account;                                                               id |           number            | balance
+----+-----------------------------+---------
+  1 | DE12 3456 7890 ABCD EFGH IJ | 1000000
+  2 | DE98 7654 3210 ABCD EFGH IJ | 4000000
+(2 Zeilen)
+
+testdb=>
diff --git a/20231130/transactions-08.txt b/20231130/transactions-08.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4c5995e636d998eb5b0ba1ad63f960a1b4aa8678
--- /dev/null
+++ b/20231130/transactions-08.txt
@@ -0,0 +1,21 @@
+testdb=> BEGIN;
+BEGIN
+testdb=*> UPDATE account SET balance = balance + 1 WHERE id = (SELECT account_id FROM customer WHERE lastname = 'Mustermann');
+UPDATE 1
+testdb=*> UPDATE account SET balance = balance - 1 WHERE id = (SELECT account_id FROM customer WHERE lastname = 'Rich');
+UPDATE 1
+testdb=*> SELECT * FROM customer;                                                             id |  lastname  | firstname | account_id
+----+------------+-----------+------------
+  2 | Mustermann | Erika     |          1
+  4 | Rich       | Richie    |          2
+(2 Zeilen)
+
+testdb=*> SELECT * FROM account;                                                              id |           number            | balance
+----+-----------------------------+---------
+  1 | DE12 3456 7890 ABCD EFGH IJ | 1000001
+  2 | DE98 7654 3210 ABCD EFGH IJ | 3999999
+(2 Zeilen)
+
+testdb=*> COMMIT;
+COMMIT
+testdb=>
diff --git a/20231130/transactions-09.txt b/20231130/transactions-09.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5f0e8c07534be6488fb9d2ef8d1f43ec4177f2dc
--- /dev/null
+++ b/20231130/transactions-09.txt
@@ -0,0 +1,34 @@
+testdb=> BEGIN;                                                                              BEGIN
+testdb=*> UPDATE account SET balance = balance + 10000000 WHERE id = (SELECT account_id FROM customer WHERE lastname = 'Mustermann');
+UPDATE 1
+testdb=*> UPDATE account SET balance = balance - 10000000 WHERE id = (SELECT account_id FROM customer WHERE lastname = 'Rich');
+UPDATE 1
+testdb=*> SELECT * FROM customer;                                                             id |  lastname  | firstname | account_id
+----+------------+-----------+------------
+  2 | Mustermann | Erika     |          1
+  4 | Rich       | Richie    |          2
+(2 Zeilen)
+
+testdb=*> SELECT * FROM account;                                                              id |           number            | balance
+----+-----------------------------+----------
+  1 | DE12 3456 7890 ABCD EFGH IJ | 11000001
+  2 | DE98 7654 3210 ABCD EFGH IJ | -6000001
+(2 Zeilen)
+
+testdb=*> ROLLBACK;
+ROLLBACK
+testdb=> SELECT * FROM customer;
+ id |  lastname  | firstname | account_id
+----+------------+-----------+------------
+  2 | Mustermann | Erika     |          1
+  4 | Rich       | Richie    |          2
+(2 Zeilen)
+
+testdb=> SELECT * FROM account;
+ id |           number            | balance
+----+-----------------------------+---------
+  1 | DE12 3456 7890 ABCD EFGH IJ | 1000001
+  2 | DE98 7654 3210 ABCD EFGH IJ | 3999999
+(2 Zeilen)
+
+testdb=>