Contraintes d’arête

S’applique à : SQL Server 2019 (15.x) et versions ultérieures Base de données Azure SQL Azure SQL Managed Instance

Les contraintes d'Edge de graphe peuvent être utilisées pour renforcer l'intégrité des données et la sémantique spécifique des tables de bord dans une base de données de graphe de SQL Server.

Contraintes d’arête

Par défaut, les tables d'Edges n'appliquent rien aux points de terminaison de l'Edge. Autrement dit, une arête dans une base de données de graphe pouvait connecter n’importe quel nœud à n’importe quel autre nœud, quel que soit leur type.

SQL Graph prend en charge les contraintes d’arête, lesquelles permettent aux utilisateurs d’ajouter des contraintes à leurs tables d’arêtes, appliquant ainsi une sémantique spécifique et préservant l’intégrité des données. Lorsqu'une nouvelle arête est ajoutée à une table d'Edges avec des contraintes d'Edge, le moteur de base de données fait en sorte que les nœuds que l'Edge essaie de connecter existent dans les tables de nœuds appropriées. Il est également garanti qu'un nœud ne peut pas être supprimé, s'il est référencé par une arête.

Clauses de contrainte d’arête

Une contrainte d’arête se compose d’une ou plusieurs clauses de contrainte d’arête.

CONSTRAINT constraint_name CONNECTION (cause1[, clause2...])
  • Une clause de contrainte d’arête est une paire de noms de tables de nœuds, séparés par le mot clé TO.
  • Le nom de la première table dans la clause de contrainte d’arête est le nom de la table de nœuds FROM pour la relation d’arête.
  • Le nom de la deuxième table dans la clause de contrainte d’arête est le nom de la table de nœuds TO pour la relation d’arête.
  • La paire de noms de tables indique par conséquent le sens de la relation d’arête.
  • Comme indiqué précédemment, une contrainte d’arête peut contenir une ou plusieurs clauses de contrainte d’arête.

Contraintes et clauses multiples

  • Les contraintes d’arête multiples qui sont définies pour la même table d’arêtes sont appliquées à l’aide d’un opérateur AND.
  • Les clauses de contraintes d’arête multiples qui sont définies pour la même table d’arêtes sont appliquées à l’aide d’un opérateur OR.

Examinez les nœuds Supplier et Customer dans votre graphique. Chacun peut être associé au nœud Product par une table d’arêtes partagée unique : bought. La table d’arête bought prend en charge les types de relations Customer-(bought)->Product et Supplier-(bought)->Product. Cette opération peut être réalisée à l’aide d’une contrainte d’arête unique avec plusieurs clauses de contrainte d’arête.

Exemples
CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product)

L’exemple ci-dessus illustre une contrainte d’arête, avec une clause de contrainte d’arête. Cette contrainte prend en charge Customer-(bought)->Product. Cela signifie que l’insertion d’une relation d’arête bought allant de Customer à Product est autorisée. Si vous essayer d'insérer une autre combinaison de nœuds comme par exemple Supplier-(bought)->Product, même si elle puisse décrire une relation valide dans le monde réel, cela échouera.

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

L’exemple ci-dessus définit une contrainte d’arête, avec deux clauses de contrainte d’arête. Ces clauses de contrainte permettent à l’arête bought de contenir des relations Supplier-(bought)->Product ou Customer-(bought)->Product. L’insertion d’autres types de relations de périphérie dans la table bought échoue.

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

L’exemple ci-dessus montre deux contraintes sur la même table de périphérie, chaque contrainte d’arête spécifiant une clause de contrainte. Dans ce cas, SQL autorise uniquement les insertions qui satisfont simultanément aux DEUX clauses de contrainte d’arête. Ce n’est pas possible. Il n'existe aucune paire de nœuds pouvant satisfaire aux deux clauses de contrainte d'Edge. Cette combinaison de contraintes d’arête rend la table d’arête inutilisable.

Pour obtenir une description détaillée de l'utilisation des contraintes d'Edge multiples dans un scénario réel, consultez l'exemple « Créer une contrainte d'Edge sur une table d'Edges existante, avec une nouvelle clause contrainte d'Edge », plus loin dans cette page.

Index sur les contraintes d’arête

La création d'une contrainte d'Edge ne crée pas automatiquement un index correspondant sur les colonnes $from_id et $to_id dans la table d'Edges. La création manuelle d’un index sur une paire $from_id, $to_id est recommandée si vous avez des requêtes de recherche de points ou une charge de travail OLTP.

Actions référentielles ON DELETE sur des contraintes d’arête

Les actions en cascade sur une contrainte d’arête permettent aux utilisateurs de définir les actions que le moteur de base de données effectue quand un utilisateur supprime le ou les nœuds auxquels l’arête donnée est reliée. Les actions référentielle suivantes peuvent être définies : NO ACTION - Le moteur de base de données génère une erreur quand vous essayez de supprimer un nœud ayant une ou plusieurs arêtes de connexion.

CASCADE : Quand un nœud est supprimé de la base de données, la ou les arêtes de connexion sont supprimées.

Utilisez des contraintes d'Edge

Vous pouvez définir une contrainte d’arête dans SQL Server à l'aide de Transact-SQL. Une contrainte d’arête peut être définie sur une table d’arêtes de graphe uniquement. Pour créer, supprimer ou modifier une contrainte d’arête, vous devez disposer de l’autorisation ALTER sur la table.

Créer des contraintes d’arête

Les exemples suivants vous montrent comment créer des contraintes d’arête sur des tables nouvelles ou existantes.

Créez une contrainte d'Edge sur une nouvelle table d'Edges

L'exemple suivant crée une contrainte d'Edge sur la table d'Edges 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;

Définissez des actions référentielles sur une nouvelle table d'Edges

L'exemple suivant crée une contrainte d'Edge sur la table d'Edges bought et définit l'action référentielle 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;

Ajoutez une contrainte d'Edge à une table d'Edges existante

L'exemple suivant utilise ALTER TABLE pour ajouter une contrainte d'Edge à la table d'Edges 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);

Créer une nouvelle contrainte d’arête sur une table d’arêtes existante, avec des clauses de contrainte d’arête supplémentaires

L'exemple suivant utilise la commande ALTER TABLE pour ajouter une nouvelle contrainte d'Edge avec des clauses de contrainte d'Edge supplémentaires sur la table d'Edges 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);

Dans l'exemple précédent, il existe deux clauses de contrainte d'Edge dans la contrainte EC_BOUGHT1 : une qui connecte Customer à Product et l'autre qui connecte Supplier à Product. Ces deux clauses sont appliquées en disjonction. Autrement dit, une arête donnée doit satisfaire une de ces deux clauses pour être autorisée dans la table d’arêtes.

Créez une nouvelle contrainte d'Edge sur une table d'Edges existante, avec une nouvelle clause de contrainte d'Edge

L'exemple suivant utilise la commande ALTER TABLE pour ajouter une nouvelle contrainte d'Edge avec une nouvelle clause de contrainte d'Edge sur la table d'Edges 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

Dans l’exemple précédent, imaginez que nous devons maintenant également inclure la relation Supplier à Product, par le biais de la table d’arêtes bought. Vous pouvez essayer d'ajouter une nouvelle contrainte de périphérie :

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

Toutefois, l'ajout d'une nouvelle contrainte de périphérie n'est pas la solution correcte. Nous avons créé deux contraintes d'Edge distinctes sur la table d'Edges bought, EC_BOUGHT EC_BOUGHT1. Ces deux contraintes d’arête ont des clauses de contrainte d’arête différentes. Si une table d’arêtes fait l’objet de plusieurs contraintes d’arête, une arête donnée doit satisfaire TOUTES les contraintes d’arête pour être autorisée dans la table d’arêtes. Puisqu'aucune arête ne peut satisfaire à la fois EC_BOUGHT et EC_BOUGHT1 ici, l'instruction ALTER TABLE ci-dessus échoue s'il existe des lignes dans la table d'Edges bought.

Pour que cette contrainte d'Edge soit créée avec succès, la méthode prescrite consiste à suivre une séquence comme indiqué dans cet exemple :

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

Le fait que nous ayons d'abord ajouté la nouvelle contrainte « super-set » sans supprimer la plus ancienne permet à l'opération de porter uniquement sur les métadonnées : elle n'a pas besoin de vérifier toutes les données existantes dans la table bought, car elle englobe la contrainte existante.

Ainsi, pour qu'une arête donnée soit autorisée dans l'Edge bought, elle doit satisfaire l'une des clauses de contrainte d'Edge figurant dans la contrainte EC_BOUGHT_NEW. Par conséquent, toute arête qui tente de se connecter à des nœuds valides Customer à Product ou Supplier à Product des nœuds est autorisée.

Supprimer des contraintes d’arête

L'exemple suivant identifie d'abord le nom de la contrainte d’arête, puis supprime la contrainte.

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

Modifier des contraintes d’arête

Pour modifier une contrainte d'Edge à l'aide de Transact-SQL, vous devez d'abord supprimer la contrainte d'Edge existante, puis la recréer avec la nouvelle définition.

Afficher des contraintes d’arête

La visibilité des métadonnées dans les affichages catalogue est limitée aux éléments sécurisables qu'un utilisateur détient ou pour lesquels des autorisations lui ont été accordées. Pour plus d'informations, consultez Metadata Visibility Configuration.

L'exemple retourne toutes les contraintes d'Edge et leurs propriétés pour la table d'Edges bought dans la base de données 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');

Étapes suivantes