Restrições do Microsoft Edge

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

É possível usar restrições de borda para impor a integridade dos dados e uma semântica específica às tabelas de borda no banco de dados de gráfico do SQL Server.

Restrições de borda

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

O SQL Graph dá suporte a restrições de borda, que permitem aos usuários adicionar restrições a suas tabelas de borda, imponto assim uma semântica específica e 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ó adequadas. Também é garantido que um nó não possa ser removido se alguma borda estiver referenciando esse nó.

Cláusulas de restrição de borda

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

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

Várias 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.
  • Várias cláusulas de restrição de borda, definidas dentro da mesma restrição de borda, são impostas com um operador OR.

Considere os nós Supplier e Customer em seu gráfico. Cada um pode estar relacionado ao Product nó por uma única tabela de borda compartilhada: \bought. A tabela de borda bought dá suporte aos tipos de relação Customer-(bought)->Product e Supplier-(bought)->Product. Isso pode ser feito usando uma única restrição de borda com várias cláusulas dessa restrição.

Exemplos
CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product)

O exemplo acima mostra uma restrição de borda com essa cláusula de restrição. Essa restrição dá suporte a Customer-(bought)->Product. Ou seja, a inserção de uma relação de borda bought que vai de um Customer para Productseria permitida. 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 borda com duas cláusulas dessa restrição. Essas cláusulas de restrição permitem que a borda bought contenha relacionamentos Supplier-(bought)->Product ou Customer-(bought)->Product. A inserção de 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 especificando uma cláusula relacionada. Nessa situação, o SQL permitirá apenas inserções que atendam a 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 atender a ambas as cláusulas de restrição de borda. 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, confira o exemplo em "Criando uma nova restrição de borda em uma tabela de borda existente com uma nova cláusula de restrição de borda" mais adiante nesta página.

Índices em restrições de borda

Criar uma restrição de borda não cria automaticamente um índice correspondente nas colunas $from_id e $to_id da tabela de borda. Criar manualmente um índice em um par $from_id, $to_id é recomendado se você tem consultas de pesquisa de ponto ou carga de trabalho de OLTP.

Ações referenciais ON DELETE 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 usa quando um usuário exclui os nós que a borda especificada conecta. As seguintes ações referenciais podem ser definidas: NO ACTION O mecanismo de banco de dados gera um erro quando você tenta excluir um nó que tem bordas de conexão.

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

Trabalho com restrições de borda

É possível definir uma restrição de borda no SQL Server usando o Transact-SQL. É possível definir uma restrição de borda apenas em uma tabela de borda do gráfico. Para criar, excluir ou modificar uma restrição de borda, você deve ter a permissão ALTER para a tabela.

Criar restrições de borda

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

Para criar uma restrição de borda em uma nova tabela de borda

O exemplo a seguir cria uma 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 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 borda na tabela de borda 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 uma 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 borda na tabela de borda existente com cláusulas adicionais de restrição de borda

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 a outra que conecta Supplier a Product. Essas duas cláusulas são aplicadas em disjunção. Ou seja, uma determinada borda precisa satisfazer uma dessas duas cláusulas para ser permitida na tabela de borda.

Criar uma nova restrição de borda na tabela de borda existente com uma nova cláusula de restrição de borda

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 também precisamos incluir a relação de Supplier para Product por meio da tabela de borda bought. Você pode tentar adicionar uma nova restrição de borda:

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, EC_BOUGHT e EC_BOUGHT1. Essas duas restrições de borda têm cláusulas de restrição de borda diferentes. Se uma tabela de borda tiver mais de uma restrição de borda, uma determinada borda precisará satisfazer TODAS as restrições para ser permitida na tabela de borda. Como nenhuma borda será capaz de satisfazer EC_BOUGHT e EC_BOUGHT1 aqui, a instrução ALTER TABLE acima falhará se houver linhas na tabela de borda bought.

Para que essa restrição de borda seja criada com êxito, a maneira prescrita é seguir uma sequência como a mostrada 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 que adicionamos a nova restrição "super-set" primeiro sem remover a anterior permite que a operação seja somente de metadados – ela não precisa verificar todos os dados existentes na tabela bought, pois abrange a restrição existente.

Com isso, para que uma determinada borda seja permitida na borda bought, ela precisará atender a qualquer uma das cláusulas de restrição de borda na restrição EC_BOUGHT_NEW. Portanto, qualquer borda que esteja tentando se conectar Customer válida a Product ou Supplier a nós Product, é permitida.

Excluir restrições de borda

O exemplo a seguir primeiro identifica o nome da restrição de borda e depois 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 borda

Para modificar uma restrição de borda usando o Transact-SQL, exclua primeiramente a restrição de borda existente e, em seguida, recrie-a com a nova definição.

Exibir restrições de borda

A visibilidade dos metadados em exibições do catálogo está limitada aos protegíveis que pertencem a um usuário ou para os quais o usuário recebeu permissão. Para obter mais informações, consulte Metadata Visibility Configuration.

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óximas etapas