Informationssysteme und Datenbanken: relationales Modell, Normalformen, SQL
Der Bereich Informationssysteme und Datenbanken prüft den Weg von der Anforderung zum normalisierten relationalen Schema und zur korrekten Abfrage. Erwartet werden ER-Modellierung, die Überführung in Tabellen, die Prüfung funktionaler Abhängigkeiten und Normalformen sowie sicheres Formulieren von SELECT-Anweisungen mit Verbunden, Gruppierung und Unterabfragen.
Vom ER-Modell zum Schema
- Entitätstyp wird Tabelle, Attribut wird Spalte, 1:n-Beziehung wird Fremdschlüssel auf der n-Seite.
- m:n-Beziehungen brauchen eine eigene Zwischentabelle, deren Primärschlüssel aus beiden Fremdschlüsseln zusammengesetzt ist.
- Primärschlüssel: eindeutig, minimal, niemals NULL; Fremdschlüssel verweisen auf einen Primärschlüssel und sichern referentielle Integrität.
Normalformen
- 1NF: alle Attributwerte atomar, keine Listen oder Wiederholungsgruppen.
- 2NF: 1NF und jedes Nichtschlüsselattribut hängt voll vom gesamten (zusammengesetzten) Schlüssel ab.
- 3NF: 2NF und keine transitiven Abhängigkeiten, also kein Nichtschlüsselattribut, das von einem anderen Nichtschlüsselattribut abhängt.
- Ziel ist die Vermeidung von Redundanz und damit von Einfüge-, Änderungs- und Löschanomalien.
SQL-Grundgerüst
- Reihenfolge: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY.
- WHERE filtert Zeilen vor der Gruppierung, HAVING filtert fertige Gruppen danach.
- INNER JOIN liefert nur Paare mit Treffer, LEFT JOIN behält alle Zeilen der linken Tabelle und füllt fehlende Werte mit NULL.
- COUNT(*) zählt Zeilen, COUNT(spalte) ignoriert NULL-Werte; Unterabfragen mit IN, EXISTS oder als Skalarvergleich.
Durchgerechnetes Beispiel
Gegeben sind schueler(id, name) und leihgabe(id, schueler_id, titel). Gesucht sind die Namen der Schülerinnen und Schüler mit mehr als zwei Ausleihen:
SELECT s.name FROM schueler s JOIN leihgabe l ON l.schueler_id = s.id GROUP BY s.id, s.name HAVING COUNT(*) > 2;
Begründung: Der JOIN führt Ausleihen mit ihren Schülern zusammen, GROUP BY bildet eine Gruppe pro Person, COUNT(*) zählt die Zeilen dieser Gruppe. Die Bedingung „mehr als zwei“ betrifft das Aggregat und muss deshalb in HAVING stehen; WHERE würde vor der Gruppierung ausgewertet und könnte COUNT nicht prüfen. Die Gruppierung über id und name ist portabel, weil name funktional von id abhängt, aber nicht in jeder SQL-Implementierung automatisch mitgruppiert wird.
Typische Punktverluste
- Aggregatbedingung in WHERE statt in HAVING.
- NULL-Vergleich mit = statt IS NULL; NULL zählt in Aggregaten nicht mit.
- m:n-Beziehung ohne Zwischentabelle oder Fremdschlüssel auf der falschen Seite.
- 2NF-Verstoß nur bei zusammengesetztem Schlüssel möglich, wird aber oft fälschlich bei einfachem Schlüssel gesucht.