PHP에서 연결 테이블을 통한 관계 설정
이제 사용자가 여러 도시에 있었던 경우를 가정해 보겠습니다. 이 경우 사용자 테이블은 다음과 같은 모습일 수 있습니다:
| id | name | city |
|---|---|---|
| 1 | user1 | city1, city2, city3 |
| 2 | user2 | city1, city2 |
| 3 | user3 | city2, city3 |
| 4 | user4 | city1 |
이런 식으로 데이터를 저장하는 것은 올바르지 않다는 것이 분명합니다. 도시는 별도의 테이블로 분리해야 합니다. 다음은 그 테이블입니다:
| id | name |
|---|---|
| 1 | city1 |
| 2 | city2 |
| 3 | city3 |
그러나 각 사용자가 여러 도시를 참조할 수 있도록 만들어야 합니다. 두 개의 테이블로는 이것을 구현할 수 없습니다.
소위 연결 테이블을 도입해야 합니다. 이 테이블은 사용자를 해당 도시들과 연결할 것입니다.
이 테이블의 각 레코드는 사용자와 하나의 도시 간의 연결을 저장합니다. 이 경우 한 사용자에 대해 이 테이블에는 그가 방문한 도시 수만큼의 레코드가 존재합니다.
다음은 우리의 연결 테이블입니다:
| 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 |
사용자 테이블은 연결 없이 사용자 이름만 저장할 것입니다:
| id | name |
|---|---|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
| 5 | user5 |
쿼리
사용자와 그들의 도시를 함께 가져오는 쿼리를 만들어 보겠습니다. 이를 위해서는 두 개의 조인이 필요합니다: 첫 번째 조인은 사용자에 연결 테이블을 붙이고, 두 번째 조인은 연결을 통해 도시를 붙입니다:
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
쿼리 결과
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
$res = [
['user1' => ['city1', 'city2', 'city3']],
['user2' => ['city1', 'city2']],
['user3' => ['city2', 'city3']],
['user4' => ['city1']],
];
?>
이러한 변환을 수행하는 코드를 작성해 보겠습니다:
<?php
$res = [];
foreach ($data as $elem) {
$res[$elem['user_name']][] = $elem['city_name'];
}
var_dump($res);
?>
실습 과제
하나의 제품이 여러 카테고리에 속할 수 있다고 가정합니다. 저장 구조를 설명하세요.
제품을 해당 카테고리와 함께 가져오는 쿼리를 작성하세요.
얻은 데이터를 ul 목록으로 출력하세요. 각 li에는
먼저 제품 이름이 오고, 콜론 뒤에 해당 제품의 카테고리를 쉼표로 구분하여 나열하세요.
대략 다음과 같이:
<ul>
<li>product1: category1, category2, category3</li>
<li>product2: category1, category3</li>
<li>product3: category1</li>
</ul>