Partilhar via


Restrições de aresta

Aplica-se a: SQL Server 2019 (15.x) e versões posteriores Banco de Dados SQL do AzureInstância Gerenciada SQL do Azurebanco de dados SQL no Microsoft Fabric

As restrições de borda podem ser usadas para impor a integridade dos dados e semânticas específicas nas tabelas de borda no banco de dados gráfico do SQL Server.

Restrições de Aresta

Por padrão, as tabelas de aresta não impõem nada para os pontos finais da aresta. Ou seja, uma aresta num banco de dados gráfico pode conectar qualquer nó a qualquer outro nó, independentemente do tipo.

O SQL Graph oferece suporte a restrições de borda, que permitem que os usuários adicionem restrições às suas tabelas de borda, impondo semânticas específicas e também mantendo a integridade dos dados. Quando uma nova borda é adicionada a uma tabela de borda com restrições de borda, o Mecanismo de Banco de Dados impõe que os nós que a borda está tentando conectar existam nas tabelas de nós adequadas. Também é garantido que um nó não possa ser descartado, se alguma borda estiver fazendo referência a esse nó.

Cláusulas de restrição de borda

Uma restrição de aresta única consiste em uma ou mais cláusulas de restrição de aresta.

CONSTRAINT constraint_name CONNECTION (cause1[, clause2...])
  • Uma cláusula de restrição de borda é um par de nomes de tabela de nós, separados pela palavra-chave TO.
  • O primeiro nome de tabela na cláusula de restrição de borda é o nome da tabela de nó FROM para a relação de borda.
  • O segundo nome de tabela na cláusula de restrição de borda é o nome da tabela de nó TO para a relação de borda.
  • O par de nomes de tabela, portanto, indica a direção da relação de borda.
  • Como dito anteriormente, uma restrição de aresta pode conter uma ou mais cláusulas de restrição de aresta.

Múltiplas restrições e cláusulas

  • Várias restrições de borda, definidas para a mesma tabela de borda, são impostas com um operador AND.
  • Cláusulas de restrição de borda múltipla, definidas dentro da mesma restrição de borda, são aplicadas com um operador OR.

Considere os nós Supplier e Customer em seu gráfico. Cada um pode ser relacionado ao nó Product por meio de uma única tabela de arestas compartilhada: bought. A tabela de borda bought suporta Customer-(bought)->Product e Supplier-(bought)->Product tipos de relacionamento. Isto pode ser alcançado utilizando uma única restrição lateral com várias cláusulas de restrição associadas.

Exemplos
CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product)

O exemplo acima mostra uma restrição de aresta, com uma cláusula de restrição de aresta. Esta restrição suporta Customer-(bought)->Product. Ou seja, inserir uma relação de borda bought indo de um Customer para Product seria permitido. Se você tentar inserir qualquer outra combinação de nós, como Supplier-(bought)->Product, mesmo que possa descrever uma relação válida no mundo real, falharia.

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

O exemplo acima define uma restrição de aresta com duas cláusulas de restrição de aresta. Essas cláusulas de restrição permitem que a borda bought contenha relações Supplier-(bought)->Product ou Customer-(bought)->Product. A inserção de quaisquer outros tipos de relações de borda na tabela bought falharia.

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

O exemplo acima mostra duas restrições na mesma tabela de borda, com cada restrição de borda especificando uma cláusula de restrição. Nessa situação, o SQL só permitiria inserções que satisfizessem AMBAS as cláusulas de restrição de borda simultaneamente. Isso não é possível. Não há nenhum par de nós que possa satisfazer ambas as cláusulas de restrição de aresta. Essa combinação de restrição de borda torna a tabela de borda inutilizável.

Para obter uma explicação detalhada de onde várias restrições de borda podem ser usadas em um cenário da vida real, consulte o exemplo "Criando uma nova restrição de borda na tabela de borda existente, com nova cláusula de restrição de borda" mais adiante nesta página.

Índices em restrições de limite

Criar uma restrição de aresta não cria automaticamente um índice correspondente nas colunas $from_id e $to_id na tabela de aresta. A criação manual de um índice em um par $from_id, $to_id é recomendada se você tiver consultas de procura pontuais ou carga de trabalho OLTP.

ON DELETE ações referenciais em restrições de borda

As ações em cascata em uma restrição de borda permitem que os usuários definam as ações que o mecanismo de banco de dados executa quando um usuário exclui o(s) nó(s) que a borda determinada conecta. Podem ser definidas as seguintes ações referenciais: NENHUMA AÇÃO O mecanismo de banco de dados gera um erro quando você tenta excluir um nó que tem borda(s) de conexão.

CASCADE Quando um nó é excluído do banco de dados, as bordas de conexão são excluídas.

Trabalhar com restrições de borda

Você pode definir uma restrição de borda no SQL Server usando Transact-SQL. Uma restrição de borda pode ser definida somente em uma tabela de borda do gráfico. Para criar, eliminar ou modificar uma restrição de aresta, é necessário ter permissão ALTER na tabela.

Criar restrições de borda

Os exemplos a seguir mostram como criar uma restrição de borda em tabelas novas ou existentes.

Criar uma restrição de borda em uma nova tabela de borda

O exemplo a seguir cria uma restrição de aresta na tabela de arestas bought.

-- 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;

Definir ações referenciais em uma nova tabela de borda

O exemplo a seguir cria uma restrição de aresta na tabela de aresta bought e define a ação referencial 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;

Adicionar restrição de borda a uma tabela de borda existente

O exemplo a seguir usa ALTER TABLE para adicionar uma restrição de borda à tabela de borda bought.

-- 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);

Criar uma nova restrição de aresta na tabela de arestas existente, com cláusulas de restrição de aresta adicionais.

O exemplo a seguir usa o comando ALTER TABLE para adicionar uma nova restrição de borda com cláusulas de restrição de borda adicionais na tabela de borda 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;
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);

No exemplo anterior, há duas cláusulas de restrição de borda na restrição EC_BOUGHT1, uma que conecta Customer a Product e outra conecta Supplier a Product. Ambas as cláusulas são aplicadas em disjunção. Ou seja, uma dada aresta tem que satisfazer uma dessas duas cláusulas para ser permitida na tabela de arestas.

Criar uma nova restrição de aresta na tabela de arestas existente, com nova cláusula de restrição de aresta

O exemplo a seguir usa o comando ALTER TABLE para adicionar uma nova restrição de borda com uma nova cláusula de restrição de borda na tabela de borda 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;
GO
CREATE TABLE bought
  (
     PurchaseCount INT,
        CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product)
  )
  AS EDGE;
GO

No exemplo anterior, imagine que agora precisamos incluir também a relação de Supplier para Product, através da tabela de arestas bought. Você pode tentar adicionar uma nova restrição de aresta:

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

No entanto, adicionar uma nova restrição de borda não é a solução correta. Criamos duas restrições de borda separadas na tabela de borda bought, nomeadamente EC_BOUGHT e EC_BOUGHT1. Ambas as restrições de borda têm cláusulas de restrição de borda diferentes. Se uma tabela de arestas tiver mais de uma restrição de aresta, uma determinada aresta terá que satisfazer TODAS as restrições de aresta para ser permitida na tabela de arestas. Como nenhuma aresta pode satisfazer EC_BOUGHT e EC_BOUGHT1 aqui, a declaração ALTER TABLE acima falha caso exista pelo menos uma linha na tabela de arestas bought.

Para que essa restrição de borda seja criada com êxito, a maneira prescrita é seguir uma sequência como mostrado neste exemplo:

-- 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]';

O fato de termos adicionado a nova restrição de "superconjunto" primeiro sem descartar a anterior, permite que a operação seja uma operação somente de metadados - não precisa verificar todos os dados existentes na tabela bought, pois engloba a restrição existente.

Com isso, para que uma determinada aresta seja permitida na aresta bought, ela tem que satisfazer uma das cláusulas de restrição de aresta definidas na restrição EC_BOUGHT_NEW. Portanto, qualquer aresta que esteja tentando conectar os nós válidos Customer a Product ou Supplier a Product é permitida.

Excluir restrições de aresta

O exemplo a seguir identifica primeiro o nome da restrição de borda e, em seguida, exclui a restrição.

-- 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;

Modificar restrições de aresta

Para modificar uma restrição de borda usando Transact-SQL, você deve primeiro excluir a restrição de borda existente e, em seguida, recriá-la com a nova definição.

Visualizar restrições de borda

A visibilidade dos metadados nas visualizações de catálogo é limitada aos elementos seguros que um utilizador possui ou nos quais foi concedida permissão ao utilizador. Para obter mais informações, consulte Configuração de visibilidade de metadados.

O exemplo retorna todas as restrições de borda e suas propriedades para a tabela de borda bought no banco de dados tempdb.

-- 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');

Próximos passos