PHP'de Bağlantı Tablosu ile İlişkilendirme
Şimdi kullanıcının farklı şehirlerde bulunduğunu varsayalım. Bu durumda kullanıcılar tablosu şu şekilde olabilir:
| id | name | city |
|---|---|---|
| 1 | user1 | city1, city2, city3 |
| 2 | user2 | city1, city2 |
| 3 | user3 | city2, city3 |
| 4 | user4 | city1 |
Verileri bu şekilde saklamanın yanlış olduğu açıktır - şehirler ayrı bir tabloya taşınmalıdır. İşte o tablo:
| id | name |
|---|---|
| 1 | city1 |
| 2 | city2 |
| 3 | city3 |
Ancak, her kullanıcının birden fazla şehre referans verebilmesini sağlamamız gerekiyor. Bunu sadece iki tablo ile yapmak imkansızdır.
Bir kullanıcıyı şehirleriyle bağlayacak, sözde bağlantı tablosu olarak adlandırılan bir tabloya ihtiyacımız olacak.
Bu tablodaki her kayıt, bir kullanıcı ile bir şehir arasındaki bağlantıyı saklayacaktır. Ayrıca, bir kullanıcı için bu tabloda, bulunduğu şehir sayısı kadar kayıt olacaktır.
İşte bağlantı tablomuz:
| 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 |
Kullanıcılar tablosu sadece kullanıcı isimlerini saklayacak, bağlantılar olmadan:
| id | name |
|---|---|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
| 5 | user5 |
Sorgular
Kullanıcıları şehirleriyle birlikte getirecek bir sorgu yapalım. Bunun için iki join işlemine ihtiyacımız olacak: ilk join, kullanıcılara bağlantı tablosunu ekleyecek, ikinci join ise bağlantılar üzerinden şehirleri ekleyecek:
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
Sorgu Sonucu
PHP'de sorgumuzun sonucu, her kullanıcının adını, bağlı olduğu şehir sayısı kadar içerecektir:
<?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'],
];
?>
Böyle bir diziyi dönüştürüp aşağıdaki hale getirmek daha kullanışlı olurdu:
<?php
$res = [
['user1' => ['city1', 'city2', 'city3']],
['user2' => ['city1', 'city2']],
['user3' => ['city2', 'city3']],
['user4' => ['city1']],
];
?>
Böyle bir dönüşümü gerçekleştiren kodu yazalım:
<?php
$res = [];
foreach ($data as $elem) {
$res[$elem['user_name']][] = $elem['city_name'];
}
var_dump($res);
?>
Pratik Görevler
Bir ürünün birden fazla kategoriye ait olabildiğini varsayalım. Saklama yapısını açıklayın.
Ürünleri kategorileriyle birlikte getirecek bir sorgu yazın.
Elde edilen verileri, her li'de önce
ürün adının yer aldığı, ardından iki nokta
üst üsteden sonra bu ürünün kategorilerinin
virgülle listelendiği bir ul listesi
olarak gösterin.
Örnek olarak şu şekilde:
<ul>
<li>product1: category1, category2, category3</li>
<li>product2: category1, category3</li>
<li>product3: category1</li>
</ul>