Estou estudando travessia de grafos usando CTEs recursivas (curso learnSQL). A questão pergunta sobre visitar cada cidade a partir de uma cidade inicial. Eles usam uma string "path" construída a partir de nomes de cidades anexados e, em seguida, usam where position(city.name IN travel.path) = 0
para verificar se a cidade já foi visitada. Isso funciona, mas costumo procurar alternativas e poderia usar um array de cidades visitadas.
Como um desenvolvedor experiente (por exemplo, Java, mas qualquer linguagem imperativa), eu representaria visited
como um SET para testes de contenção eficientes, mas o postgresql parece oferecer apenas ARRAY.
- Existe um tipo SET (algo simples, não uma tabela separada ou conjunto JSON) que eu possa usar?
- O ARRAY é eficiente em termos de pesquisa?
Os dados de exemplo são, claro, minúsculos e não representam um problema, mas gostaria de saber o que é mais eficiente/melhor prática. Na minha opinião, a consulta por string position
não é muito semântica .
Obrigado!
with recursive
travel(path, visited, visited_count) AS (
select
name::text,
array[name::text],
1
from city
where
name = 'Bristol'
union all
select
travel.path || '->' || city.name,
visited || name::text,
visited_count + 1
from city, travel
where
city.name <> all(visited)
--position(city.name IN travel.path) = 0
)
select
path,
visited
from travel
where
visited_count = 6
Use a
ARRAY
abordagem para clareza semântica, pois tanto as verificações de matriz (<> ALL
) quanto as pesquisas de string (position()) têm desempenho de pesquisa O(N) semelhante dentro da etapa recursiva.