3 ms·
It doesn't handle all cases or all queries, but one method I've used to deal with graph data in relational databases it to materialize paths and cache them on t
by claytongulick 4y ago
It doesn't handle all cases or all queries, but one method I've used to deal with graph data in relational databases it to materialize paths and cache them on the node (this only really works well with DAGs).
So, the path key could look something like: bob.ted.lisa.bill (obviously, use ids instead of names here)
Then you can index this in various ways to make LIKE queries fast.
Want do know anyone that rolls up to ted?
select * from blah where path like 'bob.ted%'
Or, how many people report to ted, but aren't under lisa?
select count(*) from blah where path like 'bob.ted%' and path not like 'bob.ted.lisa%'
And something a bit more complex that would typically be considered the domain of a graph database, like "What are the average number of direct reports each manager in my organization has?"
select name, avg((select count(*) from blah as sub where path like '%' || name || '%' and (array_position(string_to_array(path,'.'), name) = ((array_position(string_to_array(path,'.'), sub.name) - 1))
So, even with that degree of complexity, you're still avoiding recursion, though you might be getting into O(n^2) territory if you don't have an index that will handle '%' || ... || '%' well. You can expand on this with various techniques depending on the application.
It's certainly no replacement for a graph database, but for basic stuff it's very fast, handles huge volumes, and doesn't rely on any sort of recursion at the database layer (unless you materialize in a trigger or something).
The actual materialization code can be tricky, one technique to deal with that is to use the author's technique or something similar to have a recursive CTE in a view. When a graph change is made, you can scope the change based on the path's hierarchy and update the paths from the recursive view, that way you only hit the performance penalty at write time, not read.