Udostępnij za pośrednictwem


Ograniczenia brzegowe

Dotyczy: SQL Server 2019 (15.x) i późniejsze wersje Azure SQL DatabaseAzure SQL Managed InstanceSQL Database w Microsoft Fabric

Ograniczenia krawędzi mogą służyć do wymuszania integralności danych i określonych semantyki w tabelach brzegowych w bazie danych grafów programu SQL Server.

Ograniczenia krawędzi

Domyślnie tabele krawędzi nie wymuszają żadnych ograniczeń dla punktów końcowych krawędzi. Oznacza to, że krawędź w grafowej bazie danych może połączyć dowolny węzeł z dowolnym innym węzłem, niezależnie od typu.

Program SQL Graph obsługuje ograniczenia brzegowe, które umożliwiają użytkownikom dodawanie ograniczeń do tabel brzegowych, wymuszając w ten sposób konkretną semantyka, a także utrzymując integralność danych. Po dodaniu nowej krawędzi do tabeli krawędzi z ograniczeniami, aparat bazy danych wymusza, aby węzły, które krawędź próbuje połączyć, istniały w odpowiednich tabelach węzłów. Jest również zapewnione, że węzeł nie może być usunięty, jeśli jakakolwiek krawędź odwołuje się do tego węzła.

Klauzule ograniczenia krawędzi

Ograniczenie pojedynczej krawędzi składa się z jednej lub większej liczby klauzul ograniczenia krawędzi.

CONSTRAINT constraint_name CONNECTION (cause1[, clause2...])
  • Klauzula ograniczenia krawędzi to para nazw tabel węzłów oddzielona TO słowem kluczowym.
  • Pierwsza nazwa tabeli w klauzuli ograniczenia krawędzi jest nazwą tabeli węzłów FROM dla relacji krawędzi.
  • Druga nazwa tabeli w klauzuli ograniczenia krawędzi jest nazwą tabeli węzłów TO dla relacji krawędzi.
  • W związku z tym para nazw tabel wskazuje kierunek relacji krawędzi.
  • Jak wspomniano wcześniej, ograniczenie krawędzi może zawierać co najmniej jedną klauzulę ograniczenia krawędzi.

Wiele ograniczeń i klauzul

  • Wiele ograniczeń krawędzi zdefiniowanych dla tej samej tabeli krawędzi jest wymuszanych za pomocą operatora AND.
  • Wiele klauzul ograniczenia krawędzi , zdefiniowanych w obrębie tego samego ograniczenia krawędzi, jest wymuszane za pomocą operatora OR.

Rozważ użycie węzłów Supplier i Customer na grafie. Każdy z nich może być powiązany z węzłem Product za pomocą pojedynczej, udostępnionej tabeli krawędzi: bought. Tabela krawędzi bought obsługuje typy relacji Customer-(bought)->Product i Supplier-(bought)->Product. Można to osiągnąć przy użyciu jednego ograniczenia krawędzi z wieloma klauzulami ograniczenia krawędzi.

Przykłady
CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product)

W powyższym przykładzie przedstawiono jedno ograniczenie krawędzi z jedną klauzulą ograniczenia krawędzi. To ograniczenie wspiera Customer-(bought)->Product. Oznacza to, że wstawienie relacji krawędzi bought przechodzącej z Customer do Product jest dozwolone. Jeśli spróbujesz wstawić dowolną inną kombinację węzłów, na przykład Supplier-(bought)->Product, mimo że może to opisać prawidłową relację w świecie rzeczywistym, zakończy się niepowodzeniem.

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

W powyższym przykładzie zdefiniowano jedno ograniczenie krawędzi z dwoma klauzulami ograniczenia krawędzi. Te klauzule ograniczeń umożliwiają krawędziom bought zawierać relacje Supplier-(bought)->Product lub Customer-(bought)->Product. Wstawianie innych typów relacji krawędzi do tabeli bought zakończy się niepowodzeniem.

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

W powyższym przykładzie pokazano dwa ograniczenia w tej samej tabeli krawędzi, z każdym ograniczeniem krawędzi określającym jedną klauzulę ograniczenia. W tej sytuacji SQL zezwalałby tylko na wstawianie, które jednocześnie spełnia obie klauzule ograniczenia krawędzi. Nie jest to możliwe. Nie ma pary węzłów, która może spełniać oba klauzule ograniczenia krawędzi. Ta kombinacja ograniczeń krawędzi sprawia, że tabela krawędzi jest bezużyteczna.

Aby uzyskać szczegółowe wyjaśnienie, gdzie można używać wielu ograniczeń krawędzi w rzeczywistym scenariuszu, zobacz przykład "Tworzenie nowego ograniczenia krawędzi w istniejącej tabeli krawędzi z nową klauzulą ograniczenia krawędzi" w dalszej części tej strony.

Indeksy na ograniczeniach krawędziowych

Utworzenie ograniczenia krawędzi nie powoduje automatycznego utworzenia odpowiedniego indeksu w kolumnach $from_id i $to_id w tabeli krawędzi. Ręczne tworzenie indeksu w parze $from_id, $to_id jest zalecane, jeśli masz zapytania wyszukiwania punktów lub obciążenie OLTP.

Akcje referencyjne PRZY USUWANIU na ograniczeniach krawędziowych

Kaskadowe akcje na ograniczeniu krawędzi umożliwiają użytkownikom definiowanie akcji, które aparat bazy danych wykonuje po usunięciu węzłów przez użytkownika, z którymi łączy się dana krawędź. Można zdefiniować następujące akcje referentalne: NO ACTION Aparat bazy danych zgłasza błąd podczas próby usunięcia węzła, który ma połączone krawędzie.

CASCADE Po usunięciu węzła z bazy danych usuwane są związane z nim krawędzie połączeń.

Praca z ograniczeniami brzegowymi

Ograniczenie krawędzi można zdefiniować w programie SQL Server przy użyciu języka Transact-SQL. Ograniczenie krawędzi można zdefiniować tylko w tabeli krawędzi grafu. Aby utworzyć, usunąć lub zmodyfikować ograniczenie krawędzi, musisz mieć uprawnienia ALTER w tabeli.

Tworzenie ograniczeń brzegowych

W poniższych przykładach pokazano, jak utworzyć ograniczenie krawędzi dla nowych lub istniejących tabel.

Tworzenie ograniczenia krawędzi w nowej tabeli krawędzi

Poniższy przykład tworzy ograniczenie krawędzi w tabeli krawędzi 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;

Określ akcje referencyjne na nowej tabeli krawędzi

Poniższy przykład tworzy ograniczenie na krawędź w tabeli krawędzi bought i definiuje akcję referencyjną 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;

Dodawanie ograniczenia krawędzi do istniejącej tabeli krawędzi

W poniższym przykładzie użyto funkcji ALTER TABLE, aby dodać ograniczenie krawędzi do tabeli krawędzi 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);

Utwórz nowe ograniczenie krawędzi w istniejącej tabeli krawędzi z dodatkowymi klauzulami ograniczenia krawędzi

W poniższym przykładzie użyto polecenia ALTER TABLE, aby dodać nowe ograniczenie krawędzi z dodatkowymi klauzulami ograniczenia krawędzi w tabeli krawędzi 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);

W poprzednim przykładzie w ograniczeniu EC_BOUGHT1 istnieją dwie klauzule ograniczenia krawędzi, jedna, która łączy Customer z Product, a inna łączy Supplier z Product. Oba te klauzule są stosowane w alternatywie. Oznacza to, że dana krawędź musi spełniać jedną z tych dwóch klauzul, aby być dozwoloną w tabeli krawędzi.

Utwórz nowe ograniczenie krawędzi w istniejącej tabeli krawędzi z nową klauzulą ograniczenia krawędzi

W poniższym przykładzie użyto polecenia ALTER TABLE, aby dodać nowe ograniczenie krawędzi z nową klauzulą ograniczenia krawędzi w tabeli krawędzi 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

W poprzednim przykładzie wyobraźmy sobie, że teraz musimy również uwzględnić relację z Supplier do Product, przy użyciu tabeli krawędzi bought. Możesz spróbować dodać nowe ograniczenie krawędzi:

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

Jednak dodanie nowego ograniczenia krawędzi nie jest poprawnym rozwiązaniem. Utworzyliśmy dwa oddzielne ograniczenia krawędzi dla tabeli krawędzi bought, EC_BOUGHT i EC_BOUGHT1. Oba te ograniczenia krawędzi mają różne klauzule ograniczenia krawędzi. Jeśli tabela krawędzi ma więcej niż jedno ograniczenie krawędzi, dana krawędź musi spełniać wszystkie ograniczenia krawędzi dozwolone w tabeli krawędzi. Ponieważ żadna krawędź tutaj nie może spełnić jednocześnie warunków EC_BOUGHT i EC_BOUGHT1, powyższe twierdzenie ALTER TABLE kończy się niepowodzeniem, jeśli w tabeli krawędzi bought znajdują się jakiekolwiek wiersze.

Aby to ograniczenie krawędzi zostało utworzone pomyślnie, zalecanym sposobem jest wykonanie sekwencji, jak pokazano w tym przykładzie:

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

Fakt, że dodaliśmy nowe ograniczenie "super-set" najpierw bez porzucania wcześniejszego, umożliwia operację tylko metadanych — nie musi sprawdzać wszystkich istniejących danych w tabeli bought, ponieważ obejmuje istniejące ograniczenie.

Dzięki temu, aby dana krawędź mogła być dozwolona w bought, musi spełniać jedną z klauzul ograniczeń krawędzi w ograniczeniu EC_BOUGHT_NEW. W związku z tym każda krawędź, która próbuje połączyć prawidłowe Customer z Product lub Supplier z węzłami Product, jest dozwolona.

Usuwanie ograniczeń krawędzi

Poniższy przykład najpierw identyfikuje nazwę ograniczenia krawędzi, a następnie usuwa ograniczenie.

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

Modyfikowanie ograniczeń krawędzi

Aby zmodyfikować ograniczenie krawędzi przy użyciu języka Transact-SQL, należy najpierw usunąć istniejące ograniczenie krawędzi, a następnie ponownie utworzyć je przy użyciu nowej definicji.

Wyświetlanie ograniczeń krawędzi

Widoczność metadanych w widokach katalogu jest ograniczona do elementów zabezpieczeń, których użytkownik jest właścicielem lub na które użytkownik uzyskał jakieś uprawnienia. Aby uzyskać więcej informacji, zobacz Konfiguracja widoczności metadanych.

Przykład zwraca wszystkie ograniczenia krawędzi i ich właściwości dla tabeli krawędzi bought w bazie danych 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');

Następne kroki