계층형 카테고리 관리: MySQL과 PHP로 트리 구조 만들기
계층형 카테고리 관리: MySQL과 PHP로 트리 구조 만들기
웹사이트나 쇼핑몰을 운영하다 보면 계층적인 카테고리 구조를 관리해야 하는 경우가 많습니다. 예를 들어, 전자제품 카테고리를 만들면 "TV" → "OLED TV" → "LG OLED TV"와 같이 단계별로 구분됩니다. 이런 트리 구조를 효과적으로 관리하려면 어떻게 해야 할까요? 이번 글에서는 MySQL과 PHP를 활용하여 카테고리 트리를 구현하는 방법을 소개합니다.
1. 계층형 카테고리 설계
📌 4단계 테이블 구조
우리는 카테고리를 4단계로 나누고, 각 단계는 상위 단계의 ID를 참조하도록 설계합니다. 테이블 구조는 다음과 같습니다:
CREATE TABLE category_l1 (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL
);
CREATE TABLE category_l2 (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
parent_id INT NOT NULL,
FOREIGN KEY (parent_id) REFERENCES category_l1(id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
CREATE TABLE category_l3 (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
parent_id INT NOT NULL,
FOREIGN KEY (parent_id) REFERENCES category_l2(id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
CREATE TABLE category_l4 (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
parent_id INT NOT NULL,
FOREIGN KEY (parent_id) REFERENCES category_l3(id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
이 구조에서는 각 하위 카테고리 테이블이 상위 테이블의 ID를 참조하며, ON DELETE CASCADE 옵션을 설정하여 부모 카테고리가 삭제되면 하위 카테고리도 자동으로 삭제됩니다. 즉, "LG OLED TV"가 속한 "OLED TV" 카테고리를 삭제하면, "LG OLED TV"도 자동으로 삭제됩니다.
2. PHP에서 계층형 데이터 조회
이제 저장된 카테고리를 트리 형태로 변환하여 출력하는 PHP 코드를 작성해봅니다.
function getCategories($pdo) {
$categories = [
'l1' => [],
'l2' => [],
'l3' => [],
'l4' => []
];
foreach (['l1', 'l2', 'l3', 'l4'] as $level) {
$query = "SELECT * FROM category_" . $level;
$stmt = $pdo->query($query);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$categories[$level][$row['id']] = $row;
}
}
return $categories;
}
이렇게 데이터를 가져온 후, PHP에서 트리 구조로 변환하여 HTML로 출력해야 합니다.
function buildTree($categories, $parentId = 0, $level = 'l1') {
$html = "<ul>";
foreach ($categories[$level] as $id => $category) {
if ($category['parent_id'] == $parentId || $level === 'l1') {
$html .= "<li>" . $category['name'];
$nextLevel = 'l' . (substr($level, 1) + 1);
if (isset($categories[$nextLevel])) {
$html .= buildTree($categories, $id, $nextLevel);
}
$html .= "</li>";
}
}
$html .= "</ul>";
return $html;
}
이제 getCategories($pdo)로 데이터를 가져오고 buildTree($categories)를 실행하면 트리 구조의 HTML이 자동으로 생성됩니다.
3. AJAX를 활용한 추가/수정/삭제 기능
사용자는 웹에서 카테고리를 추가, 수정, 삭제할 수 있어야 합니다. 이를 위해 AJAX를 사용하여 saveCategory.php와 deleteCategory.php를 호출하는 방식으로 구현합니다.
📌 카테고리 추가/수정 (saveCategory.php)
<?php
require 'db.php';
$name = $_POST['name'];
$parentId = $_POST['parent_id'];
$level = $_POST['level'];
$id = $_POST['id'] ?? null;
if ($id) {
$stmt = $pdo->prepare("UPDATE category_$level SET name = ? WHERE id = ?");
$stmt->execute([$name, $id]);
} else {
$stmt = $pdo->prepare("INSERT INTO category_$level (name, parent_id) VALUES (?, ?)");
$stmt->execute([$name, $parentId]);
}
echo json_encode(["status" => "success"]);
📌 카테고리 삭제 (deleteCategory.php)
<?php
require 'db.php';
$id = $_POST['id'];
$level = $_POST['level'];
$stmt = $pdo->prepare("DELETE FROM category_$level WHERE id = ?");
$stmt->execute([$id]);
echo json_encode(["status" => "success"]);
4. 트리 UI 구현 (HTML + JavaScript)
<ul id="categoryTree"></ul>
<button id="addCategory">추가</button>
<script>
function loadCategories() {
$.get('loadCategories.php', function(data) {
$('#categoryTree').html(data);
});
}
$(document).on('click', '.delete-btn', function() {
const id = $(this).data('id');
const level = $(this).data('level');
$.post('deleteCategory.php', { id, level }, function() {
loadCategories();
});
});
$('#addCategory').click(function() {
const name = prompt('카테고리명:');
if (!name) return;
$.post('saveCategory.php', { name, parent_id: 0, level: 'l1' }, function() {
loadCategories();
});
});
loadCategories();
</script>
이제 트리 구조가 실시간으로 추가, 수정, 삭제가 가능해졌습니다. 이 방식은 JSON 기반보다 확장성이 뛰어나며, 데이터 무결성을 유지하기에도 좋습니다. 이 구조를 활용하면 재고 관리, 제품 분류, 메뉴 관리 등 다양한 분야에 적용할 수 있습니다.
#MySQL,#PHP,#카테고리트리,#트리구조,#데이터베이스설계,#계층형데이터,#AJAX,#웹개발,#데이터무결성,#동적UI