Ограничения границ

Область применения: SQL Server 2019 (15.x) и более поздних версий База данных SQL Azure Управляемый экземпляр SQL Azure

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

Ограничения ребер

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

Graph SQL поддерживает ограничения ребер, позволяющие пользователям добавлять ограничения к таблицам ребер, тем самым принудительно применяя определенную семантику и сохраняя целостность данных. При добавлении нового края в таблицу edge с ограничениями края ядро СУБД принудительно применяется, что узлы, которые ребра пытается подключить, существуют в соответствующих таблицах узлов. Он также гарантирует, что узел не может быть удален, если какой-либо край ссылается на этот узел.

Предложения ограничения ребер

Отдельное ограничение ребер состоит из одного или нескольких предложений ограничения ребер.

CONSTRAINT constraint_name CONNECTION (cause1[, clause2...])
  • Предложение ограничения ребер — это пара имен таблицы узлов, разделенная ключевым словом TO.
  • Первое имя таблицы в предложении ограничения ребер — это имя таблицы узла FROM для отношения ребер.
  • Второе имя таблицы в предложении ограничения ребер — это имя таблицы узла TO для отношения ребер.
  • То есть пара имен таблиц обозначает направление отношения ребер.
  • Как упоминалось ранее, ограничение ребер может содержать одно или несколько предложений ограничения ребер.

Несколько ограничений и предложений

  • Несколько ограничений ребер, определенных для одной таблицы ребер, применяются с помощью оператора AND.
  • Несколько предложений ограничений ребер, определенных в одном ограничении ребер, применяются с помощью оператора OR.

Рассмотрим узлы Supplier и Customer в вашем графе. Каждый из них может быть связан с узлом Product одной общей таблицы ребер: bought. Таблица ребер bought поддерживает типы отношений Customer-(bought)->Product и Supplier-(bought)->Product. Этого можно добиться с помощью одного ограничения ребер с несколькими предложениями ограничений ребер.

Примеры
CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product)

В примере выше приведено одно ограничение ребер с одним предложением ограничения ребер. Это ограничение поддерживает Customer-(bought)->Product. Это значит, что вставка отношения ребер bought из Customer в Product разрешена. Если вы пытаетесь вставить любое другое сочетание узлов, например Supplier-(bought)->Product, даже если оно может описать допустимую связь в реальном мире, завершится ошибкой.

CONSTRAINT EC_BOUGHT CONNECTION (Supplier TO Product, Customer TO Product)

В примере выше определено одно ограничение ребер с двумя предложениями ограничений ребер. Эти предложения ограничений позволяют ребру bought включать отношения Supplier-(bought)->Product или Customer-(bought)->Product. Вставка любых других типов отношений ребер в таблицу bought приведет к ошибке.

CONSTRAINT EC_BOUGHT1 CONNECTION (Supplier TO Product)
CONSTRAINT EC_BOUGHT2 CONNECTION (Customer TO Product)

В примере выше приведены два ограничения для одной таблицы ребер, при этом каждое ограничение ребер указывает одно предложение ограничения. В такой ситуации SQL будет разрешать только те операции вставки, которые одновременно удовлетворяют ОБЕИМ предложениям ограничений ребер. Это невозможно. Не существует пары узлов, которые могут удовлетворить оба предложения ограничений edge. Такое сочетание ограничений ребер приводит к тому, что таблицу ребер невозможно использовать.

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

Индексы для ограничений ребер

Создание ограничения edge не создает соответствующий индекс $from_id и $to_id столбцы в пограничной таблице. Рекомендуется создать индексы для пары $from_id и $to_id вручную, если имеются запросы на поиск точек или рабочая нагрузка OLTP.

Ссылочные действия ON DELETE для ограничений ребер

Каскадные действия для ограничений ребер позволяют пользователям определять действия, которые будет предпринимать ядро СУБД, когда пользователь удаляет узлы, соединяемые указанным ребром. Можно определить следующие ссылочные действия: NO ACTION. При попытке удалить узел с подключенными ребрами ядро СУБД вызывает ошибку.

CASCADE , когда узел удаляется из базы данных, подключающиеся ребра удаляются.

Работа с ограничениями пограничных вычислений

Ограничение границ в SQL Server можно определить с помощью Transact-SQL. Ограничение ребра можно задать только для таблицы ребер графа. Чтобы создать, удалить или изменить ограничение ребра, вам необходимо иметь разрешение ALTER для таблицы.

Создание ограничений ребер

В следующих примерах показано, как создать ограничение edge для новых или существующих таблиц.

Создание ограничения границ для новой пограничной таблицы

В следующем примере создается ограничение границ в bought таблице edge.

-- CREATE node and edge tables
CREATE TABLE Customer
   (
      ID INTEGER PRIMARY KEY
      ,CustomerName VARCHAR(100)
   )
AS NODE;
GO
CREATE TABLE Product
   (
      ID INTEGER PRIMARY KEY
      ,ProductName VARCHAR(100)
   )
AS NODE;
GO
CREATE TABLE bought
   (
      PurchaseCount INT
         ,CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product) ON DELETE NO ACTION
   )
   AS EDGE;

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

В следующем примере создается ограничение ребра в пограничной bought таблице и определяется действие ON DELETE CASCADE со ссылкой.

-- CREATE node and edge tables
CREATE TABLE Customer
   (
      ID INTEGER PRIMARY KEY
      ,CustomerName VARCHAR(100)
   )
AS NODE;
GO
CREATE TABLE Product
   (
      ID INTEGER PRIMARY KEY
      ,ProductName VARCHAR(100)
   )
AS NODE;
GO
CREATE TABLE bought
   (
      PurchaseCount INT
         ,CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product) ON DELETE CASCADE
   )
   AS EDGE;

Добавление ограничения edge в существующую таблицу edge

В следующем примере используется ALTER TABLE для добавления ограничения края в таблицу bought edge.

-- CREATE node and edge tables
CREATE TABLE Customer
   (
      ID INTEGER PRIMARY KEY
      , CustomerName VARCHAR(100)
   )
   AS NODE;
CREATE TABLE Product
   (
      ID INTEGER PRIMARY KEY
      , ProductName VARCHAR(100)
   )
   AS NODE;
GO
CREATE TABLE bought
   (
      PurchaseCount INT
   )
   AS EDGE;
GO
ALTER TABLE bought ADD CONSTRAINT EC_BOUGHT1 CONNECTION (Customer TO Product);

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

В следующем примере команда используется ALTER TABLE для добавления нового ограничения края с дополнительными предложениями ограничений edge в bought таблице edge.

-- CREATE node and edge tables
CREATE TABLE Customer
   (
      ID INTEGER PRIMARY KEY
      , CustomerName VARCHAR(100)
   )
   AS NODE;
GO
CREATE TABLE Supplier
   (
      ID INTEGER PRIMARY KEY
      , SupplierName VARCHAR(100)
   )
   AS NODE;
GO
CREATE TABLE Product
   (
      ID INTEGER PRIMARY KEY
      , ProductName VARCHAR(100)
   )
   AS NODE;
GO
CREATE TABLE bought
   (
      PurchaseCount INT
      , CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product)
   )
   AS EDGE;
-- Drop the existing edge constraint first and then create a new one.
ALTER TABLE bought DROP CONSTRAINT EC_BOUGHT;
GO
-- User ALTER TABLE to create a new edge constraint.
ALTER TABLE bought ADD CONSTRAINT EC_BOUGHT1 CONNECTION (Customer TO Product, Supplier TO Product);

В предыдущем примере в ограничении есть два предложения EC_BOUGHT1 ограничений edge, к которым подключается ProductCustomer и к другим подключениям SupplierProduct. Оба этих предложения применены в логическом сложении. То есть заданное ребро должно соответствовать любому из этих двух предложений, чтобы использоваться в таблице ребер.

Создание нового ограничения edge в существующей таблице edge с новым предложением ограничения edge

В следующем примере команда используется ALTER TABLE для добавления нового ограничения edge с новым предложением ограничения edge в bought таблице edge.

-- CREATE node and edge tables
CREATE TABLE Customer
  (
     ID INTEGER PRIMARY KEY
     , CustomerName VARCHAR(100)
  )
  AS NODE;
GO
CREATE TABLE Supplier
  (
     ID INTEGER PRIMARY KEY
     , SupplierName VARCHAR(100)
  )
  AS NODE;
GO
CREATE TABLE Product
  (
     ID INTEGER PRIMARY KEY
     , ProductName VARCHAR(100)
  )
  AS NODE;
GO
CREATE TABLE bought
  (
     PurchaseCount INT,
        CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product)
  )
  AS EDGE;
GO

Опираясь на приведенный выше пример, представьте, что теперь нам нужно включить связь Supplier с Product с помощью таблицы ребер bought. Вы можете попробовать добавить новое ограничение edge:

ALTER TABLE bought ADD CONSTRAINT EC_BOUGHT1 CONNECTION (Supplier TO Product);

Однако добавление нового ограничения edge не является правильным решением. Мы создали два отдельных ограничения ребер в пограничной bought таблице EC_BOUGHT и EC_BOUGHT1. Оба этих ограничения имеют различные предложения ограничения ребра. Если в таблице ребер присутствует более одного ограничения, данное ребро должно соответствовать ВСЕМ ограничениям, чтобы использоваться в таблице ребер. Так как ни один край не может удовлетворить оба EC_BOUGHTEC_BOUGHT1 и здесь, приведенный выше ALTER TABLE оператор завершается ошибкой, если в граничной bought таблице есть строки вообще.

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

-- First, add the desired ("super-set") constraint:
ALTER TABLE bought ADD CONSTRAINT EC_BOUGHT_NEW CONNECTION (Customer TO Product, Supplier TO Product);
GO

-- Then, drop the older edge constraint:
ALTER TABLE bought DROP CONSTRAINT EC_BOUGHT;
GO

-- If needed, you can rename the new edge constraint to match the original name:
EXECUTE sp_rename '[dbo].[EC_BOUGHT_NEW]', '[dbo].[EC_BOUGHT]';

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

При этом для разрешения заданного края в пограничном bought краю он должен удовлетворять любой из предложений ограничений края в EC_BOUGHT_NEW ограничении. Поэтому разрешено любое ребра, которое пытается подключиться к CustomerProduct узлам или Supplier к Product узлам.

Удаление ограничений ребер

В следующем примере сначала определяется имя ограничения ребер, а затем удаляется ограничение.

-- CREATE node and edge tables
CREATE TABLE Customer
   (
      ID INTEGER PRIMARY KEY
      , CustomerName VARCHAR(100)
   )
   AS NODE;
GO
CREATE TABLE Product
   (
      ID INTEGER PRIMARY KEY
      , ProductName VARCHAR(100)
   ) AS NODE;
GO
CREATE TABLE bought
   (
      PurchaseCount INT
      , CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product)
    )
    AS EDGE;
GO

-- Return the name of edge constraint.
SELECT name
   FROM sys.edge_constraints
   WHERE type = 'EC' AND parent_object_id = OBJECT_ID('bought');
GO

-- Delete the primary key constraint.
ALTER TABLE bought
DROP CONSTRAINT EC_BOUGHT;

Изменение ограничений ребер

Чтобы изменить ограничение ребра с помощью Transact-SQL, необходимо сначала удалить существующее ограничение края, а затем повторно создать его с новым определением.

Просмотр ограничений ребер

Видимость метаданных в представлениях каталога ограничена защищаемыми объектами, которыми владеет пользователь или которым пользователь получил некоторое разрешение. Дополнительные сведения см. в разделе Metadata Visibility Configuration.

В примере возвращаются все ограничения ребер и их свойства для пограничной tempdb таблицы bought в базе данных.

-- CREATE node and edge tables
CREATE TABLE Customer
   (
      ID INTEGER PRIMARY KEY
      , CustomerName VARCHAR(100)
   )
   AS NODE;
GO
CREATE TABLE Supplier
   (
      ID INTEGER PRIMARY KEY
      , SupplierName VARCHAR(100)
   )
   AS NODE;
   GO
CREATE TABLE Product
   (
      ID INTEGER PRIMARY KEY
      , ProductName VARCHAR(100)
   )
   AS NODE;

-- CREATE edge table with edge constraints.
CREATE TABLE bought
   (
      PurchaseCount INT
      , CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product, Supplier TO Product)
   )
   AS EDGE;

-- Query sys.edge_constraints and sys.edge_constraint_clauses to view
-- edge constraint properties.
SELECT
   EC.name AS edge_constraint_name
   , OBJECT_NAME(EC.parent_object_id) AS edge_table_name
   , OBJECT_NAME(ECC.from_object_id) AS from_node_table_name
   , OBJECT_NAME(ECC.to_object_id) AS to_node_table_name
   , is_disabled
   , is_not_trusted
FROM sys.edge_constraints EC
   INNER JOIN sys.edge_constraint_clauses ECC
   ON EC.object_id = ECC.object_id
WHERE EC.parent_object_id = object_id('bought');

Следующие шаги