Others have already pointed out the issues of cycles.
Others have already pointed out the issues of cycles.
> The solution is to build and index denormalized n-th order relationship tables.
This sounds much more performant but also more difficult to maintain.
Obviously maintaining a flattened version is going to perform better in queries, but you're trading maintenance (write) time for query time. Or materialization time if you decide to do it lazily.
A->B
A->D
B->C
C->D
Postgres will walk both paths from A to D in the recursive CTE and then you can filter them afterwards to keep only the shortest.
You can use aggregate functions within the recursive CTE, so you can’t GROUP BY your starting node and stop once you find the first path. There isn’t a way to compare across multiple paths or iterations of the for-loop.
If I'm traversing ancestors (let's say) until I find one that doesn't satisfy a condition, it'll bail out then. I get that this doesn't serve all uses cases, but it isn't a small thing either.
I myself build transitive closure tables that I update incrementally as needed (sometimes in a deferred way), so that many of the recursive queries I do can be very fast, but I only build transitive closures for the smallest portion I can (basically group nesting).
What do you consider large ? We have a 12-year old telco application with a few million objects in Neo4J, doing fault impact calculations... Would PostgreSQL handle that easily nowadays ?
https://gist.github.com/simonw/c16ce01244760e186a3a0aa3fee04...
Then I ran that query again and it seems to return results in about 80ms:
https://lite.datasette.io/?sql=https://gist.github.com/simon...
Can you elaborate on this?
Does an n-th order relationship table contain all the nodes reachable from some node going through n edges?
And you'd have one such table for each integer in the range 2..n?
I've found recursive queries to be difficult to scale in real-world queries past a few million edge nodes. We've denormalized several tree relationships so that the edge is connected both to its parent and to the root of its tree in several cases.
I'm using recursive algorithm on Postgres to find trees in a graph, but only where I'm specificaly interested in all of the nodes.