Restrições de aresta
Aplica-se a: SQL Server 2019 (15.x) e versões posteriores
Banco de Dados SQL do Azure
Instância Gerenciada SQL do Azure
banco 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
- Arquitetura do SQL Graph
- Exemplo de base de dados gráfica SQL
- CRIAR TABELA (Grafo SQL)
- ALTER TABLE table_constraint