- 1 Section
- 10 Lessons
- unbegrenzt
- Datenintegrität & Transaktionen10
- 1.1Integritätstypen
- 1.2Primary Key, Foreign Key, Constraints
- 1.3Referenzielle Integrität: ON DELETE, ON UPDATE
- 1.4Was sind Transaktionen?
- 1.5ACID-Eigenschaften
- 1.6Transaktions-Isolation und Anomalien
- 1.7COMMIT, ROLLBACK und SAVEPOINT
- 1.8Deadlocks: Entstehung und Vermeidung
- 1.9Datenbankindizes und Performance
- 1.10Aufgaben Datenintegrität
Primary Key, Foreign Key, Constraints
In Lektion 1 haben wir gesehen, dass das DBMS Datenintegrität über sogenannte Constraints durchsetzt – Regeln die im Schema definiert werden und vor jedem Insert/Update geprüft werden. Diese Lektion gräbt tiefer: was sind eigentlich Primary Keys und Foreign Keys genau, welche Arten gibt es, und welche weiteren Constraint-Typen kennt SQL?
Wer Constraints versteht, baut Datenbanken die von selbst sauber bleiben. Wer sie ignoriert, schreibt jede Prüfung 17-mal im Anwendungscode – und vergisst sie an Stelle 18. Diese Lektion ist die Werkzeugkiste.
1) Schlüsselkandidat, Primärschlüssel, Alternativschlüssel
Bevor wir über den Primärschlüssel reden, ein Schritt zurück: in einer Tabelle kann es mehrere Spalten oder Spaltenkombinationen geben, die theoretisch geeignet wären eine Zeile eindeutig zu identifizieren. Solche heißen Schlüsselkandidaten (engl. Candidate Keys). Aus dieser Menge wird genau einer zum Primärschlüssel ernannt – alle anderen heißen Alternativschlüssel (Secondary Keys).
Beispiel: in einer Mitarbeitertabelle könnten personalnummer, email und die Kombination (steuer_id) jeweils einzeln eindeutig sein. Alle drei sind Schlüsselkandidaten. Du wählst einen davon zum Primärschlüssel – meist nach Pragmatik (kurz, stabil, technisch).
| personal_nr | vorname | nachname | geburtsdatum | |
|---|---|---|---|---|
| 1001 | a.bauer@firma.de | Anna | Bauer | 1990-03-12 |
| 1002 | t.schulz@firma.de | Tim | Schulz | 1985-07-04 |
| 1003 | l.wagner@firma.de | Lisa | Wagner | 1992-11-21 |
| 1004 | t.schulz2@firma.de | Tim | Schulz | 1988-02-15 |
Klick eine Spalte und prüfe ob sie ein Schlüsselkandidat ist:
2) Natürlicher vs. künstlicher Primärschlüssel
Es gibt zwei philosophische Lager beim Wählen eines Primärschlüssels. Der natürliche Schlüssel (Natural Key) nutzt eine Spalte die fachlich ohnehin eindeutig ist (ISBN, Personalnummer, IBAN). Der künstliche Schlüssel (Surrogate Key oder Synthetic Key) ist eine vom System vergebene Nummer – meist id BIGINT AUTO_INCREMENT – ohne fachliche Bedeutung. Beide haben Vor- und Nachteile:
UNIQUE-Constraint zu definieren, ist Pflicht – sonst geht die Eindeutigkeitsgarantie verloren.3) Zusammengesetzte Primärschlüssel
Manchmal reicht eine Spalte nicht zur eindeutigen Identifikation – aber die Kombination mehrerer schon. Das heißt dann zusammengesetzter Schlüssel (Composite Key oder Compound Key). Klassisches Beispiel: eine Tabelle „Bestellpositionen" – jede Bestellung kann mehrere Positionen haben, aber pro Bestellung ist eine Positionsnummer eindeutig. Erst das Paar (bestell_id, position) identifiziert eine Zeile.
Welche Spalten gehören zum Primärschlüssel? Klick die Kombinationen durch:
| bestell_id 🔑 | position 🔑 | artikel | menge |
|---|---|---|---|
| 1001 | 1 | Tastatur | 1 |
| 1001 | 2 | Maus | 2 |
| 1002 | 1 | Monitor | 1 |
| 1002 | 2 | HDMI-Kabel | 3 |
PRIMARY KEY (bestell_id, position). Wichtig: ein zusammengesetzter Schlüssel ist als Einheit eindeutig – die einzelnen Spalten dürfen sehr wohl Duplikate haben (bestell_id 1001 kommt zweimal vor – kein Problem, solange die zugehörige position unterschiedlich ist). In modernen Systemen wird oft trotzdem ein zusätzlicher Surrogate Key spendiert (id), und die fachliche Eindeutigkeit per UNIQUE (bestell_id, position) abgesichert.4) Foreign Keys: die Brücke zwischen Tabellen
Der Fremdschlüssel ist die Spalte (oder Spaltenkombination) in einer Tabelle, deren Werte den Primärschlüssel einer anderen Tabelle referenzieren. Damit modellierst du Beziehungen zwischen Entitäten: „diese Bestellung gehört zu jenem Kunden", „dieser Kommentar zu jenem Beitrag". Die Kardinalität (1:N, M:N) bestimmt wo der FK steht.
Syntaktisch sieht das in SQL so aus:
id BIGINT AUTO_INCREMENT PRIMARY KEY,
kunden_id BIGINT NOT NULL,
summe DECIMAL(10,2),
FOREIGN KEY (kunden_id) REFERENCES kunden(id)
);
Die FOREIGN KEY-Klausel sagt: „die Spalte kunden_id referenziert die Spalte id in der Tabelle kunden." Ab dem Moment garantiert das DBMS, dass jeder Wert in kunden_id als id in der Kundentabelle existiert (oder NULL ist, falls nicht NOT NULL). Was beim Löschen oder Ändern der referenzierten Zeile passiert, regeln die Klauseln ON DELETE und ON UPDATE – das ist Thema von Lektion 3.
5) Die wichtigsten Constraints im Überblick
Constraints sind die Werkzeuge mit denen du im Schema festlegst was erlaubt ist. Hier die sechs Typen die du sicher kennen solltest – jeder mit einer Mini-Anwendung:
email VARCHAR(120) NOT NULL UNIQUE CHECK (email LIKE '%@%'). Reihenfolge spielt syntaktisch keine Rolle – das DBMS prüft beim Insert alle. Constraints können beim CREATE TABLE direkt mitgegeben werden (inline) oder nachträglich mit ALTER TABLE … ADD CONSTRAINT ergänzt werden.6) Constraint-Builder – baue deine eigene Tabelle
Wähle die Constraints die du auf deine Spalten anwenden willst und sieh wie sich das SQL-Statement ändert:
CREATE TABLE-Block in Echtzeit verändert. Die Combo NOT NULL UNIQUE auf einer Mail-Spalte ist Standard für Login-Systeme. CHECK mit Domänenbedingungen ist die Stelle wo viele Bugs verhindert werden bevor sie entstehen. DEFAULT ohne NOT NULL ist seltsam – wenn ein Standard existiert, sollte die Spalte sowieso nicht leer sein.7) Constraints nachträglich hinzufügen oder entfernen
In der Praxis arbeitest du selten mit einer leeren Datenbank. Oft musst du Constraints zu existierenden Tabellen nachrüsten. Dafür gibt es ALTER TABLE:
ALTER TABLE users ADD CONSTRAINT uq_email UNIQUE (email);
-- Fremdschlüssel auf eine existierende Spalte legen
ALTER TABLE bestellungen
ADD CONSTRAINT fk_kunde FOREIGN KEY (kunden_id) REFERENCES kunden(id);
-- CHECK-Constraint hinzufügen
ALTER TABLE produkte ADD CONSTRAINT ck_preis CHECK (preis > 0);
-- Constraint wieder entfernen
ALTER TABLE users DROP CONSTRAINT uq_email;
Zwei Stolperfallen: Erstens, wenn du einen Constraint auf bestehende Daten anwendest und die Daten schon die Regel verletzen, schlägt das ALTER TABLE fehl. Du musst die Daten erst aufräumen. Zweitens: Constraints zu benennen (CONSTRAINT uq_email) ist optional, aber stark empfohlen. Sonst bekommst du in Fehlermeldungen kryptische auto-generierte Namen wie users_email_key_1.
8) Wann gehört Validierung in die DB, wann in die App?
Eine wiederkehrende Diskussion: was prüft die Datenbank, was prüft der Anwendungscode? Beide haben ihre Berechtigung – und die saubere Lösung ist defense in depth: kritische Constraints stehen in der DB, freundliche UX-Validierung in der App.
- In die DB gehört: alles was die Datenintegrität strukturell sichert – Primary Keys, Foreign Keys, NOT NULL auf Pflichtspalten, harte CHECK-Regeln (preis > 0). Diese Regeln sollen niemals verletzt werden, egal welcher Client schreibt.
- In die App gehört: alles was eine bessere Nutzererfahrung erlaubt – sofortiges Feedback beim Tippen, kontextabhängige Regeln (z.B. „Versanddatum ≥ Bestelldatum"), komplexe Validierungen die mehrere Systeme involvieren.
- Idealerweise in beidem: wichtige fachliche Regeln. Die App liefert schnelles Feedback, die DB ist das letzte Sicherheitsnetz – falls die App umgangen wird (Migrations-Skript, direkter SQL-Zugriff, fehlerhafter zweiter Client).
Sicherheitsrelevant ist außerdem die Trennung: Konstrukte wie SQL-Injection würden die App-seitige Validierung umgehen können – das DBMS aber lässt sich nicht überreden seine Constraints zu ignorieren (siehe SQL-Injection in K11). Eine fundamentale Schicht in der Verteidigung.
Zusammenfassung
Ein Schlüsselkandidat ist jede Spalte/Kombination die eine Zeile eindeutig identifizieren kann. Daraus wird einer zum Primärschlüssel ernannt, die anderen sind Alternativschlüssel. Es gibt natürliche (fachlich eindeutige Werte wie ISBN) und künstliche/Surrogate Schlüssel (auto-generierte IDs) – in der modernen Praxis dominiert der Surrogate Key, oft kombiniert mit einem UNIQUE-Constraint auf dem natürlichen Wert. Zusammengesetzte Schlüssel bestehen aus mehreren Spalten gemeinsam (PRIMARY KEY (bestell_id, position)). Fremdschlüssel verweisen auf den PK einer anderen Tabelle und sichern die referenzielle Integrität. Die wichtigsten Constraints: PRIMARY KEY, FOREIGN KEY, UNIQUE, NOT NULL, CHECK, DEFAULT – kombinierbar pro Spalte, definierbar bei CREATE TABLE oder nachträglich per ALTER TABLE. Faustregel: harte Integritätsregeln gehören ins DB-Schema, UX-Feedback in die Anwendung – im Idealfall beides parallel.
