Povezivanje preko tabele veze u PHP-u
Neka sada korisnik boravi u različitim gradovima. U ovom slučaju tabela sa korisnicima bi mogla da ima sledeći izgled:
| id | name | city |
|---|---|---|
| 1 | user1 | city1, city2, city3 |
| 2 | user2 | city1, city2 |
| 3 | user3 | city2, city3 |
| 4 | user4 | city1 |
Jasno je da na ovaj način čuvati podatke nije ispravno - gradove treba izdvojiti u zasebnu tabelu. Evo je:
| id | name |
|---|---|
| 1 | city1 |
| 2 | city2 |
| 3 | city3 |
Međutim, potrebno je da postignemo da svaki korisnik može da se odnosi na više gradova. Pomoću dve tabele to je nemoguće uraditi.
Trebaće nam da uvedemo takozvanu tabelu veze, koja će da povezuje korisnika sa njegovim gradovima.
U svakom zapisu ove tabele će se čuvati veza između korisnika i jednog grada. Pristom za jednog korisnika u ovoj tabeli će biti onoliko zapisa, u koliko je gradova bio.
Evo naše tabele veze:
| 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 |
Tabela sa korisnicima će čuvati samo imena korisnika, bez veza:
| id | name |
|---|---|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
| 5 | user5 |
Upiti
Hajde da napravimo upit, pomoću koga ćemo izvući korisnike zajedno sa njihovim gradovima. Za ovo će nam biti potrebno da izvršimo dva spajanja (join-a): prvo spajanje će pridružiti korisnicima tabelu veze, a drugo spajanje preko veza će pridružiti gradove:
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
Rezultat upita
Rezultat našeg upita u PHP-u će sadržati ime svakog korisnika onoliko puta, sa koliko gradova je povezan:
<?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'],
];
?>
Bilo bi praktičnije da se takav niz konvertuje i pretvori u sledeći:
<?php
$res = [
['user1' => ['city1', 'city2', 'city3']],
['user2' => ['city1', 'city2']],
['user3' => ['city2', 'city3']],
['user4' => ['city1']],
];
?>
Napišimo kod koji izvršava takvu konverziju:
<?php
$res = [];
foreach ($data as $elem) {
$res[$elem['user_name']][] = $elem['city_name'];
}
var_dump($res);
?>
Praktični zadaci
Neka proizvod može pripadati nekoliko kategorija. Opišite strukturu čuvanja podataka.
Napišite upit koji će izvući proizvode zajedno sa njihovim kategorijama.
Prikažite dobijene podatke u obliku liste
ul tako da u svakoj li na početku
stoji ime proizvoda, a posle dvotačke preko
zareza budu nabrojane kategorije tog proizvoda.
Otprilike ovako:
<ul>
<li>product1: category1, category2, category3</li>
<li>product2: category1, category3</li>
<li>product3: category1</li>
</ul>