0 Inhaltsverzeichnis

  1. Grundlagen
  • OLTP/OLAP
  • ACID
  • DB/DBMS/DBS
  • DDL/DML/DCL
  1. ER-Modelle
  • Kochrezept ER-Diagramme
  1. Relationenmodell
  • ERD -> Relationenschema
  • Generalisierung Methoden
  • Join (outer/semi/…)
  • Division
  • Anfrageoptimierung
  • Funktionale Abhängigkeit
  • Superschlüssel, Schlüsselkandidat
  • 1NF, 2NF, 3NF Überführung
  1. SQL
  • Datentypen
  • CREATE , ALTER, DROP TABLE
  • INSERT, UPDATE, DELETE, SELECT
  • UNION, INTERSECT, EXCEPT, CASE WHEN
  1. Mehrnutzerbetrieb
  • Views
  • Users, Roles, Permissions
  • Mehrbenutzeranomalien
  • SX-Matrix
  • Isolation levels
  • Journaling
  1. Anwendungsentwicklung
  • JDBC Connection, (Prepared)Statement, ResultSet, Metadata
  • PL/pgSQL Procedures, Functions, Trigger
  • Clustered Index, B-Baum, B+-Baum
  • Join-Algorithmen

1 Grundlagen

OLTPOLAP
OnLine Transaction ProcessingOnLine Analytical Processing
Viele schnelle AnfragenKomplexe Anfragen
DatabaseData Warehouse
  • Atomicity (Alles oder nichts)
  • Consistency (Nur erlaubte Zustände)
  • Isolation (Kein gleichzeitiger Zugriff)
  • Durability (Systemcrash-Schutz)
DBDBMSDBS
DatenbankDatenbank-ManagementsystemDatenbanksystem
DatenPostgreSQLDB + DBMS
DDLDMLDCL
Data Definition LanguageData Manipulation LanguageData Control Language
Metadaten/DatenbankschemaCRUDBenutzerverwaltung

2 ER-Modelle

  • Sind alle Kardinalitäten an Beziehungen?
  • Kardinalitäten richtig herum?
  • Gibt es überflüssige Entitätstypen?
  • Hat jeder Entitätstyp einen Primärschlüssel?
  • Müssen manche Entitätstypen schwach sein?
  • Ist die entsprechende Beziehung doppelt umrahmt?
  • Sind erweiternde Primärschlüssel unterstrichelt?
  • Sind Generalisierungen korrekt modelliert?

3 Relationenmodelle

ERDRelationenschema
EntitätTabelle
AttributSpalte
SubattributEinzelne Spalten
Mehrwertiges Attribut1:N Beziehung
BeziehungenFremdschlüssel
Schwache EntitätZusammengesetzter PK
Ternäre Beziehungwie N:M Beziehungen
Generalisierungsiehe unten
GeneralisierungsmethodeErklärung
Volle RedundanzJede Entität wird zu einer Tabelle mit allen Spalten, führt zu Redundanz
HausklassenmodellWie volle Redundanz, aber es wird nur in eine Tabelle eingefügt
Vertikale PartitionierungBei Subentitäten nur spezielle Spalten übernehmen
HierarchierelationNur eine Tabelle mit allen Spalten, + type tag

Joins

TypErklärung
Equi-JoinNur
Theta-Join
Natural JoinEqui-Join mit gleich heißenden Attributen
Semi-JoinR⋉S bzw. R⋊S: bzw.

Division

Heuristiken

  • Selektion, Projektion früh und zusammengefasst
  • Kleine Zwischenergebnisse
  • Selektion statt Mengenoperation

Kardinalitätsschätzung

  • bzw.

Abhängigkeit

falls und

Schlüssel

  • Superschlüssel:
  • Schlüsselkandidat:

Normalformen

NFEigenschaftenÜberführung
1NFAttribute sind atomarAttribute flachklopfen
2NFnicht-Schlüsselattribute hängen voll vom ganzen Schlüssel abZerlegung in Tabellen
3NFkeine transitive Abhängigkeiten wird zu und

4 SQL

  • DOUBLE/REAL: Fließkommazahl
  • DATE: Jahr-Monat-Tag
  • DECIMAL(p, s): p Stellen, davon s Nachkommastellen
FOREIGN KEY (a, b) REFERENCES table(c, d) ON {DELETE|UPDATE} {RESTRICT|NO ACTION|SET NULL|SET DEFAULT|CASCADE}
CREATE TABLE kunden (
	kundennummer SERIAL PRIMARY KEY,
	name VARCHAR(100) NOT NULL,
	email VARCHAR(500) CHECK (email LIKE '%@%') UNIQUE,
	passwort CHAR(32),
	land VARCHAR(100) DEFAULT 'Deutschland',
	geworben_von INT REFERENCES kunden(kundennummer)
		ON DELETE SET NULL ON UPDATE CASCADE
);
CREATE TABLE privatkunden (LIKE kunden); -- Übernimmt Attribute
CREATE TABLE privatkunden2 AS SELECT * FROM kunden -- Übernimmt Zeilen
ALTER TABLE kunden {ADD|DROP|RENAME} COLUMN my_col [INT|...];
INSERT INTO kunden(kundennummer, name) VALUES (default, 'jeff');
UPDATE kunden SET name='jeff' WHERE kundennummer=3;
DELETE FROM kunden WHERE ...;
TRUNCATE TABLE kunden;
SELECT DISTINCT H.land, COUNT(*) AS anzahl, AVG(P.preis) AS avg_preis
FROM hersteller H JOIN produkte P ON H.firma = P.hersteller
WHERE P.preis > 3
GROUP BY h.land
HAVING COUNT(*) < 5
ORDER BY COUNT(*);
WITH ... AS (SELECT ...) SELECT ...;
SELECT ... UNION/INTERSECT/EXCEPT [ALL] SELECT ...;
SELECT CASE preis WHEN 0 THEN 'kostenlos' ELSE preis END FROM ...;

5 Mehrbenutzerbetrieb

CREATE [MATERIALIZED] VIEW my_view AS SELECT ... [WITH CHECK OPTION];
REFRESH MATERIALIZED VIEW my_mat_view;
CREATE USER noah WITH PASSWORD 'abc';
CREATE ROLE cool;
GRANT cool TO noah;
GRANT {PERM} ON {ALL TABLES|...} [IN SCHEMA my_schema] TO {USER} [WITH GRANT OPTION];
REVOKE {PERM} FROM {USER} [RESTRICT|CASCADE];
  • Dirty Read: Unterschiedliche Werte
  • Lost Update: Parallele Änderung, 1 geht verloren
  • Non-repeatable Read: Untersch. SELECT-Erg. in einer TA
  • Phantomproblem: Anzahl Zeilen inkonsistent
SX
S-
X--
Isolation levelLost UpdateDirty ReadNonrepeatable readPhantom readSerialization Anomaly
Read uncommitted
Read committed
Repeatable read✅ (❎PG)
Serializable
LSNTAPageIDUndoRedoPrevLSN
Log-Sequenz-NrTransaktionPage auf FestplatteVerliererGewinnerGleiche TA, vorherige Aktion

6 Anwendungsentwicklung

JDBC

// Summary:
"jdbc://postgresql://host/db?currentSchema=schema";
DriverManager.getConnection(url, user, pass);
conn.prepareStatement("...").setString(1, "...");
st.executeQuery().next().getString(1);
rs.getMetaData().getColumnCount();
String url = "jdbc://postgresql://host/db?currentSchema=schema"
Connection conn = DriverManager.getConnection(url, "user", "password");
conn.close();
Statement st = conn.createStatement();
PreparedStatement pst = conn.prepareStatement("SELECT * FROM t WHERE id = ?");
pst.setString(1, "id");
ResultSet rs = st.executeQuery();
 
while (rs.next()) {
	String col1 = rs.getString(1);
	int my_col = rs.getInt("my_col");
}
DatabaseMetaData data = conn.getMetaData();
ResultSet rs = data.getTables("catalog", "schema", "table");
ResultSetMetaData data = rs.getMetaData();
data.getColumnCount();
data.getColumnName(0);
data.getColumnTypeName(0);

PL/pgSQL

IF ... THEN ... ELSE ... END IF;
WHILE ... LOOP ... END LOOP;
LOOP ... EXIT WHEN ...; END LOOP;
FOR ... IN ... LOOP ... END LOOP;
CREATE OR REPLACE {FUNCTION|PROCEDURE} my_fun(INT) RETURNS INT AS
$$ DECLARE
-- variables
BEGIN
-- code
RETURN $1;
END $$ LANGUAGE plpgsql;

B-Baum

  • Zwischen 0 und 2k+1 Kindknoten
  • Zwischen k und 2k Einträge pro Knoten

B+-Baum

  • Zwischen k* und 2k* Einträge pro Blatt
  • Suche: links, rechts
  • Einfügen: (1) Suchen (2) mittleren Knoten kopieren (3) linke und rechte Knoten splitten (4) bei Vater verschieben
  • Löschen: (1) Suchen (2a) Aus Nachbarblatt ausgleichen und Wegweiser anpassen (2b) Mit Nachbarblatt mischen und Wegweiser entfernen
CREATE INDEX my_table_pkey ON my_table(pkey_col);
CREATE INDEX ON meine_tabelle(a, b, c);
VACUUM my_table;

Join-Algorithmen

Nested-Loop-Join

for each row r in R:
	for each row s in S:
		if r.sId == s.id:
			emit(r, s)

Sort-Merge-Join

  • Nach Join-spalte sortieren
  • Von oben nach unten Join-Partner suchen

Hash-Join

hash_table = []

for each row r in R:
	hash_table.put(hash(r.sId)), r)

for each row s in S:
	r = hash_table.get(hash(s.id))
	emit(r, s)

Index-Join

for each row r in R:
	s = s_id_index.get(r.sId) # e.g. using B+-Tree search
	emit(r, s)