Ryšių lentelės susiejimas PHP
Tarkime, vartotojas buvo įvairiuose miestuose. Šiuo atveju lentelė su vartotojais galėtų turėti tokį vaizdą:
| id | name | city |
|---|---|---|
| 1 | user1 | city1, city2, city3 |
| 2 | user2 | city1, city2 |
| 3 | user3 | city2, city3 |
| 4 | user4 | city1 |
Suprantama, kad tokiu būdu saugoti duomenis neteisinga - miestus reikia išskirti į atskirą lentelę. Štai ji:
| id | name |
|---|---|
| 1 | city1 |
| 2 | city2 |
| 3 | city3 |
Tačiau mums reikia padaryti taip, kad kiekvienas vartotojas galėtų nuorodą į kelis miestus. Naudojant dvi lenteles to padaryti neįmanoma.
Mums reikės įvesti vadinamąją ryšių lentelę, kuri susies vartotoją su jo miestais.
Kiekviename šios lentelės įraše bus saugomas ryšys tarp vartotojo ir vieno miesto. Tuo pačiu metu vienam vartotojui šioje lentelėje bus tiek įrašų, kiek miestų jis lankėsi.
Štai mūsų ryšių lentelė:
| 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 |
Lentelė su vartotojais saugos tik vartotojų vardus, be ryšių:
| id | name |
|---|---|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
| 5 | user5 |
Užklausos
Padarykime užklausą, kurios pagalba ištrauksime vartotojus kartu su jų miestais. Tam mums reikės atlikti du jungimus: pirmasis jungimas prijungs prie vartotojų ryšių lentelę, o antrasis jungimas per ryšius prijungs miestus:
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
Užklausos rezultatas
Mūsų užklausos rezultatas PHP talpins kiekvieno vartotojo vardą tiek kartų, su kiek miestų jis susijęs:
<?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'],
];
?>
Patogiau būtų konvertuoti tokį masyvą ir paversti jį tokiu:
<?php
$res = [
['user1' => ['city1', 'city2', 'city3']],
['user2' => ['city1', 'city2']],
['user3' => ['city2', 'city3']],
['user4' => ['city1']],
];
?>
Parašykime kodą, atliekantį tokią konvertaciją:
<?php
$res = [];
foreach ($data as $elem) {
$res[$elem['user_name']][] = $elem['city_name'];
}
var_dump($res);
?>
Praktinės užduotys
Tarkime, produktas gali priklausyti kelioms kategorijoms. Aprašykite saugojimo struktūrą.
Parašykite užklausą, kuri ištrauks produktus kartu su jų kategorijomis.
Atvaizduokite gautus duomenis kaip sąrašą
ul taip, kad kiekvienoje li pradžioje
būtų produkto pavadinimas, o po dvitaškio per
kablelį būtų išvardintos šio produkto kategorijos.
Maždaug taip:
<ul>
<li>product1: category1, category2, category3</li>
<li>product2: category1, category3</li>
<li>product3: category1</li>
</ul>