Không có truy vấn SQL đơn lẻ nào có thể mang lại cho Bạn kết quả được sắp xếp theo cách Bạn mong đợi dựa trên cấu trúc bảng này.
Có hai cách để giải quyết vấn đề:
-
Sử dụng logic ứng dụng bên ngoài (bên ngoài DB) để thực hiện các lệnh gọi đệ quy sẽ phát hiện ra con của mỗi danh mục và xây dựng cây trong ứng dụng.
-
Sử dụng một trong các thuật toán để lưu trữ dữ liệu dạng cây trong cơ sở dữ liệu quan hệ. Một trong các thuật toán đó được gọi là
Modified Preorder Tree Traversal
hoặc đơn giản là MPTT.
Giả sử chúng ta sử dụng các cột lft
và rgt
để duy trì các chỉ mục trái / phải trong quá trình duyệt, khi bạn chèn một danh mục mới, bạn sẽ cần:
-
Nhận thông tin danh mục chính theo Id:
SELECT lft,rgt FROM tbl_categories WHERE categoryId=5
Hãy giả sử cho một vấn đề ví dụ, rằng danh mục mẹ cólft=7
vàrgt=10
(trong trường hợp này nó đã có một con) -
Dành chỗ cho mục nhập mới - chuyển tất cả các bản ghi theo 2 (1 cho lft và 1 cho rgt):
UPDATE tbl_categories SET rgt=rgt+2 WHERE rgt>=10 ORDER BY rgt DESC
UPDATE tbl_categories SET lft=lft+2 WHERE lft>=10 ORDER BY lft DESC
Lưu ý ở đây ORDER
giảm dần. Dưới dạng lft
và rgt
được cho là duy nhất, nên tạo UNIQUE
ràng buộc chúng và sau đó thứ tự giảm dần trong cập nhật là cần thiết để ngăn các lỗi chính trùng lặp.
-
Đặt
lft=<former parent rgt>
vàrgt=<former parent rgt +1>
và chèn một bản ghi mới ...INSERT INTO tbl_categories SET categoryName="New Child",parentCategoryId=5,lft=11,rgt=12,...
Bạn có thể tìm thấy các ví dụ chi tiết hơn với mã nếu bạn tìm kiếm MPTT PHP MySQL
. Có khá nhiều hướng dẫn về chủ đề này.