Linkkaus liitostaulun kautta PHP:ssä
Oletetaan nyt, että käyttäjä on käynyt eri kaupungeissa. Tässä tapauksessa käyttäjät taulukko voisi näyttää seuraavalta:
| id | name | city |
|---|---|---|
| 1 | user1 | city1, city2, city3 |
| 2 | user2 | city1, city2 |
| 3 | user3 | city2, city3 |
| 4 | user4 | city1 |
On selvää, että tällainen tietojen tallennus on väärin - kaupungit on siirrettävä erilliseen taulukkoon. Tässä se on:
| id | name |
|---|---|
| 1 | city1 |
| 2 | city2 |
| 3 | city3 |
Meidän on kuitenkin tehtävä niin, että jokainen käyttäjä voi viitata useaan kaupunkiin. Kahdella taulukolla tätä ei ole mahdollista tehdä.
Tarvitsemme niin kutsutun liitostaulun, joka linkittää käyttäjän hänen kaupunkeihinsa.
Jokaisessa tämän taulukon tietueessa tallennetaan yhteys käyttäjän ja yhden kaupungin välillä. Samalla yhdelle käyttäjälle tässä taulukossa on niin monta tietuetta, kuin monessa kaupungissa hän on käynyt.
Tässä on liitostaulumme:
| 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 |
Käyttäjien taulukko tallentaa vain käyttäjien nimet ilman linkityksiä:
| id | name |
|---|---|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
| 5 | user5 |
Kyselyt
Tehdään kysely, jonka avulla haemme käyttäjät yhdessä heidän kaupunkien kanssa. Tätä varten tarvitsemme kaksi liitosta: ensimmäinen liitos yhdistää käyttäjiin liitostaulun, ja toinen liitos liittyy kaupunkeihin linkkien kautta:
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
Kyselyn tulos
Kyselymme tulos PHP:ssä sisältää jokaisen käyttäjän nimen niin monta kertaa, kuin monen kaupungin kanssa hän on linkitetty:
<?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'],
];
?>
Olisi kätevämpää muuntaa tällainen taulukko ja muuttaa se seuraavaksi:
<?php
$res = [
['user1' => ['city1', 'city2', 'city3']],
['user2' => ['city1', 'city2']],
['user3' => ['city2', 'city3']],
['user4' => ['city1']],
];
?>
Kirjoitetaan koodi, joka suorittaa tällaisen muunnoksen:
<?php
$res = [];
foreach ($data as $elem) {
$res[$elem['user_name']][] = $elem['city_name'];
}
var_dump($res);
?>
Käytännön tehtävät
Oletetaan, että tuote voi kuulua useisiin kategorioihin. Kuvaile tallennusrakenne.
Kirjoita kysely, joka hakee tuotteet yhdessä niiden kategorioiden kanssa.
Näytä saadut tiedot listana
ul siten, että jokaisessa li aluksi
on tuotteen nimi, ja kaksoispisteen jälkeen pilkuilla eroteltuina
luetellaan tämän tuotteen kategoriat.
Suunnilleen näin:
<ul>
<li>product1: category1, category2, category3</li>
<li>product2: category1, category3</li>
<li>product3: category1</li>
</ul>