Таблица oc_category_path
Таблица oc_category_path является служебной и используется для эффективного построения и хранения иерархических связей между категориями. Она позволяет быстро определять всех предков (родителей, бабушек/дедушек и т.д.) для любой категории, что критически важно для построения дерева категорий, фильтрации товаров и корректного отображения путей (breadcrumbs).
Поля
| Поле | Тип данных | Описание |
|---|---|---|
category_id |
int |
Идентификатор категории, для которой строится путь. Внешний ключ, ссылается на oc_category.
|
path_id |
int |
Идентификатор категории, являющейся частью пути (предком) для категории с category_id. Также является внешним ключом для oc_category.
|
level |
int |
Уровень вложенности категории path_id относительно категории category_id. Уровень увеличивается с каждым шагом вверх по иерархии.
|
Как это работает
OpenCart использует таблицу oc_category_path для реализации подхода Materialized Path (материализованный путь). Вместо того чтобы рекурсивно обходить дерево категорий каждый раз, система заранее сохраняет все возможные пути для каждой категории.
Для каждой категории в этой таблице хранится несколько записей, которые перечисляют всех её предков, включая её саму. Например, для категории "Смартфоны" (20), которая находится по пути "Электроника → Телефоны → Смартфоны", в таблице будут следующие записи:
category_id | path_id | level
------------|---------|------
20 | 15 | 0 -- (Электроника, уровень 0 относительно cat_id=20)
20 | 18 | 1 -- (Телефоны, уровень 1)
20 | 20 | 2 -- (Смартфоны, уровень 2 - сама категория)
Поле level указывает на то, на каком уровне от конечной категории находится предок. Уровень 0 всегда соответствует корневому предку в данном пути, а максимальный уровень - самой категории.
Такой подход позволяет очень быстро выбирать все товары из категории и всех её подкатегорий всего одним запросом с JOIN на эту таблицу, без использования рекурсивных запросов, которые могут быть медленными.
Пример SQL-запроса
Получить полный путь (всех предков) для категории с ID 25:
SELECT cp.path_id, c.parent_id, cd.name, cp.level
FROM oc_category_path cp
LEFT JOIN oc_category c ON (cp.path_id = c.category_id)
LEFT JOIN oc_category_description cd ON (cp.path_id = cd.category_id)
WHERE cp.category_id = 25
ORDER BY cp.level ASC;
Найти все товары, которые принадлежат категории с ID 34 или любой из её дочерних категорий:
SELECT DISTINCT p.*
FROM oc_product p
LEFT JOIN oc_product_to_category p2c ON (p.product_id = p2c.product_id)
LEFT JOIN oc_category_path cp ON (p2c.category_id = cp.category_id)
WHERE cp.path_id = 34;
Смотрите также
-
таблицу
oc_category,
которая хранит основную информацию о категориях -
таблицу
oc_category_description,
которая содержит локализованные названия и описания категорий -
таблицу
oc_product_to_category,
которая связывает товары с категориями