senäh

17senäh und so…

PHP, Server & Config
14. Jul 2012
Kommentare: 2

Was sind eigentlich diese Joins und wo kann ich sie billig kaufen?

Kategorien: PHP, Server & Config | 14. Jul 2012 | Kommentare: 2

Entschuldigt bitte die reißerische Überschrift. Es ist Samstag Abend. Mir war danach 😀 Ich möchte heut ein klein wenig Klarheit in das Mysterium der Joins bringen. Für all jene unter euch, die mit dem Begriff mal so gar nix anfangen können, werde ich zeigen, was Joins eigentlich sind und warum ihr sie in abgewandelter Form vielleicht schon genutzt habt. Außerdem werde ich den Unterschied zwischen den 3 – meiner bescheidenen Meinung nach – wichtigsten Arten von Joins aufzeigen.

Was sind Joins? Kann man die nicht rauchen?

Joins bezeichnet in der Sprache der relationalen Datenbanken (sprich MySQL und Geschwister) die Verbindung zweier Datenbanktabellen. Dabei werden Datensätze auf Basis einer Bedingung verknüpft. Klingt sehr theoretisch, darum hier ein Beispiel: Katzen mit Hüten.

Beispieldatenbank

Das Beispiel, das sich durch diesen Blogpost ziehen wird: Katzen mit Hut

Das Beispiel, das sich durch diesen Blogpost ziehen wird: Katzen mit Hut (Quelle: soifound.com)

Ihr habt eine Tabelle cats und eine tabelle hats. Eine Katze hat eine ID (cat_id) und einen Namen (name). Ein Hut hat ebenfalls eine id (hat_id) und eine Bezeichnung (title). Außerdem gehört ein Hut zu einer Katze. Entsprechend hat unsere hats-Tabelle noch eine cat_id als Referenz. In SQL-Form

CREATE TABLE cats (
  cat_id int(10) NOT NULL AUTO_INCREMENT,
  name varchar(32) NOT NULL DEFAULT '',
  PRIMARY KEY (cat_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE hats (
  hat_id int(10) unsigned NOT NULL AUTO_INCREMENT,
  title varchar(32) NOT NULL DEFAULT '',
  cat_id int(11) DEFAULT NULL,
  PRIMARY KEY (hat_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

So, Beispieldatensätze. 4 Katzen: Maru, Al Katzone, Ginger Cat und Mauzi (ja, das Pokémon^^).

INSERT INTO cats (cat_id, name)
VALUES
    (1,'Maru'),
    (2,'Al Katzone'),
    (3,'Ginger Cat'),
    (4,'Mauzi');

Außerdem ein paar Hüte.

INSERT INTO hats (hat_id, title, cat_id)
VALUES
    (1,'Sombrero',2),
    (2,'Papiertüte',1),
    (3,'Partyhut',1),
    (4,'Strohhut',3),
    (5,'Amboss',NULL),
    (6,'Toupet',NULL);

Ich habe Amboss sowie Toupet keiner Katze zugewiesen. Außerdem hat Maru 2 Kopfbedeckungen, wohingegen Mauzi gar keine hat. Mit Absicht. Ist wichtig für das Verständnis. Ihr werdet schon sehen 😀

Joins ohne JOIN

Mal angenommen, wir wollen jetzt jede Katz inklusive ihrem Hut bzw. Hüten haben. Dazu holen wir einfach die Daten aus der cats-Tabelle und verbinden sie über die cat_id mit der hats-Tabelle. Wenn wir nur Katzenname und Huttitel haben wollen, sieht die SQL-Abfrage wie folgt aus:

SELECT cats.name, hats.title
FROM cats, hats
WHERE cats.cat_id = hats.cat_id

Ergebnis:

+------------+-------------+
| name       | title       |
+------------+-------------+
| Al Katzone | Sombrero    |
| Maru       | Papiertüte  |
| Maru       | Partyhut    |
| Ginger Cat | Strohhut    |
+------------+-------------+

Das mögt ihr vielleicht bereits kennen. Joins sind quasi identisch dazu, zumindest der INNER JOIN. Obige Abfrage sieht mit einem Join so hier aus:

SELECT cats.name, hats.title
FROM cats
JOIN hats
ON cats.cat_id = hats.cat_id

Liest sich ein wenig natürlicher. Und war doch gar nicht so schwer, oder? Das Ergebnis der Abfrage bleibt wie gesagt das gleiche.

Wie in der Abfrage zu sehen wird der Standard-JOIN immer automatisch als INNER JOIN interpretiert. Dabei werden nur kombinierte Datensätze aus beiden Tabellen angezeigt, die auf beiden Seiten gültig sind. Da Mauzi z.B. keinen Hut hat, kommt sie auch nicht im Ergebnis vor. Maru kommt dagegen 2 Mal vor, da er 2 Kopfbedeckungen hat, d.h. es ergeben sich 2 mögliche Kombinationen aus Katze + Hut.

LEFT JOIN und RIGHT JOIN

Doch was ist, wenn wir alle Katzen haben wollen, egal ob mit Hut oder nicht. Wenn ein Hut da ist, soll dieser inkl. dazugehöriger Katze angezeigt werden. Falls nicht, egal. Wir wollen alle Katzen, zur Not halt ohne Hut. Hier kommen Left- und Right-Joins zur Anwendung. Dabei bekommt die Tabelle das größere Gewicht, die eben links bzw. rechts der Join-Anweisung steht. Ich weiß, ich weiß. Es dürstet euch nach einem Beispiel. Darum hier eine Beispielabfrage inkl. Ergebnis.

SELECT cats.name, hats.title
FROM cats
LEFT JOIN hats
ON cats.cat_id = hats.cat_id

Hier hat sich im Gegensatz zur letzten Abfrage nichts weiter verändert außer dem Wörtchen LEFT. Doch wie sieht das Ergebnis aus?

+------------+-------------+
| name       | title       |
+------------+-------------+
| Maru       | Papiertüte  |
| Maru       | Partyhut    |
| Al Katzone | Sombrero    |
| Ginger Cat | Strohhut    |
| Mauzi      | NULL        |
+------------+-------------+

Maru ist wieder 2 Mal mit von der Partie, doch diesmal ist auch Mauzi dabei. Warum? Wir haben durch den Left-Join der linken Tabelle (in unserem Fall cats) unser Hauptaugenmerk verliehen. Da Mauzi keinen Hut hat, wird das entsprechende Feld einfach mit NULL gefüllt.

Andersherum funktioniert es genauso. Wollen wir einfach alle Hüte haben mit weniger Fokus auf die zugehörigen Katzen, erhalten wir folgende Anfrage:

SELECT cats.name, hats.title
FROM cats
RIGHT JOIN hats
ON cats.cat_id = hats.cat_id

Wir erhalten entsprechend alle Hüte, auch solche, die keiner Katze auf dem Kopf sitzen. Bei letzteren werden die abgefragten Spalten wieder mit NULL gefüllt:

+------------+-------------+
| name       | title       |
+------------+-------------+
| Al Katzone | Sombrero    |
| Maru       | Papiertüte  |
| Maru       | Partyhut    |
| Ginger Cat | Strohhut    |
| NULL       | Amboss      |
| NULL       | Toupet      |
+------------+-------------+

Das war’s auch schon

Mehr Magie steckt nicht dahinter. Aus meiner Praxis kann ich sagen, dass ich den Left-Join gelegentlich benötige, den Right-Join fast gar nicht. Unermüdliche Verwendung findet hingegen der Inner-Join.

Ein grundlegendes Verständnis der verschiedenen Möglichkeiten kann dennoch nicht schaden. Ich hoffe, dass ich ein solches vermitteln konnte 🙂

Autor: Enno

Ich bin Enno. PHP ist mein Ding, aber auch alles Neue rund um die Themen HTML5, CSS3 & Co finde ich interessant. Ich mag es Leuten zu helfen und mein Wissen weiterzugeben. Sollte dir mein Beitrag gefallen haben, lass doch nen Kommentar da oder benutze einen der Social Buttons, um deinen Dank auszudrücken ;)