segunda-feira, 28 de novembro de 2011

Sobre como montar árvores armazenadas em bancos de dados relacionais

Sumário: Neste post vou falar sobre como montar a árvore de relacionamentos de uma estrutura hierárquica armazenada em uma tabela de um banco de dados relacional, e em seguida aplicar isso na exibição de um select(html) onde os relacionamentos entre pais e filhos são demonstrados. Download de código de exemplo no final do post.

Em um projeto que ajudo a desenvolver no trabalho, um CMS, temos uma tabela no banco de dados chamada Páginas. Esta tabela armazena informações sobre as página de um site, estas páginas indicam cada local de conteúdo de um site, como Home, Busca, Notícias, etc. Acontece que as páginas são inter-relacionadas, ou seja, a página Home pode ser pai da página Notícias e a página Notícias pode ser pai da página Destaques. A estrutura simplificada da tabela Página é a seguinte:
Tabela Páginas
id nome id_pagina_pai

1

Home

null

2

Notícias

1

3

Destaques

2

4

Busca

1

5

Menu

null

Como vocês podem ver a coluna id_pagina_pai é uma referência a coluna id da mesma tabela, por exemplo, olhando no registros da tabela podemos ver que a página Destaques é filha de Notícias.

Este tipo de estrutura hierárquica é muito comum em muitos softwares e sistemas e no dia-a-dia como relações familiares, grupos e sub-grupos, sistemas de arquivos com suas pastas e sub-pastas e muitos outros. Acontece que bancos de dados relacionais não são as melhores ferramentas para armazenar e manipular estes tipos de informações. Por exemplo, como faríamos para exibir a estrutura da tabela de Páginas mostrada acima em um select html da seguinte forma?:



No código exemplo que pode ser obtido abaixo eu demonstro a forma que eu encontrei para fazer isso. Provavelmente não é a melhor forma, mas resolveu meu caso muito bem. Só lembrando que em bancos de dados como Oracle e Postgre existem recursos como queries recursivas que ajudam na hora de manipular dados hierárquicos. No exemplo estou usando o banco de dados Mysql.

A Função que faz a Mágica
O principal trecho do código é função create_pool_tree, reproduzida abaixo:


Esta função basicamente cria toda a árvore que está armazenada na tabela paginas usando referências dentro de um array. Um pouco difícil de entender? Vamos por partes:

O primeiro foreach do código basicamente pega todas as páginas e as coloca em um array com uma estrutura pré-preparada. A imagem abaixo vai ilustrar o processo tomando como exemplo os dados da tabela Páginas acima:
Array $pool

Cada quadrado destes é um elemento do array $pool. Os nomes Home1, Noticias2, Destaques3, Busca4 e Menu5 são os índices. O índice pagina dentro de cada item é o objeto pagina. E filhas é um array vazio por enquanto.

O próximo foreach vai criar referências onde cada item de $pool vai ser referenciado por uma referência no array filhas de seu pai que também está em $pool. Complicado? A figura abaixo deve ajudar:
Array $pool com as refrências.

Vejam que todos os elementos estão no array e como as referências nos permitem saber a estrutura da árvore. Observem como Home e Menu não são referenciados por ninguém, o que significa que são os nós raízes da árvore.

O link para download do código exemplo está logo abaixo. São apenas dois arquivos, um de código php e outro com o banco de dados exemplo. Acho que o código não deve ser muito difícil de se adaptar para as necessidades de cada um. Qualquer dúvida, sugestão ou crítica sou todo ouvidos.


segunda-feira, 14 de novembro de 2011

Mais um pequeno Jogo que desenvolvi - DarkMatters

Link para o jogo

ScreenShot:


Um pequeno jogo desenvolvido usando Flixel e a biblioteca Flixel Power Tools, usada pelo método de colisão usando a transparência dos sprites. Devo dizer que demorei muito mais tempo do que eu imaginava para finalizar este game, e é um jogo bem simples, mesmo!