Типы графов GQL

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

В этой статье объясняется, как определить типы графов с помощью синтаксиса GQL, включая типы узлов, пограничные типы, ограничения и наследование.

Это важно

В этой статье исключительно используется пример графа социальных сетей.

Типы графов предоставляют несколько ключевых преимуществ:

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

Замечание

В этой статье представлены типы графов концептуально иллюстрируют их определение с помощью синтаксиса, определенного в стандарте GQL. Однако этот синтаксис сейчас не поддерживается непосредственно для графа.

Структурно тип графа определяет разрешенные типы узлов и типы ребер графов типа графа, а также дополнительные ограничения, которые дополнительно ограничивают эти графы.

Замечание

Определите типы графов с помощью набора типов узлов, пограничных типов и определений ограничений. Изменение порядка этих определений не изменяет тип графа, который вы определяете.

Определение типов узлов

Тип узла указывает, какие метки и типы свойств могут иметь узлы. Вот как указать базовый тип узла:

(:Organization => { 
  id :: UINT64 NOT NULL, 
  name :: STRING, 
  url :: STRING 
})

В этом примере создается тип узла, определяющий узлы со следующими параметрами:

  • Метка Organization.
  • Свойство id , которое содержит значения целого числа без знака и не может иметь значение NULL.
  • name Свойство, которое содержит строковые значения (может иметь значение NULL).
  • url Свойство, которое содержит строковые значения (может иметь значение NULL).

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

Замечание

В GQL NOT NULL является частью типа, который отличается от SQL.

Типы узлов также могут быть более сложными, с большими свойствами и типами данных:

(:Person => {
    id :: UINT64 NOT NULL,
    creationDate :: ZONED DATETIME,
    firstName :: STRING,
    lastName :: STRING,
    gender :: STRING,
    birthday :: UINT64,
    browserUsed :: STRING,
    locationIP :: STRING
})

Типы узлов с несколькими метками

Узлы могут иметь несколько меток для поддержки наследования и классификации. Можно указать несколько меток для типа узла, но одна метка (метка ключа) должна однозначно определить тип узла (если указана только одна метка, это будет ключевой меткой типа узла).

В качестве примера рассмотрим:

(:University => :Organization),

(:Company => :Organization)

University Здесь и Company являются ключевыми метками двух типов узлов, а в то время как Organization это вторичная метка, к которой относятся оба типа. Обратите внимание, что метка ключа и вторичные метки разделяются => в каждом типе узла. Этот подход создает иерархию типов, в которой как университеты, так и компании являются типами организаций.

Так как метки ключей определяют типы узлов, свойства типов узлов, определяемых вторичными метками, автоматически наследуются при использовании этого синтаксиса. Поэтому предыдущий синтаксис можно понять, чтобы эффективно определить следующие типы узлов:

(:University => :Organization {
  id :: UINT64 NOT NULL, 
  name :: STRING, 
  url :: STRING 
}),

(:Company => :Organization {
  id :: UINT64 NOT NULL, 
  name :: STRING, 
  url :: STRING 
})

Замечание

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

Экономия времени с помощью сочетаний клавиш наследования

Повторяющиеся метки и свойства из родительских типов узлов бывают емкими и подверженными ошибкам. Graph предоставляет оператор, += чтобы можно было указать только дополнительные (ненаследуемые) метки и типы свойств:

(:Post => :Message += {
    language :: STRING,
    imageFile :: STRING
})

Если дополнительные свойства не указаны, граф наследует все необходимые свойства от родительского типа:

(:Comment => :Message)  -- Same as: (:Comment => :Message += {})

Использование абстрактных типов узлов

Вы можете определить типы узлов исключительно для создания иерархий, даже если граф не содержит конкретных узлов этого типа. Абстрактные типы узлов полезны для создания концептуальных групп и наборов общих свойств. Для этого можно определить тип узла, как ABSTRACT в графе:

ABSTRACT (:Message => {
    id :: UINT64 NOT NULL,
    creationDate :: ZONED DATETIME,
    browserUsed :: STRING,
    locationIP :: STRING,
    content :: STRING,
    length :: UINT64
})

Абстрактные типы узлов недоступны для прямой загрузки графа. Они существуют только для структуры иерархии и определения общих свойств. Конкретные типы узлов, наследуемые от абстрактных типов, можно загрузить с данными.

Определение пограничных типов и семейств

Тип края определяет метку ключа, типы свойств и типы узлов конечной точки для ребер. В графовых базах данных ребра представляют соединения между узлами. Определение края сообщает системе, какие связи разрешены в графе:

(:Person)-[:knows { creationDate :: ZONED DATETIME }]->(:Person)

Этот тип края определяет все края с помощью:

  • Метка knows(ключ).
  • creationDate Свойство, которое содержит ZONED DATETIME значения (метки времени вместе со смещением часового пояса).
  • Начальная и целевая конечные точки, которые должны быть Person узлами.

Стрелка -> указывает направление края — от начала до цели. Эта направленная информация имеет решающее значение для понимания семантики графа.

Ниже приведены дополнительные примеры типов edge:

(:Person)-[:studyAt { classYear :: UINT64 }]->(:University)
(:Person)-[:workAt { workFrom :: UINT64 }]->(:Company)

Необходимо указать только метки ключей (PersonилиUniversityCompany) для типов узлов конечной точки. Вам не нужно повторять полное определение типа узла. Система разрешает эти ссылки на определения типа полного узла.

Семейства пограничных типов Graph

Метки ключей пограничных вычислений графа работают по-разному от меток ключей узла. Вы можете иметь несколько типов ребер с одной и той же меткой ключа в типе графа, если они имеют одинаковые метки и типы свойств. Однако два типа ребер с одной и той же меткой ключей должны отличаться по крайней мере в одном типе узла конечной точки. Набор пограничных типов с одной и той же меткой ключей — это семейство типов пограничных типов.

Эта концепция позволяет моделировать одинаковый тип отношений между различными типами сущностей.

Example:

(:City)-[:isPartOf]->(:Country),
(:Country)-[:isPartOf]->(:Continent)

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

Использование подтипизации узлов в определениях типов рёбер

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

Пример:

-- Node types
ABSTRACT (:Message { ... }),
(:Post => :Message { ... }),
(:Comment => :Message { ... }),

-- All edge types (x)-[:hasTag]->(:Tag) where x is at least a (:Message)
(<:Message)-[:hasTag]->(:Tag) 

Это определение неявно определяет следующие типы ребер:

(:Post)-[:hasTag]->(:Tag) 
(:Comment)-[:hasTag]->(:Tag) 

Поддерживаемые типы свойств

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

Используйте следующие типы данных для значений свойств:

  • INT (также: INT64)
  • UINT (также: UINT64)
  • STRING
  • BOOL (также: BOOLEAN)
  • DOUBLE (также: FLOAT64, FLOAT)
  • T NOT NULL, где T находится любой из предыдущих типов данных.
  • LIST<T> и LIST<T> NOT NULL, где T находится любой из предыдущих типов данных.

Полные сведения о типах значений см. в разделе "Значения GQL" и "Типы значений".

Это важно

Все типы свойств с одинаковым именем, которые происходят в типе узла или пограничном типе заданного типа графа, должны указывать один и тот же тип значения свойства. Единственное исключение: они могут отличаться в том, включают ли они значение NULL. Например, в соответствии с этим правилом, допустимый тип (:A { id :: STRING }), (:B { id :: STRING NOT NULL}) графа, а тип (:A { id :: STRING }), (:B { id :: INT}) графа с недопустимым.

Настройка ограничений ключа узла

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

Понимание ключевых ограничений имеет решающее значение, так как они:

  • Убедитесь, что уникальность: запретить повторяющиеся узлы на основе бизнес-логики.
  • Включите эффективные поиски: позволяет системе оптимизировать запросы, которые ищут определенные узлы.
  • Поддержка интеграции данных. Предоставление стабильного способа ссылки на узлы в разных источниках данных.

Это важно

Для графа одно ограничение ключа должно ограничивать каждый узел.

Как работают ограничения ключа узла

Ограничения ключа узла можно указать в типе графа. Каждое ограничение ключа узла имеет определенные характеристики, которые позволяют эффективно работать:

Компоненты ограничения ключа узла:

  • Имеет уникальное имя в типе графа для простой ссылки.
  • Определяет целевые узлы с помощью простого шаблона ограничения , указывающего, к каким узлам применяется ограничение.
  • Определяет свойства, которые образуют уникальное значение ключа.

Example:

CONSTRAINT person_pk
  FOR (n:Person) REQUIRE n.id IS KEY

Этот синтаксис создает ограничение ключа узла с именем person_pk для всех узлов по крайнейPerson мере меткой. Ограничение гарантирует, что каждый узел в графе однозначно определяется его id свойством. Не два узла с Person меткой могут иметь одно и то же id значение.

Можно также определить составные ключи, которые используют несколько свойств вместе, чтобы обеспечить уникальность с помощью синтаксиса CONSTRAINT ... FOR ... REQUIRE (n.prop1, n.prop2) IS KEY .

Это важно

Свойства, используемые в ограничениях ключей:

  • Не удается иметь значение NULL
  • Необходимо объявить как NOT NULL в типах узлов и граничных типах, предназначенных для ограничения ключа.