PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Postgres Materialized Path - Quais são os benefícios de usar ltree?


TL;DR Rótulos reutilizáveis, padrões de pesquisa complexos e pesquisas de ancestralidade em vários nós descendentes (ou um único nó cujo caminho ainda não foi recuperado) não podem ser realizados usando um índice de caminho materializado.

Para os interessados ​​nos detalhes sangrentos...

Em primeiro lugar, sua pergunta só é relevante se você não estiver reutilizando nenhum rótulo na descrição do nó. Se fosse, a l-tree é realmente a única opção das duas. Mas as implementações de caminho materializado normalmente não precisam disso, então vamos deixar isso de lado.

Uma diferença óbvia será a flexibilidade nos tipos de buscas que o l-tree oferece. Considere estes exemplos (do ltree docs vinculados em sua pergunta):
foo         Match the exact label path foo
*.foo.*     Match any label path containing the label foo
*.foo       Match any label path whose last label is foo

A primeira consulta é obviamente alcançável com o caminho materializado. O último também é possível, onde você ajusta a consulta como uma pesquisa de irmãos. O caso do meio, no entanto, não é diretamente alcançável com uma única pesquisa de índice. Você teria que dividir isso em duas consultas (todos os descendentes + todos os ancestrais) ou recorrer a uma varredura de tabela.

E então existem consultas realmente complexas como esta (também dos documentos):
Top.*{0,2}.sport*@.!football|tennis.Russ*|Spain

Um índice de caminho materializado seria inútil aqui, e uma varredura completa da tabela seria necessária para lidar com isso. l-tree é a única opção se você quiser fazer isso como uma consulta SARGable.

Mas para as operações hierárquicas padrão, encontrar qualquer um dos seguintes:
  • pai
  • crianças
  • descendentes
  • nós raiz
  • nós de folha

caminho materializado funcionará tão bem quanto l-tree. Ao contrário do artigo vinculado acima , procurar todos os descendentes de um ancestral comum é muito factível usando uma b-tree. O formato de consulta WHERE path LIKE 'A.%' é SARGable desde que seu índice esteja preparado corretamente (eu tive que marcar explicitamente meu índice de caminho com varchar_pattern_ops para fazer isso funcionar).

O que está faltando nesta lista é encontrar todos os ancestrais para um descendente. O formato de consulta WHERE 'A.B.C.D' LIKE path || '.%' infelizmente não vai usar o índice. Uma solução que algumas bibliotecas implementam é analisar os nós ancestrais do caminho e consultá-los diretamente:WHERE id IN ('A', 'B', 'C') . No entanto, isso só funcionará se você estiver segmentando ancestrais de um nó específico cujo caminho você já recuperou. l-tree vai ganhar neste.