Relationen - Tabellen verbinden

Anhand einer Adressverwaltung sehen wir uns am praktischen Beispiel Relationen an und wie Tabellen miteinander verbunden werden.

Aufgabe: Erstellen Sie ein Adressbuch als PHP-Anwendung

Erstellen Sie ein Adressbuch, in dem Sie Adressen eintragen, ändern und löschen können. Als Beispiel, was an Daten praktisch sein könnte, hier (m)eine Visitenkarte.

Inhalt Visitenkarte für Adressverwaltung
Inhalt Visitenkarte für Adressverwaltung

Bitte beim Aufbau der Struktur der Datenbank an die Grundprinzipien für Datenbankgestaltung denken: Inhalte trennen (atomisieren), eindeutige Zugriffsmöglichkeiten schaffen, keine Datenredundanz (Mehrfachspeicherung). http://www.php-kurs.com/daten-strukturieren-fuer-datenbank.htm

Datenbankaufbau Adressverwaltung

Als Vorschlag können Sie folgenden Aufbau nutzen (bzw. vergleichen mit der von Ihnen erstellten Lösung).

Als Tabellename: adressen (das Kind sollte man so benennen, dass eindeutig hervorgeht, welche Daten sich dahinter verstecken)

id für die eindeutige Zugriffsmöglichkeit
geschlecht dieses wird hier mit „f“ für female und „m“ für male eingetragen. Aus dieser Angabe können wir dann problemlos Anreden ("Sehr geehrte Frau ...") erzeugen
nachname, vorname, strasse irgendwie selbstredend
plz 5 stellig – um das Beispiel einfach zu halten, werden wir nur 5 stellige Postleitzahlen erfassen
email die E-Mail-Adresse der Person
url die WWW-Adresse, falls die Person eine Website hat

Als fertiges MySQL-Statement sieht das wie folgt aus:

CREATE TABLE `adressen` (
`id` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`geschlecht` CHAR( 1 ) NOT NULL ,
`nachname` VARCHAR( 255 ) NOT NULL ,
`vorname` VARCHAR( 255 ) NOT NULL ,
`strasse` VARCHAR( 200 ) NOT NULL ,
`plz` INT( 5 ) NOT NULL ,
`tel` VARCHAR( 100 ) NOT NULL ,
`email` VARCHAR( 150 ) NOT NULL ,
`url` VARCHAR( 150 ) NOT NULL
) ENGINE = MYISAM ;

Wo bleibt der Ort?

Für den Ort erstellen wir eine eigene Tabelle. Dies macht Sinn, um Datenredundanz (Mehrfachspeicherung) zu vermeiden. In dieser Tabelle sind zu den entsprechenden PLZ die Orte eingetragen.

Da die PLZ eindeutig ist, wird diese zu unserem Index und kann als Suchkriterium dienen.

CREATE TABLE `orte` (
`plz` INT( 5 ) NOT NULL ,
`ort` VARCHAR( 255 ) NOT NULL ,
PRIMARY KEY ( `plz` )
) ENGINE = MYISAM ;

Tragen Sie nun 1-2 Adressen von Hand über phpMyAdmin ein (auch die PLZ und den Ort in der entsprechenden Tabelle).

Verbinden beider Tabellen

Für die Auswertung und Nutzung unserer Adressauflistung müssen wir die Tabelle „adressen“ mit der Tabelle „orte“ verbinden.

Als erstes selektieren wir alle Spalten der Adress-Tabelle:

SELECT * FROM adressen

Zum Verbinden benötigen wir den grundlegenden Aufbau:

LEFT JOIN tabellenname ON Relation

Relation: Nun müssen wir für MySQL die Zusammenhänge zwischen den Tabellen aufbauen. Dies geschieht über eine Relation. Relationen beschreiben i.A. Beziehungen zwischen Gegenständen bzw. Objekten. In Tabellen also wird die Beziehung zwischen 2 Tabellen beschrieben.

Unsere Relation ist:

adressen.plz = orte.plz

Und das Ganze nun als MySQL-Statement:

SELECT * FROM adressen
LEFT JOIN orte ON adressen.plz = orte.plz

Als Ergebnis erhalten wir nun:

über LEFT JOIN verbundene Tabellen
über LEFT JOIN verbundene Tabellen

Hier sieht man, dass ist das bei der ID 2 unter den Feldern „plz“ und „ort“ NULL ausgegeben wird. Hier greift die Relation ins „Leere“. In der Datenbank mit den Orten ist kein Eintrag hinterlegt für die Postleitzahl „77777“.

Möchte man (was bei diesem Beispiel wenig Sinn macht, aber der Vollständigkeit halber) keine NULL-Werte, können diese Sätze ausgeklammert werden.

SELECT * FROM adressen
LEFT JOIN orte ON adressen.plz = orte.plz
WHERE adressen.plz = orte.plz

Wenn nicht alle Felder ausgegeben werden sollen, kann dies fast wie gewohnt geschehen, wenn anstatt dem * die gewünschten Felder angegeben werden, die angezeigt werden sollen.

SELECT vorname
FROM adressen
LEFT JOIN orte ON adressen.plz = orte.plz

Um Fehlermeldungen vorzubeugen, falls derselbe Feldname in beiden Tabellen vorkommt, sollten Sie noch angeben, aus welcher Tabelle das Feld stammt.

SELECT adressen.vorname, orte.plz
FROM adressen
LEFT JOIN orte ON adressen.plz = orte.plz

Ansonsten können Sie schnell eine Fehlermeldung dieser Art bekommen:

MySQL meldet:  
#1052 - Column 'plz' in field list is ambiguous

Erstellen Sie die Anwendung – beachten Sie, dass bei der Neuanlage einer Adresse in der Tabelle „orte“ überprüft werden muss, ob die PLZ bereits eingetragen ist. Wenn nicht, dann diese in der Tabelle „orte“ eintragen (natürlich mit Ort).

Tipp zum Überprüfen: Zählen Sie einfach die Ergebnisse bei der Bedingung ... WHERE plz='$plz?'