Таблица 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), которая находится по пути "Электроника → Телефоны → Смартфоны", в таблице будут следующие записи:

sqlcategory_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:

sqlSELECT 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 или любой из её дочерних категорий:

sqlSELECT 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,
    которая связывает товары с категориями