У меня есть таблица в моей базе данных, где я храню древовидную структуру, используя модель гибридного вложенного набора (MPTT) (модель со значениями lft
и rght
) и модель списка смежности (сохраняя parent_id
в каждый узел).
my_table (id, parent_id, lft, rght, alias)
Этот вопрос не относится ни к одному из аспектов дерева MPTT, но я подумал, что оставлю его на всякий случай, если у кого-нибудь есть хорошая идея о том, как использовать это.
Я хочу преобразовать путь псевдонимов в конкретный узел. Например: "users.admins.nickf"
найдет узел с псевдонимом «nickf», который является дочерним по отношению к псевдониму «admin», который является дочерним по отношению к «users», который находится в корне. На (parent_id, alias)
.
существует уникальный индекс
Я начал с написания функции, чтобы она разделяла путь на части, а затем запрашивал базу данных один за другим:
SELECT `id` FROM `my_table` WHERE `parent_id` IS NULL AND `alias` = 'users';-- 1
SELECT `id` FROM `my_table` WHERE `parent_id` = 1 AND `alias` = 'admins'; -- 8
SELECT `id` FROM `my_table` WHERE `parent_id` = 8 AND `alias` = 'nickf'; -- 37
Но потом я понял, что могу сделать это с помощью одного запроса, используя переменное количество вложений:
SELECT `id` FROM `my_table` WHERE `parent_id` = (
SELECT `id` FROM `my_table` WHERE `parent_id` = (
SELECT `id` FROM `my_table`
WHERE `parent_id` IS NULL AND `alias` = 'users'
) AND `alias` = 'admins'
) AND `alias` = 'nickf';
Поскольку количество подзапросов зависит от количества шагов в пути, я столкнусь с проблемами, связанными с слишком большим количеством подзапросов ? (Если и есть такая вещь)
Существуют ли лучшие / более умные способы выполнения этого запроса?