Zum Inhalt
wannacode

Primärschlüssel und Fremdschlüssel

Kurz gesagt: Ein Primärschlüssel ist die Spalte, die jede Zeile einer Tabelle eindeutig bestimmt, und ein Fremdschlüssel ist eine Spalte, die den Primärschlüssel einer Zeile in einer anderen Tabelle enthält.

Problem

Wessen Bestellung ist das?

In der Lektion „Der Shop“ haben wir mit den Augen gesucht, wer Bestellung 60 aufgegeben hat und was darin war. Die Antwort war auf vier Tabellen verteilt: orders, customers, order_items und products.

Warum hält der Shop nicht alles in einer großen Tabelle? Und woher „weiß“ eine Tabelle, welche Zeile in einer anderen Tabelle zu ihr gehört?

Die Idee

Primärschlüssel

Fast jede Tabelle im Shop hat eine Spalte id. Die Ausnahme, order_items, steht in der Notiz am Ende der Lektion. Die Zahl ist für jede Zeile anders, wiederholt sich nie und ist nie leer. Anhand der Zahl lässt sich eine Zeile ohne jeden Zweifel finden:

SQLDatenbank: Shop

Eine solche Spalte heißt Primärschlüssel. Namen reichen nicht: Zwei Kunden können denselben Namen haben, und ein Name kann sich ändern. Die Zahl bleibt.

SQLite sagt dir, welche Spalte der Primärschlüssel ist. Die Spalte pk ist für sie 1:

SQLDatenbank: Shop

Die Idee

Fremdschlüssel

Eine Bestellung speichert nicht den Namen des Kunden. Sie behält nur seine id, in der Spalte customer_id:

customers

  • PKidinteger
  • nametext *
  • emailtext *
  • citytext
  • joined_attext *

orders

  • PKidinteger
  • FKcustomer_idinteger *→ customers
  • ordered_attext *
  • statustext *

orders.customer_id verweist auf customers.id. Eine Spalte, die den Primärschlüssel einer Zeile in einer anderen Tabelle enthält, heißt Fremdschlüssel.

Die Verweise einer Tabelle zeigt pragma_foreign_key_list:

SQLDatenbank: Shop

Eine Zeile, ein Verweis: von der Spalte customer_id (from) zur Spalte id (to) der Tabelle customers.

Marias Angaben (Name, E-Mail) sind also einmal gespeichert. Wenn sie ihre E-Mail ändert, wird sie in einer Zeile von customers korrigiert, und ihre 12 Bestellungen verweisen weiter auf dieselbe id.

Probier es aus

Die Bestellpositionen

Auf welche Tabellen verweist order_items? Zeige seine Verweise.

SQLDatenbank: Shop

Sieh es dir an

Nachschlagen nach Nummer

Mit WHERE suchen wir nicht mehr mit den Augen. Wer hat Bestellung 60 aufgegeben? Zuerst die Bestellung:

SQLDatenbank: Shop

customer_id ist 1. Dann der Kunde mit dieser id:

SQLDatenbank: Shop

Maria Ivanova. Es funktioniert, aber es braucht zwei Abfragen, und du trägst die Zahl 1 von Hand hinüber. Für eine Bestellung ist das erträglich. Für einen Bericht über 60 Bestellungen mit den Namen ihrer Kunden nicht. Die nächste Lektion fasst die beiden Schritte mit JOIN in einer Abfrage zusammen.

Probier es aus

Wessen Bewertung ist das?

Bewertung 13 hat die Note 1. Wer hat sie geschrieben? Zeige nur den Namen des Kunden.

SQLDatenbank: Shop

Übung

Zwei Aufgaben

1. Eine Bewertung verweist auf zwei Dinge. Zeige die Verweise der Tabelle reviews.

Die Verweise von reviews:

SQLDatenbank: Shop

2. Die Kategorien bilden einen Baum: „Küche“ ist eine Unterkategorie von etwas. Der Fremdschlüssel parent_id verweist auf eine Zeile in derselben Tabelle categories. Finde den Namen der Elternkategorie von „Küche“.

Die Elternkategorie von „Küche“:

SQLDatenbank: Shop
Genauer, für Neugierige

Ein Primärschlüssel kann aus mehreren Spalten bestehen. In order_items ist es das Paar (order_id, product_id): pk ist für seine Teile 1 und 2.

SQLDatenbank: Shop

Ein Fremdschlüssel ist auch eine Regel: Die Datenbank lehnt eine Bestellung für einen Kunden ab, den es nicht gibt. In SQLite ist diese Regel standardmäßig aus und wird mit PRAGMA foreign_keys = ON eingeschaltet. Hier im Kurs ist sie an. In PostgreSQL werden Fremdschlüssel immer erzwungen. Im Modul über das Ändern von Daten siehst du sie bei der Arbeit.

Test

Teste dich

1. Was stimmt für den Primärschlüssel von customers?
2. orders.customer_id ist 4. Was bedeutet das?
3. Warum steht der Name des Kunden nicht in jeder seiner Bestellungen?
4. Der Primärschlüssel von order_items ist (order_id, product_id). Was verbietet das?

Erstellt von Ivo Gergov im Rahmen der Kampagne von Evo Tech für zugängliche Programmierausbildung ·