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:

users
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:

cities
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:

users_cities
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:

users
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:

sqlSELECT
  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<?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<?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<?php
  $res = [];
  
  foreach ($data as $elem) {
    $res[$elem['user_name']][] = $elem['city_name'];
  }
  
  var_dump($res);
?>

Pratik Görevler

Задание 1

Bir ürünün birden fazla kategoriye ait olabildiğini varsayalım. Saklama yapısını açıklayın.

Задание 2

Ürünleri kategorileriyle birlikte getirecek bir sorgu yazın.

Задание 3

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:

html<ul>
  <li>product1: category1, category2, category3</li>
  <li>product2: category1, category3</li>
  <li>product3: category1</li>
</ul>