Estrutura de banco de dados para estrutura de dados em árvore


151

Qual seria a melhor maneira de implementar uma estrutura de dados de árvore personalizável (ou seja, uma estrutura em árvore com um número desconhecido de nível) em um banco de dados?

Eu fiz isso uma vez antes de usar uma tabela com uma chave estrangeira para si mesma.

Que outras implementações você pôde ver e essa implementação faz sentido?



SQL Server (desde 2008) oferece o tipo de dados hierarchyid
BornToCode

Respostas:


80

Você mencionou o mais comumente implementado, que é a Lista de Adjacências: https://blogs.msdn.microsoft.com/mvpawardprogram/2012/06/25/hierarchies-convert-adjacency-list-to-nested-sets

Também existem outros modelos, incluindo caminho materializado e conjuntos aninhados: http://communities.bmc.com/communities/docs/DOC-9902

Joe Celko escreveu um livro sobre esse assunto, que é uma boa referência de uma perspectiva geral do SQL (isso é mencionado no link do artigo do conjunto aninhado acima).

Além disso, Itzik Ben-Gann tem uma boa visão geral das opções mais comuns em seu livro "Por dentro do Microsoft SQL Server 2005: consulta T-SQL".

As principais coisas a considerar ao escolher um modelo são:

1) Frequência da mudança de estrutura - com que frequência a estrutura real da árvore é alterada. Alguns modelos fornecem melhores características de atualização da estrutura. É importante separar as alterações de estrutura de outras alterações de dados. Por exemplo, você pode modelar o organograma da empresa. Algumas pessoas modelarão isso como uma lista de adjacência, usando o ID do funcionário para vincular um funcionário ao supervisor. Geralmente, essa é uma abordagem abaixo do ideal. Uma abordagem que geralmente funciona melhor é modelar a estrutura organizacional separada dos próprios funcionários e manter o funcionário como um atributo da estrutura. Dessa forma, quando um funcionário sai da empresa, a estrutura organizacional em si não precisa ser alterada, apenas a associação com o funcionário que saiu.

2) A árvore é pesada para gravação ou leitura - algumas estruturas funcionam muito bem ao ler a estrutura, mas incorrem em sobrecarga adicional ao gravar na estrutura.

3) Quais tipos de informações você precisa obter da estrutura - algumas estruturas se destacam por fornecer certos tipos de informações sobre a estrutura. Os exemplos incluem encontrar um nó e todos os seus filhos, encontrar um nó e todos os seus pais, encontrar a contagem de nós filhos que atendem a determinadas condições etc. Você precisa saber quais informações serão necessárias a partir da estrutura para determinar a estrutura que melhor se adequará suas necessidades.


Olá, estou enfrentando exatamente o mesmo problema indicado na pergunta e gostaria de fazer uma pergunta sobre os tópicos acima. Considerando uma estrutura como no tópico número um (tabela estruturada organizacional (não estruturada para funcionários) com ParentId referenciado na mesma tabela), preciso definir quem é o chefe de uma determinada área. Atribuirei todos os funcionários dessa área específica diretamente a ela. Onde você colocaria o chefe dessa área específica? Dentro da mesma área ou um gorup acima? Minha abordagem é referenciá-lo ao grupo acima, o que me dá uma estrutura melhor, eu acho. Obrigado.
Marcos Buarque

1
O primeiro link parece estar quebrado.
Jorge Leitao 23/10

Excelente resposta. Obrigado @JeremyDWill!
precisa saber é

56

Dê uma olhada em Gerenciando dados hierárquicos no MySQL . Ele discute duas abordagens para armazenar e gerenciar dados hierárquicos (em forma de árvore) em um banco de dados relacional.

A primeira abordagem é o modelo de lista de adjacência, que é basicamente o que você descreve: ter uma chave estrangeira que se refere à própria tabela. Embora essa abordagem seja simples, pode ser muito ineficiente para determinadas consultas, como a construção de toda a árvore.

A segunda abordagem discutida no artigo é o modelo de conjunto aninhado. Essa abordagem é muito mais eficiente e flexível. Consulte o artigo para obter explicações detalhadas e consultas de exemplo.


seu link tem um tópico muito interessante sendo discutido. obrigado!
Fritz

9

Se você precisar usar o Relational DataBase para organizar a estrutura de dados em árvore, o Postgresql possui um módulo ltree legal que fornece um tipo de dados para representar rótulos de dados armazenados em uma estrutura hierárquica em forma de árvore. Você pode obter a idéia de lá (para mais informações, consulte: http://www.postgresql.org/docs/9.0/static/ltree.html )

Em geral, o LDAP é usado para organizar registros na estrutura hierárquica.


2

Ter uma mesa com uma chave estrangeira para si faz sentido para mim.

Em seguida, você pode usar uma expressão de tabela comum no SQL ou a instrução connect by anterior no Oracle para construir sua árvore.


Eu tenho uma tabela de log, com uma coluna de identidade LogID e uma coluna ParentLogID com um FK que aponta para a coluna LogID. Quando a primeira linha do log de uma transação é gravada, eu pego SCOPE_IDENTITY (). Todos os outros registros de log são gravados com esse valor na coluna ParentLogID. Isso é realmente útil para agrupar linhas que pertencem juntas. É a única maneira real de ver o que aconteceu, sem isso, seria uma enorme bagunça de linhas de log de várias transações, todas misturadas.
KM.

@KM - Ele disse que "faz sentido" não "não faz sentido"
John Rasch


1

Eu usei a seguinte implementação no SQL SERVER 2005. Verifique aqui


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.