Forbindelse gennem forbindelsestabel i PHP
Lad os nu sige, at brugeren har været i forskellige byer. I dette tilfælde kunne tabellen med brugere se sådan ud:
| id | name | city |
|---|---|---|
| 1 | user1 | city1, city2, city3 |
| 2 | user2 | city1, city2 |
| 3 | user3 | city2, city3 |
| 4 | user4 | city1 |
Det er klart, at det er forkert at gemme data på denne måde - byerne skal flyttes til en separat tabel. Her er den:
| id | name |
|---|---|
| 1 | city1 |
| 2 | city2 |
| 3 | city3 |
Men vi skal gøre det sådan, at hver bruger kan henvise til flere byer. Det er umuligt at gøre dette med kun to tabeller.
Vi bliver nødt til at indføre en såkaldt forbindelsestabel , som vil forbinde brugeren med hans byer.
I hver post i denne tabel vil der gemmes en forbindelse mellem en bruger og én by. Samtidig vil der for én bruger i denne tabel være lige så mange poster, som han har været i byer.
Her er vores forbindelsestabel:
| 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 |
Tabellen med brugere vil kun gemme brugernavnene uden forbindelser:
| id | name |
|---|---|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
| 5 | user5 |
Forespørgsler
Lad os lave en forespørgsel, som henter brugere sammen med deres byer. For at gøre dette har vi brug for at lave to joins: det første join vil tilføje forbindelsestabellen til brugerne, og det andet join vil tilføje byerne via forbindelserne:
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
Forespørgselsresultat
Resultatet af vores forespørgsel i PHP vil indeholde hver brugers navn lige så mange gange, som han er forbundet til byer:
<?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'],
];
?>
Det ville være mere praktisk at konvertere et sådant array og omdanne det til følgende:
<?php
$res = [
['user1' => ['city1', 'city2', 'city3']],
['user2' => ['city1', 'city2']],
['user3' => ['city2', 'city3']],
['user4' => ['city1']],
];
?>
Lad os skrive koden, der udfører en sådan konvertering:
<?php
$res = [];
foreach ($data as $elem) {
$res[$elem['user_name']][] = $elem['city_name'];
}
var_dump($res);
?>
Praktiske opgaver
Lad os sige, at et produkt kan tilhøre flere kategorier. Beskriv lagringsstrukturen.
Skriv en forespørgsel, der henter produkter sammen med deres kategorier.
Vis de modtagne data som en liste
ul, sådan at i hver li står
produktnavnet først, og efter et kolon
opremses produktets kategorier adskilt af
komma. Cirka sådan:
<ul>
<li>product1: category1, category2, category3</li>
<li>product2: category1, category3</li>
<li>product3: category1</li>
</ul>