Verknüpfung über eine Verknüpfungstabelle in PHP
Nehmen wir an, der User war in verschiedenen Städten. In diesem Fall könnte die Tabelle mit den Usern folgendermaßen aussehen:
| id | name | city |
|---|---|---|
| 1 | user1 | city1, city2, city3 |
| 2 | user2 | city1, city2 |
| 3 | user3 | city2, city3 |
| 4 | user4 | city1 |
Es ist klar, dass es falsch ist, Daten so zu speichern - die Städte müssen in eine separate Tabelle ausgelagert werden. Hier ist sie:
| id | name |
|---|---|
| 1 | city1 |
| 2 | city2 |
| 3 | city3 |
Allerdings müssen wir es so einrichten, dass jeder User auf mehrere Städte verweisen kann. Mit zwei Tabellen ist das unmöglich.
Wir müssen eine sogenannte Verknüpfungstabelle einführen, die den User mit seinen Städten verknüpft.
In jedem Datensatz dieser Tabelle wird die Verknüpfung zwischen einem User und einer Stadt gespeichert. Dabei wird es für einen User in dieser Tabelle so viele Datensätze geben, wie Städte er besucht hat.
Hier ist unsere Verknüpfungstabelle:
| id | user_id | city_id |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 2 | 2 |
| 6 | 3 | 2 |
| 7 | 3 | 3 |
| 8 | 4 | 1 |
Die Tabelle mit den Usern wird nur die Namen der User speichern, ohne Verknüpfungen:
| id | name |
|---|---|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
| 5 | user5 |
Abfragen
Lassen Sie uns eine Abfrage erstellen, mit der wir die User zusammen mit ihren Städten abrufen. Dafür benötigen wir zwei Joins: der erste Join verknüpft die User mit der Verknüpfungstabelle, und der zweite Join verknüpft über die Verknüpfungen die Städte:
SELECT
users.name as user_name, cities.name as city_name
FROM
users
LEFT JOIN users_cities ON users_cities.user_id=users.id
LEFT JOIN cities ON users_cities.city_id=cities.id
Ergebnis der Abfrage
Das Ergebnis unserer Abfrage in PHP wird den Namen jedes Users so oft enthalten, wie Städte mit ihm verknüpft sind:
<?php
$arr = [
['user_name' => 'user1', 'city_name' => 'city1'],
['user_name' => 'user1', 'city_name' => 'city2'],
['user_name' => 'user1', 'city_name' => 'city3'],
['user_name' => 'user2', 'city_name' => 'city1'],
['user_name' => 'user2', 'city_name' => 'city2'],
['user_name' => 'user3', 'city_name' => 'city2'],
['user_name' => 'user3', 'city_name' => 'city3'],
['user_name' => 'user4', 'city_name' => 'city1'],
];
?>
Es wäre bequemer, ein solches Array umzuwandeln und in folgendes zu verwandeln:
<?php
$res = [
['user1' => ['city1', 'city2', 'city3']],
['user2' => ['city1', 'city2']],
['user3' => ['city2', 'city3']],
['user4' => ['city1']],
];
?>
Schreiben wir einen Code, der eine solche Konvertierung durchführt:
<?php
$res = [];
foreach ($data as $elem) {
$res[$elem['user_name']][] = $elem['city_name'];
}
var_dump($res);
?>
Praktische Aufgaben
Nehmen wir an, ein Produkt kann mehreren Kategorien angehören. Beschreiben Sie die Speicherstruktur.
Schreiben Sie eine Abfrage, die die Produkte zusammen mit ihren Kategorien abruft.
Geben Sie die erhaltenen Daten in Form einer Liste
ul aus, sodass in jedem li zuerst
der Produktname steht und nach dem Doppelpunkt, durch
Komma getrennt, die Kategorien dieses Produkts aufgelistet werden.
Ungefähr so:
<ul>
<li>product1: category1, category2, category3</li>
<li>product2: category1, category3</li>
<li>product3: category1</li>
</ul>