Spanner 是否支持某种递归查询?
Does Spanner support recursive queries of some kind?
我正在 Google Cloud Spanner 中制作原型,我需要一种方法来执行递归查询,就像在 PostgreSQL / SQLite 中处理分层或图形数据一样。我正在寻找 https://sqlite.org/lang_with.html 之类的语法。 Spanner 是否有办法执行这样的递归查询,或者是否有类似存储过程的能力来执行递归?我找不到常见 table 表达式的语法。
更多详情:
嗯,我正在 Spanner 中为有向无环图 (DAG) 建模。我需要对图表进行搜索。一个示例查询是:"find all the sources connected to a specific node." 在 Spanner 中对图形建模的第一次尝试如下:
CREATE TABLE nodes (
node_id INT64 NOT NULL,
node_label String(1024) NOT NULL,
name String(1024)
) PRIMARY KEY (node_id);
CREATE TABLE out_edges (
node_id INT64 NOT NULL,
to_node_id INT64 NOT NULL,
edge_label String(1024) NOT NULL,
) PRIMARY KEY (node_id, to_node_id),
INTERLEAVE IN PARENT nodes ON DELETE CASCADE;
CREATE TABLE in_edges (
node_id INT64 NOT NULL,
from_node_id INT64 NOT NULL,
edge_label String(1024) NOT NULL,
) PRIMARY KEY (node_id, from_node_id),
INTERLEAVE IN PARENT nodes ON DELETE CASCADE;
使用interleaved tables是为了尝试实现快速访问节点的边缘。 out_edges
和 in_edges
table 中都存在每个唯一边。
在图中找到连接到特定节点的所有源的一种方法是从该节点开始执行 DFS 或 BFS,并以相反的顺序跟随边缘,同时跟踪没有任何节点的节点遍历时的边。通过这种表示,我可以想到的两种方法是使用递归通用 table 表达式(就像在 SQLite 或 PostgreSQL 或 Oracle 中的 CONNECT BY 中一样)或维护图的传递闭包并连接节点与输入节点相邻的传递闭包中的那些节点没有入边。后者可以在 Spanner 中工作,但需要所有额外的存储和维护传递闭包。如果没有某种递归查询,我将仅限于查找距输入节点固定数量的边的源。我想在 Spanner 中实现这一点的另一种方法是在客户端代码中执行搜索算法。这样做的问题是可能会向 Spanner 发出大量查询以满足原始查询。
Cloud Spanner 不支持递归查询。如果您提供有关您的用例的更多信息,则可能有一个很好的替代解决方案。
https://cloud.google.com/spanner/docs/query-syntax
基于额外的上下文:
根据您的延迟要求和图形的 shape/size,在客户端代码中进行搜索可能有意义。考虑维护一个单独的交错 table 来跟踪每个节点的源是否值得。这种方法可能无法很好地概括,具体取决于您将支持的图形形状和查询。
CREATE TABLE sources (
node_id INT64 NOT NULL,
source_node_id INT64 NOT NULL,
) PRIMARY KEY (node_id, source_node_id),
INTERLEAVE IN PARENT nodes ON DELETE CASCADE;
我正在 Google Cloud Spanner 中制作原型,我需要一种方法来执行递归查询,就像在 PostgreSQL / SQLite 中处理分层或图形数据一样。我正在寻找 https://sqlite.org/lang_with.html 之类的语法。 Spanner 是否有办法执行这样的递归查询,或者是否有类似存储过程的能力来执行递归?我找不到常见 table 表达式的语法。
更多详情:
嗯,我正在 Spanner 中为有向无环图 (DAG) 建模。我需要对图表进行搜索。一个示例查询是:"find all the sources connected to a specific node." 在 Spanner 中对图形建模的第一次尝试如下:
CREATE TABLE nodes (
node_id INT64 NOT NULL,
node_label String(1024) NOT NULL,
name String(1024)
) PRIMARY KEY (node_id);
CREATE TABLE out_edges (
node_id INT64 NOT NULL,
to_node_id INT64 NOT NULL,
edge_label String(1024) NOT NULL,
) PRIMARY KEY (node_id, to_node_id),
INTERLEAVE IN PARENT nodes ON DELETE CASCADE;
CREATE TABLE in_edges (
node_id INT64 NOT NULL,
from_node_id INT64 NOT NULL,
edge_label String(1024) NOT NULL,
) PRIMARY KEY (node_id, from_node_id),
INTERLEAVE IN PARENT nodes ON DELETE CASCADE;
使用interleaved tables是为了尝试实现快速访问节点的边缘。 out_edges
和 in_edges
table 中都存在每个唯一边。
在图中找到连接到特定节点的所有源的一种方法是从该节点开始执行 DFS 或 BFS,并以相反的顺序跟随边缘,同时跟踪没有任何节点的节点遍历时的边。通过这种表示,我可以想到的两种方法是使用递归通用 table 表达式(就像在 SQLite 或 PostgreSQL 或 Oracle 中的 CONNECT BY 中一样)或维护图的传递闭包并连接节点与输入节点相邻的传递闭包中的那些节点没有入边。后者可以在 Spanner 中工作,但需要所有额外的存储和维护传递闭包。如果没有某种递归查询,我将仅限于查找距输入节点固定数量的边的源。我想在 Spanner 中实现这一点的另一种方法是在客户端代码中执行搜索算法。这样做的问题是可能会向 Spanner 发出大量查询以满足原始查询。
Cloud Spanner 不支持递归查询。如果您提供有关您的用例的更多信息,则可能有一个很好的替代解决方案。
https://cloud.google.com/spanner/docs/query-syntax
基于额外的上下文:
根据您的延迟要求和图形的 shape/size,在客户端代码中进行搜索可能有意义。考虑维护一个单独的交错 table 来跟踪每个节点的源是否值得。这种方法可能无法很好地概括,具体取决于您将支持的图形形状和查询。
CREATE TABLE sources (
node_id INT64 NOT NULL,
source_node_id INT64 NOT NULL,
) PRIMARY KEY (node_id, source_node_id),
INTERLEAVE IN PARENT nodes ON DELETE CASCADE;