Saistīšana caur saistīšanas tabulu PHP
Tagad pieņemsim, ka lietotājs atradās dažādās pilsētās. Šajā gadījumā lietotāju tabulai varētu būt šāds izskats:
| id | name | city |
|---|---|---|
| 1 | user1 | city1, city2, city3 |
| 2 | user2 | city1, city2 |
| 3 | user3 | city2, city3 |
| 4 | user4 | city1 |
Saprotams, ka šādi datus glabāt nav pareizi - pilsētas ir jāizceļ atsevišķā tabulā. Lūk, tā:
| id | name |
|---|---|
| 1 | city1 |
| 2 | city2 |
| 3 | city3 |
Tomēr mums ir jāpanāk, lai katrs lietotājs varētu atsaukties uz vairākām pilsētām. Ar divām tabulām to izdarīt nav iespējams.
Mums būs jāievada tā sauktā saistīšanas tabula, kas savienos lietotāju ar viņa pilsētām.
Katrā šīs tabulas ierakstā tiks glabāta saite starp lietotāju un vienu pilsētu. Tajā pašā laikā vienam lietotājam šajā tabulā būs tik daudz ierakstu, cik pilsētās viņš ir bijis.
Lūk, mūsu saistīšanas tabula:
| 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 |
Lietotāju tabula glabās tikai lietotāju vārdus, bez saitēm:
| id | name |
|---|---|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
| 5 | user5 |
Pieprasījumi
Izveidosim pieprasījumu, ar kura palīdzību iegūsim lietotājus kopā ar viņu pilsētām. Priekš šī mums būs nepieciešami divi savienojumi (join): pirmais savienojums pievienos lietotājiem saistīšanas tabulu, un otrais savienojums pēc saitēm pievienos pilsētas:
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
Pieprasījuma rezultāts
Mūsu pieprasījuma rezultāts PHP saturēs katra lietotāja vārdu tik reižu, ar cik pilsētām viņš ir saistīts:
<?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'],
];
?>
Ērtāk būtu pārveidot šādu massīvu un pārvērst to sekojošā:
<?php
$res = [
['user1' => ['city1', 'city2', 'city3']],
['user2' => ['city1', 'city2']],
['user3' => ['city2', 'city3']],
['user4' => ['city1']],
];
?>
Uzrakstīsim kodu, kas veic šādu pārveidošanu:
<?php
$res = [];
foreach ($data as $elem) {
$res[$elem['user_name']][] = $elem['city_name'];
}
var_dump($res);
?>
Praktiskie uzdevumi
Pieņemsim, ka produkts var piederēt vairākām kategorijām. Izklāstiet glabāšanas struktūru.
Uzrakstiet pieprasījumu, kas iegūs produktus kopā ar to kategorijām.
Parādiet iegūtos datus saraksta veidā
ul tā, lai katrā li sākumā
stāvētu produkta nosaukums, un pēc kola caur
komatu uzskaitītas šī produkta kategorijas.
Apmēram šādi:
<ul>
<li>product1: category1, category2, category3</li>
<li>product2: category1, category3</li>
<li>product3: category1</li>
</ul>