Иерархические данные несколько раздражают в реляционной базе данных (исключая Oracle, у которого есть операторы в START WITH/CONNECT BY
для решения этой проблемы). В основном две модели : список смежности и вложенные множества.
Вы выбрали наборы смежности, что я обычно и делаю. Это гораздо проще изменить, чем модель с вложенным набором, хотя модель с вложенным набором может быть получена в правильном порядке в одном запросе. Списки смежности быть не может. Вам нужно будет построить промежуточную структуру данных (дерево) и затем преобразовать ее в список.
Что бы я сделал (и на самом деле сделал недавно):
- выбрать все содержимое меню в одном запросе, упорядоченное по родительскому идентификатору;
- Построить дерево структуры меню, используя ассоциативные массивы или классы / объекты;
- Пройдите по этому дереву, чтобы создать вложенные неупорядоченные списки; и
- Используйте плагин jQuery, например Superfish , чтобы превратить этот список в меню.
Вы строите что-то вроде этого:
$menu = array(
array(
'name' => 'Home',
'url' => '/home',
),
array(
'name' => 'Account',
'url' => '/account',
'children' => array(
'name' => 'Profile',
'url' => '/account/profile',
),
),
// etc
);
и преобразовать его в это:
<ul class="menu">;
<li><a href="/">Home</a></li>
<li><a href="/account">Account Services</a>
<ul>
<li><a href="/account/profile">Profile</a></li>
...
PHP для генерации массива меню достаточно прост, но немного сложен для решения. Вы используете рекурсивную функцию обхода дерева, которая создает разметку вложенного списка HTML, но оставит ее реализацию в качестве упражнения для читателя. :)