Graph-SQL

Граф состоит из узлов (вершин) и ребер (связей). Узлы - конкретные сущности, такие как человек (person) или автомобиль (car). Ребра соединяют узлы друг с другом. В данном примере два типа ребер: друзья (friends) и владелец (owner).

Узлы и ребра (связи) хранятся в таблицах. Связь owner представлена в виде простого поля Foreign Key (связь многие-к-одному). Связь многие-ко-многим friends представлена в виде таблицы специального типа EDGE (См. документ «Демонстрационная база данных»).

Представление графа в виде реляционных таблиц

Запросы

Graph-SQL - язык для выполнения графовых запросов, являющийся простым расширением SQL. Graph-SQL добавляет новое выражение MATCH.

Начнем с простого пример. Мы хотим найти всех людей имеющих автомобиль и у которых есть друзья имеющие автомобиль той же модели.

SELECT p1.name, p2.name as friendname, c1.model 
MATCH (car c1)-[owner]->(person p1)-[friends]->(person p2)<-[owner]-(car c2)
WHERE c1.model = c2.model

Выражение MATCH является паттерном для описания какие объекты и связи нам нужны для выполнения запроса. MATCH заменяет выражение FROM в SQL запросах. Остальные выражения: SELECT, WHERE, ORDER BY, GROUP BY, HAVING, INTO являются обычными выражениями SQL.

В данном примере выражение MATCH описывает что:

  • есть некий узел c1 типа car
  • c1 по связи owner ссылается на узел p1 типа person
  • p1 по связи friends ссылается на узел p2 типа person
  • c2 по связи owner ссылается на узел p2

Выражение WHERE добавляет условие c1.model = c2.model

На картинке ниже показан подграф удовлетворяющий данному запросу:

Результат запроса выглядит как и результат обычного SQL запроса SELECT.

name friendname model
John Sally Toyota

Простое выражение MATCH представляет цепочку узлов и связей. Но что делать если паттерн нельзя представить в виде простой цепочки? Например нам нужно указать несколько связей (больше двух) от узла p1. В этом случае мы можем добавить еще одно выражение MATCH.

SELECT p1.name, p2.name as friendname, c1.model 
MATCH (car c1)-[owner]->(person p1)-[friends]->(person p2)<-[owner]-(car c2)
MATCH (p1)-[friends]->(person p3)<-[owner]-(car c3)
WHERE c1.model = c2.model and c3.model = c1.model

Обратите внимание: во втором MATCH не указан тип узла p1 поскольку он уже был описан ранее.

Для удобства, вместо набора MATCH выражений (как в примере выше) можно все паттерны собрать под одним выражением MATCH, указав их через запятую (как в примере ниже).

SELECT p1.name, p2.name as friendname, c1.model 
MATCH (car c1)-[owner]->(person p1)-[friends]->(person p2)<-[owner]-(car c2),
      (p1)-[friends]->(person p3)<-[owner]-(car c3)
WHERE c1.model = c2.model and c3.model = c1.model

При поиске друзей может понадобиться ограничение на глубину поиска (друзья, друзья друзей, друзья друзей друзей и т.д.).

Стрелка -[friends]-> в выражении MATCH, представляющая ребро графа, может содержать дополнительные параметры глубины:

выражение комментарий
-[friends]-> глубина 1 (друзья)
-[friends 2]-> глубина 2 (друзья друзей)
-[friends 3]-> глубина 3 (друзья друзей друзей)

Дополнительный параметр глубины может указать, что вам нужны и все промежуточные узлы достижимые по связи от одной глубины до другой:

выражение комментарий
-[friends 2,3]-> глубина от 2 до 3 (друзья друзей + друзья друзей друзей)
-[friends 2,*]-> глубина от 2 до бесконечности (друзья друзей + друзья друзей друзей + ...)
-[friends *]-> аналогично -[friends 1,*]->

Найти всех друзей (а также друзей друзей и друзей друзей друзей) John-а живущих с ним в одном городе.

SELECT p1.name, p2.name as friendname
MATCH (person p1)-[friends 1..3]->(person p2)
WHERE p1.name = 'John' and p1.city = p2.city

Модификация данных графа

Создание структуры графа

Data Definition Language (DDL) - основные выражения для работы с графом

Запрос Комментарий
CREATE TABLE
DROP TABLE
Создание, удаление таблиц. Таблицы для ребер графа создаются с расширением AS EDGE.
ALTER TABLE Модификация схемы таблицы (добавление, удаление колонок и др.).
CREATE INDEX
DROP INDEX
Создание, удаление индексов. Вы также можете создать индекс для описания связи многие-к-одному для одного или нескольких полей (для создания связи типа foreign key но без объявления constrain)

Добавление или удаление данных

Data Manipulation Language (DML)

Запрос             Комментарий
INSERT
INSERT INTO
SELECT INTO
BULK INSERT
Добавление узлов графа и ребер не отличается от добавления записей в реляционные таблицы.
DELETE Удаление узлов и ребер графа.
UPDATE Модификация значений отдельных колонок записей.