Dados hierárquicos são um pouco irritantes em um banco de dados relacional (excluindo Oracle, que tem operadores em
START WITH/CONNECT BY
para lidar com isso). Existem basicamente dois modelos
:lista de adjacências e conjuntos aninhados. Você escolheu conjuntos de adjacência, que é o que eu normalmente faço também. É muito mais fácil mudar do que o modelo de conjunto aninhado, embora o modelo de conjunto aninhado possa ser recuperado na ordem correta em uma única consulta. As listas de adjacência não podem ser. Você precisará construir uma estrutura de dados intermediária (árvore) e depois convertê-la em uma lista.
O que eu faria (e fiz recentemente de fato) é:
- selecione todo o conteúdo do menu em uma consulta ordenada pelo ID do pai;
- Construa uma árvore da estrutura do menu usando arrays associativos ou classes/objetos;
- Ande nessa árvore para criar listas não ordenadas aninhadas; e
- Use um plug-in jQuery como Superfish para transformar essa lista em um menu.
Você constrói algo assim:
$menu = array(
array(
'name' => 'Home',
'url' => '/home',
),
array(
'name' => 'Account',
'url' => '/account',
'children' => array(
'name' => 'Profile',
'url' => '/account/profile',
),
),
// etc
);
e converta para isso:
<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>
...
O PHP para gerar a matriz de menu é razoavelmente simples, mas um pouco complicado de resolver. Você usa uma função de caminhada em árvore recursiva que cria a marcação de lista aninhada HTML, mas deixará sua implementação como um exercício para o leitor. :)