PHP에서 연결 테이블을 통한 관계 설정

이제 사용자가 여러 도시에 있었던 경우를 가정해 보겠습니다. 이 경우 사용자 테이블은 다음과 같은 모습일 수 있습니다:

users
id name city
1 user1 city1, city2, city3
2 user2 city1, city2
3 user3 city2, city3
4 user4 city1

이런 식으로 데이터를 저장하는 것은 올바르지 않다는 것이 분명합니다. 도시는 별도의 테이블로 분리해야 합니다. 다음은 그 테이블입니다:

cities
id name
1 city1
2 city2
3 city3

그러나 각 사용자가 여러 도시를 참조할 수 있도록 만들어야 합니다. 두 개의 테이블로는 이것을 구현할 수 없습니다.

소위 연결 테이블을 도입해야 합니다. 이 테이블은 사용자를 해당 도시들과 연결할 것입니다.

이 테이블의 각 레코드는 사용자와 하나의 도시 간의 연결을 저장합니다. 이 경우 한 사용자에 대해 이 테이블에는 그가 방문한 도시 수만큼의 레코드가 존재합니다.

다음은 우리의 연결 테이블입니다:

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

사용자 테이블은 연결 없이 사용자 이름만 저장할 것입니다:

users
id name
1 user1
2 user2
3 user3
4 user4
5 user5

쿼리

사용자와 그들의 도시를 함께 가져오는 쿼리를 만들어 보겠습니다. 이를 위해서는 두 개의 조인이 필요합니다: 첫 번째 조인은 사용자에 연결 테이블을 붙이고, 두 번째 조인은 연결을 통해 도시를 붙입니다:

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

쿼리 결과

PHP에서 우리 쿼리의 결과는 각 사용자 이름이 그가 연결된 도시 수만큼 반복되어 포함될 것입니다:

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'],
  ];
?>

이러한 배열을 변환하여 다음 형태로 만드는 것이 더 편리할 것입니다:

php<?php
  $res = [
    ['user1' => ['city1', 'city2', 'city3']],
    ['user2' => ['city1', 'city2']],
    ['user3' => ['city2', 'city3']],
    ['user4' => ['city1']],
  ];
?>

이러한 변환을 수행하는 코드를 작성해 보겠습니다:

php<?php
  $res = [];
  
  foreach ($data as $elem) {
    $res[$elem['user_name']][] = $elem['city_name'];
  }
  
  var_dump($res);
?>

실습 과제

Задание 1

하나의 제품이 여러 카테고리에 속할 수 있다고 가정합니다. 저장 구조를 설명하세요.

Задание 2

제품을 해당 카테고리와 함께 가져오는 쿼리를 작성하세요.

Задание 3

얻은 데이터를 ul 목록으로 출력하세요. 각 li에는 먼저 제품 이름이 오고, 콜론 뒤에 해당 제품의 카테고리를 쉼표로 구분하여 나열하세요. 대략 다음과 같이:

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