Kobling via koblingstabell i PHP
La oss nå si at brukeren har vært i forskjellige byer. I dette tilfellet kunne tabellen med brukere ha følgende utseende:
| 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 feil å lagre data på denne måten - byene må flyttes til en egen tabell. Her er den:
| id | name |
|---|---|
| 1 | city1 |
| 2 | city2 |
| 3 | city3 |
Imidlertid trenger vi å gjøre det slik at hver bruker kan referere til flere byer. Dette er umulig å gjøre med bare to tabeller.
Vi må innføre en såkalt koblingstabell, som vil koble brukeren med hans byer.
I hver post i denne tabellen vil det lagres en kobling mellom en bruker og én by. Samtidig vil det for én bruker være like mange poster i denne tabellen som byer han har vært i.
Her er vår koblingstabell:
| 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 brukere vil bare lagre brukernes navn, uten koblinger:
| id | name |
|---|---|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
| 5 | user5 |
Spørringer
La oss lage en spørring som henter brukerne sammen med deres byer. For å gjøre dette trenger vi å utføre to joins: den første joinen vil koble brukerne til koblingstabellen, og den andre joinen vil via koblingene koble byene:
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
Resultat av spørring
Resultatet av spørringen vår i PHP vil inneholde hvert brukernavn like mange ganger som antall byer han er koblet til:
<?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 mer praktisk å konvertere et slikt array og gjøre det om til følgende:
<?php
$res = [
['user1' => ['city1', 'city2', 'city3']],
['user2' => ['city1', 'city2']],
['user3' => ['city2', 'city3']],
['user4' => ['city1']],
];
?>
La oss skrive kode som utfører en slik konvertering:
<?php
$res = [];
foreach ($data as $elem) {
$res[$elem['user_name']][] = $elem['city_name'];
}
var_dump($res);
?>
Praktiske oppgaver
La oss si at en produkt kan tilhøre flere kategorier. Beskriv lagringsstrukturen.
Skriv en spørring som henter produktene sammen med deres kategorier.
Vis de innhentede dataene som en liste
ul slik at i hver li står
produktnavnet først, og etter kolon gjennom
komma listes kategoriene til dette produktet.
Omtrent slik:
<ul>
<li>product1: category1, category2, category3</li>
<li>product2: category1, category3</li>
<li>product3: category1</li>
</ul>