Поддерживает ли Spanner какие-либо рекурсивные запросы?

Я создаю прототип в Google Cloud Spanner, и мне нужен способ выполнять рекурсивные запросы, как в PostgreSQL / SQLite, для обработки иерархических или графических данных. Я ищу синтаксис вроде https://sqlite.org/lang_with.html. Есть ли у Spanner способ выполнять подобные рекурсивные запросы или, может быть, хранимая процедура, такая как возможность выполнять там рекурсию? Я не могу найти синтаксис для общих табличных выражений.

Подробнее:

Ну, я моделирую ориентированные ациклические графы (DAG) в Spanner. Мне нужно будет поискать по графикам. Пример запроса: «найти все источники, подключенные к определенному узлу». Первая попытка моделирования графика в 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;

Использование чередующихся таблиц состоит в том, чтобы попытаться получить быстрый доступ к краям узла. Каждое уникальное ребро существует как в таблицах out_edges, так и in_edges.

Один из способов найти все источники, подключенные к определенному узлу в графе, - это выполнить DFS или BFS, начиная с этого узла и следуя по ребрам в обратном порядке, отслеживая узлы, у которых нет ребер, по мере их прохождения. . С этим представлением я могу думать о том, чтобы сделать это двумя способами: использовать рекурсивное общее табличное выражение (например, в SQLite или PostgreSQL или CONNECT BY в Oracle) или поддерживать транзитивное закрытие графа и соединять узлы без внутренних краев. с этими узлами в транзитивном замыкании, смежными с входным узлом. Последний будет работать в Spanner, но требует всего этого дополнительного хранилища и обслуживания переходного замыкания. И без какого-либо рекурсивного запроса я был бы ограничен поиском источников на фиксированном количестве ребер от входного узла. Я предполагаю, что другой способ сделать это в Spanner - это выполнить алгоритм поиска в клиентском коде. Проблема с этим может заключаться в потенциально большом количестве запросов к Spanner, чтобы удовлетворить исходный запрос.


person Jason Kapp    schedule 15.05.2019    source источник


Ответы (1)


Cloud Spanner не поддерживает рекурсивные запросы. Если вы предоставите дополнительную информацию о своем варианте использования, возможно, есть хорошее альтернативное решение.

https://cloud.google.com/spanner/docs/query-syntax

На основе дополнительного контекста:

Возможно, имеет смысл выполнить поиск в клиентском коде, в зависимости от ваших требований к задержке и формы / размера вашего графика. Подумайте, стоит ли поддерживать отдельную таблицу с чередованием, которая отслеживает источники для каждого узла. Этот подход может плохо обобщаться, в зависимости от формы графа и запросов, которые вы будете поддерживать.

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;
person Reid Hironaga    schedule 15.05.2019
comment
Спасибо, Рид. Я, вероятно, проведу несколько тестов, чтобы увидеть, как работают обходы в клиентском коде. - person Jason Kapp; 17.05.2019