Fremdschlüssel

Um in SQL einen Fremdschlüssel zu erstellen, musst man zunächst zwei Tabellen haben, die miteinander verknüpft werden sollen. Eine Tabelle wird als „Haupttabelle“ und die andere als „Fremdtabelle“ bezeichnet. Die Haupttabelle enthält den Primärschlüssel, die als Fremdschlüssel in der Fremdtabelle verwendet wird.

In dem folgenden ERM existieren zwei Entitäten - Kunde und Rechnung - die über eine 1:N-Beziehung miteinander verbunden sind.

Fremdschlüssel ERM

Aufgelöst wird das ERM, indem der Primärschlüssel als Fremdschlüssel bei Rechnungen als Fremdschlüssel hinzugefügt wird (1:N-Regel).

Fremdschlüssel Tabelle aufgelöst

Der folgrnde SQL-Befehl erstellt diese Tabellen:

MYSQL
CREATE TABLE kunde (
	k_id integer primary key auto_increment,
	k_name varchar(20)
);

CREATE TABLE rechnungen (
	r_id integer primary key auto_increment,
	r_nummer integer,
	k_id integer,
	FOREIGN KEY (k_id) REFERENCES kunde (k_id) 
);
SQLite
CREATE TABLE kunde (
	k_id integer primary key autoincrement,
	k_name text
);

CREATE TABLE rechnungen (
	r_id integer primary key autoincrement,
	r_nummer integer,
	k_id integer,
	FOREIGN KEY (k_id) REFERENCES kunde (k_id) 
);

Dieser SQL-Befehl erstellt zwei Tabellen mit dem Namen kunde und rechnungen. Die Tabelle rechnungen erhält den Primärschlüssel als Fremdschlüssel.

Mit FOREIGN KEY (k_id) wird der Fremdschlüssel festgelegt und welche Spalte der Fremdschlüssel sein soll. REFERENCES leitet die Referenztabelle ein, kunde ist der Tabellenname. Mit (k_id) wird der Schlüssel in der Referenztabelle angegeben.

Um festzulegen, was passiert, wenn in der Tabelle kunde ein Eintrag gelöscht oder geändert wird, können die Optionen ON DELETE und ON UPDATE verwendet werden.

FOREIGN KEY (k_id) REFERENCES kunde (k_id) 
[ON DELETE OPTION]
[ON UPDATE OPTION]

Die folgende Tabelle stellt die Optionen dar:

Option

Beschreibung

RESTRICT

Veränderungen an der Eltern-Tabelle (Tabelle mit dem Primärschlüssel) werden verhindert, solange es Referenzen in der Kind-Tabelle (Tabelle mit dem Fremdschlüssel) gibt. Diese Option ist sowohl beim Löschen als auch beim Ändern Standard und muss nicht extra angegeben werden.

SET NULL

Eine Veränderung an der Eltern-Tabelle sorgt dafür, dass in Kind-Tabelle der Eintrag im Fremdschlüssel auf einen Nullwert (NULL) gesetzt wird.

CASCADE

Eine Lösung oder Veränderung an der Eltern-Tabelle sorgt dafür, dass in der Kind-Tabelle der Eintrag (die Zeile) entweder auch gelöscht oder verändert wird.

Anpassung der Tabelle „rechungen“ mit der Fremdschlüssel-Option SET NULL

MYSQL
CREATE TABLE kunde (
	k_id integer primary key auto_increment,
	k_name varchar(20)
);

CREATE TABLE rechnungen (
	r_id integer primary key auto_increment,
	r_nummer integer,
	k_id integer,
	FOREIGN KEY (k_id) REFERENCES kunde (k_id)
	ON DELETE SET NULL
	ON UPDATE SET NULL
);
SQLite
CREATE TABLE kunde (
	k_id integer primary key autoincrement,
	k_name text
);

CREATE TABLE rechnungen (
	r_id integer primary key autoincrement,
	r_nummer integer,
	k_id integer,
	FOREIGN KEY (k_id) REFERENCES kunde (k_id)
	ON DELETE SET NULL
	ON UPDATE SET NULL
);

Anpassung der Tabelle „rechungen“ mit der Fremdschlüssel-Option CASCADE

MYSQL
CREATE TABLE kunde (
	k_id integer primary key auto_increment,
	k_name varchar(20)
);

CREATE TABLE rechnungen (
	r_id integer primary key auto_increment,
	r_nummer integer,
	k_id integer,
	FOREIGN KEY (k_id) REFERENCES kunde (k_id)
	ON DELETE CASCADE
	ON UPDATE CASCADE
);
SQLite
CREATE TABLE kunde (
	k_id integer primary key autoincrement,
	k_name text
);

CREATE TABLE rechnungen (
	r_id integer primary key autoincrement,
	r_nummer integer,
	k_id integer,
	FOREIGN KEY (k_id) REFERENCES kunde (k_id)
	ON DELETE CASCADE
	ON UPDATE CASCADE
);

SET NULL und CASCADE könne auch kombiniert werden.

FOREIGN KEY (k_id) REFERENCES kunde (k_id)
ON DELETE SET NULL
ON UPDATE CASCADE

Mehrere Fremdschlüssel-Anweisungen werden mittels Komma (,) getrennt.

create table if not exists kunden (
  kunden_id integer primary key autoincrement,
  vorname text
);

create table if not exists produkte (
  produkt_id integer primary key autoincrement,
  name text
);

create table if not exists kunden_produkt (
  kunden_produkt_id integer primary key autoincrement,
  kunden_id integer,
  produkt_id integer,
  foreign key (kunden_id) references kunden (kunden_id)
  on update cascade
  on delete cascade,
  foreign key (produkt_id) references produkt (produkt_id)
  on update cascade
  on delete cascade
);