Foreign Key

Ein Foreign Key (Fremdschlüssel) ist eine Spalte in einer SQL Tabelle, die auf den Primary Key einer anderen Tabelle verweist.

Foreign Keys stellen Beziehungen zwischen Tabellen her und sichern die Datenintegrität.

Foreign Key Beziehung:

Parent-Tabelle: Schueler
┌────────────┬──────────┐
│ schueler_id│ name     │ ← Primary Key
├────────────┼──────────┤
│     1      │ Max      │
│     2      │ Anna     │
│     3      │ Tom      │
└────────────┴──────────┘
       │
       │ wird referenziert von
       ▼
Child-Tabelle: Noten
┌─────────┬────────────┬──────┐
│ note_id │ schueler_id│ note │  ← Foreign Key
├─────────┼────────────┼──────┤     zeigt auf
│   101   │     1      │ 2.0  │     schueler_id
│   102   │     1      │ 1.5  │     (Parent)
│   103   │     2      │ 2.5  │
└─────────┴────────────┴──────┘

Referentielle Integrität:

✓ ERLAUBT:
schueler_id = 1 (existiert in Parent)
┌─────────┬────────────┬──────┐
│ note_id │ schueler_id│ note │
├─────────┼────────────┼──────┤
│   101   │     1      │ 2.0  │ ← OK!
└─────────┴────────────┴──────┘

✗ VERBOTEN:
schueler_id = 999 (existiert NICHT in Parent)
┌─────────┬────────────┬──────┐
│ note_id │ schueler_id│ note │
├─────────┼────────────┼──────┤
│   101   │    999     │ 2.0  │ ← FEHLER!
└─────────┴────────────┴──────┘

n:m Beziehung mit Zwischentabelle:

Schueler              Kurse
┌────┬──────┐        ┌────┬──────┐
│ id │ name │        │ id │ name │
├────┼──────┤        ├────┼──────┤
│ 1  │ Max  │        │ 1  │ Math │
│ 2  │ Anna │        │ 2  │ Bio  │
└────┴──────┘        └────┴──────┘
      │                    │
      └──────┬─────────────┘
             │
    ┌────────▼───────┐
    │ Einschreibung  │ ← 2 Foreign Keys!
    ├────────┬───────┤
    │stud_id │kurs_id│
    ├────────┼───────┤
    │   1    │   1   │
    │   1    │   2   │
    │   2    │   1   │
    └────────┴───────┘
       FK1     FK2

Syntax

Einfacher Foreign Key

CREATE TABLE Noten (
   note_id INT PRIMARY KEY,
   schueler_id INT,
   note DECIMAL(2,1),
   FOREIGN KEY (schueler_id)          -- ← Foreign Key
       REFERENCES Schueler(schueler_id)  -- zeigt auf Parent
);

Mehrere Foreign Keys

CREATE TABLE Einschreibung (
   einschreibung_id INT PRIMARY KEY,
   schueler_id INT,                   -- FK zu Schueler
   kurs_id INT,                       -- FK zu Kurse
   einschreibedatum DATE,
   FOREIGN KEY (schueler_id) REFERENCES Schueler(schueler_id),
   FOREIGN KEY (kurs_id) REFERENCES Kurse(kurs_id)
);

Mit Aktion bei Löschung/Änderung

CREATE TABLE Noten (
   note_id INT PRIMARY KEY,
   schueler_id INT,
   note DECIMAL(2,1),
   FOREIGN KEY (schueler_id)
       REFERENCES Schueler(schueler_id)
       ON DELETE CASCADE                -- ← Lösche auch Child
       ON UPDATE CASCADE                -- ← Update auch Child
);

Referentielle Aktionen

ON DELETE / ON UPDATE Optionen:

┌────────────┬──────────────────────────────────┐
│ Option     │ Bedeutung                        │
├────────────┼──────────────────────────────────┤
│ CASCADE    │ Lösche/Ändere auch Child-Zeilen  │
│ SET NULL   │ Setze FK auf NULL                │
│ SET DEFAULT│ Setze FK auf Default-Wert        │
│ RESTRICT   │ Verhindere Löschung/Änderung     │
│ NO ACTION  │ Wie RESTRICT (Standard)          │
└────────────┴──────────────────────────────────┘

Beispiel CASCADE:

Parent: Schueler         Child: Noten
┌────┬──────┐           ┌─────┬────────────┬──────┐
│ id │ name │           │  id │ schueler_id│ note │
├────┼──────┤           ├─────┼────────────┼──────┤
│ 1  │ Max  │ ───────> │ 101 │     1      │ 2.0  │
└────┴──────┘           │ 102 │     1      │ 1.5  │
                        └─────┴────────────┴──────┘

DELETE FROM Schueler WHERE id = 1;
                  │
                  ▼ CASCADE
         ┌─────────────────┐
         │ Auch Noten      │
         │ werden gelöscht!│
         └─────────────────┘
Prüfungsrelevant

Was ist ein Foreign Key?

  • Spalte, die auf Primary Key einer anderen Tabelle zeigt
  • Stellt Beziehung zwischen Tabellen her
  • Sichert Datenintegrität (referentielle Integrität)

Eigenschaften:

  • Wert muss in Parent-Tabelle existieren ODER NULL sein
  • Kann mehrfach vorkommen (im Gegensatz zu PK)
  • Kann NULL sein (außer wenn NOT NULL definiert)

Zweck:

  • Verknüpfung von Tabellen
  • Verhindert "verwaiste" Datensätze
  • Erzwingt Konsistenz
Häufige Fehler

  1. FK auf nicht existierenden PK
INSERT INTO Noten (schueler_id, note)
VALUES (999, 2.0);  -- ❌ Schueler 999 existiert nicht!
  1. Parent löschen ohne CASCADE
DELETE FROM Schueler WHERE id = 1;
-- ❌ Fehler: Noten referenzieren noch diesen Schüler!
  1. Falsche Reihenfolge beim Löschen
-- ✗ FALSCH:
DELETE FROM Schueler WHERE id = 1;  -- Fehler!
DELETE FROM Noten WHERE schueler_id = 1;

-- ✓ RICHTIG:
DELETE FROM Noten WHERE schueler_id = 1;  -- Erst Child
DELETE FROM Schueler WHERE id = 1;         -- Dann Parent

Best Practices

  1. Immer Foreign Keys definieren
  • Auch wenn DB es nicht erzwingt
  • Dokumentiert Beziehungen
  • Verhindert Fehler
  1. Naming Convention
-- Wenn Parent-Tabelle "Schueler" heißt:
schueler_id   -- ✓ Erkennbar
fk_schueler   -- ✓ Alternative
id            -- ✗ Zu allgemein
  1. CASCADE mit Bedacht
  • ON DELETE CASCADE: Nur wenn wirklich gewollt
  • Oft besser: RESTRICT (verhindert Löschung)
  1. Indizes auf FK
CREATE INDEX idx_schueler_id ON Noten(schueler_id);

→ Macht JOINs schneller!

Foreign Key vs Primary Key

┌──────────────┬───────────────┬──────────────┐
│ Eigenschaft  │ Primary Key   │ Foreign Key  │
├──────────────┼───────────────┼──────────────┤
│ Eindeutig    │ Ja (UNIQUE)   │ Nein         │
│ NULL erlaubt │ Nein          │ Ja*          │
│ Pro Tabelle  │ Nur 1         │ Mehrere      │
│ Verweist auf │ Sich selbst   │ Andere Tabell│
└──────────────┴───────────────┴──────────────┘
* Außer NOT NULL definiert

Siehe auch