Sdílet prostřednictvím


Omezení hran

Platí pro: SQL Server 2019 (15.x) a novější verze Azure SQL DatabaseAzure SQL Managed InstanceSQL Database v Microsoft Fabricu

Omezení edge se dají použít k vynucení integrity dat a konkrétní sémantiky u hraničních tabulek v grafové databázi SQL Serveru.

Hraniční omezení

Ve výchozím nastavení hraniční tabulky nevynucují nic pro koncové body hran. To znamená, že hrana v grafové databázi by mohla připojit jakýkoli uzel k jinému uzlu bez ohledu na typ.

SQL Graph podporuje omezení okrajů, která uživatelům umožňují přidávat omezení do hraničních tabulek, čímž vynucují specifickou sémantiku a také udržují integritu dat. Když se do hraniční tabulky přidá nová hrana s omezeními okrajů, databázový stroj vynutí, aby uzly, které se hrana pokouší připojit, existovaly ve správných tabulkách uzlů. Je také zajištěno, že uzel nelze odstranit, pokud na tento uzel odkazuje nějaká hrana.

Klauzule okrajového omezení

Jedno hraniční omezení se skládá z jedné nebo více klauzulí omezení okrajů.

CONSTRAINT constraint_name CONNECTION (cause1[, clause2...])
  • Klauzule omezení okraje je dvojice názvů tabulek uzlů oddělená klíčovým slovem TO.
  • První název tabulky v klauzuli omezení okraje je název tabulky FROM node pro relaci okrajů.
  • Druhý název tabulky v klauzuli omezení okrajů je název tabulky uzlu TO pro relaci okrajů.
  • Dvojice názvů tabulek proto označuje směr vztahu hran.
  • Jak jsme uvedli dříve, omezení okrajů může obsahovat jednu nebo více klauzulí omezení okrajů.

Více omezení a klauzulí

  • Pomocí operátoru AND se vynucuje několik omezení okrajů definovaných pro stejnou hraniční tabulku.
  • Klauze s více hraničními omezeními, definované v rámci téhož hraničního omezení, jsou vynucovány operátorem OR.

Zvažte Supplier a Customer uzly v grafu. Každý z nich může souviset s uzlem Product jednou sdílenou hraniční tabulkou: bought. Hraniční tabulka bought podporuje typy relací Customer-(bought)->Product a Supplier-(bought)->Product. Toho lze dosáhnout pomocí jednoho hraničního omezení s několika klauzulemi omezení okrajů.

Příklady
CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product)

Výše uvedený příklad ukazuje jedno omezení okrajů s jednou klauzulí omezení okraje. Toto omezení podporuje Customer-(bought)->Product. To znamená, že vložení vztahu hrany bought od Customer do Product by bylo povoleno. Pokud se pokusíte vložit jakoukoli jinou kombinaci uzlů, například Supplier-(bought)->Product, i když může popisovat platnou relaci v reálném světě, selže.

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

Výše uvedený příklad definuje jedno omezení okrajů se dvěma klauzulemi omezení okrajů. Tyto klauzule omezení umožňují hraně bought obsahovat buď vztahy Supplier-(bought)->Product nebo Customer-(bought)->Product. Vložení jiných typů hraničních relací do tabulky bought by se nezdařilo.

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

Výše uvedený příklad ukazuje dvě omezení ve stejné hraniční tabulce, přičemž každé omezení hrany určuje jednu klauzuli constraint. V této situaci by SQL umožňoval pouze vložení, které splňují klauzule omezení obou okrajů současně. To není možné. Neexistuje žádný pár uzlů, který by mohl splňovat obě klauzule omezení okrajů. Tato kombinace omezení okrajů činí tabulku okrajů nepoužitelnou.

Podrobné vysvětlení toho, kde lze v reálném scénáři použít několik omezení okrajů, najdete v příkladu "Vytvoření nového omezení okrajů u existující tabulky okrajů s novou klauzulí omezení okrajů" dále na této stránce.

Indexy na hraničních omezeních

Vytvořením omezení okraje se automaticky nevytvoří odpovídající index pro $from_id a $to_id sloupce v hraniční tabulce. Ruční vytvoření indexu u dvojice $from_id, $to_id se doporučuje, pokud máte dotazy pro vyhledávání konkrétních bodů nebo úlohu OLTP.

Referenční akce ON DELETE při hranových omezeních

Kaskádové akce na hraničním omezení umožňují uživatelům definovat akce, které databázový stroj provede, když uživatel odstraní uzly, které daná hrana připojí. Je možné definovat následující referenční akce: ŽÁDNÁ AKCE Databázový stroj vyvolá chybu při pokusu o odstranění uzlu, který obsahuje spojovací hrany.

CASCADE Při odstranění uzlu z databáze se odstraní spojovací hrany.

Práce s okrajovými omezeními

Omezení edge v SQL Serveru můžete definovat pomocí jazyka Transact-SQL. Okrajové omezení lze definovat pouze v hraniční tabulce grafu. Pokud chcete vytvořit, odstranit nebo upravit omezení okrajů, musíte mít k tabulce oprávnění ALTER.

Vytvoření hraničních omezení

Následující příklady ukazují, jak vytvořit omezení okrajů pro nové nebo existující tabulky.

Vytvoření omezení okrajů v nové hraniční tabulce

Následující příklad vytvoří omezení na hraně v tabulce hran 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;

Definujte referenční akce na nové tabulce hran

Následující příklad vytvoří omezení hrany na tabulce hran bought a definuje referenční akci 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;

Přidání omezení okrajů do existující hraniční tabulky

Následující příklad používá ALTER TABLE k přidání hraničního omezení do bought hraniční tabulky.

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

Vytvoření nového omezení okrajů u existující tabulky okrajů s dalšími klauzulemi omezení okrajů

Následující příklad používá příkaz ALTER TABLE k přidání nového omezení hran s dalšími klauzulemi pro omezení hran v tabulce hran 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);

V předchozím příkladu existují dvě klauzule omezení okrajů v omezení EC_BOUGHT1, jedna, která spojuje Customer k Product, a druhá spojuje Supplier k Product. Obě tyto klauzule se uplatňují odděleně. To znamená, že daná hrana musí splňovat některou z těchto dvou podmínek, aby byla povolena v tabulce hran.

Vytvoření nového omezení okrajů u existující tabulky okrajů s novou klauzulí omezení okrajů

Následující příklad používá příkaz ALTER TABLE k přidání nového omezení hrany s novou klauzulí omezení hrany v tabulce hran 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

V předchozím příkladu si představte, že teď musíme také zahrnout relaci mezi Supplier a Product prostřednictvím tabulky hran bought. Můžete zkusit přidat nové omezení edge:

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

Přidání nového omezení okrajů ale není správným řešením. Na bought hraniční tabulce jsme vytvořili dvě samostatná omezení okrajů, EC_BOUGHT a EC_BOUGHT1. Obě tato omezení okrajů mají různé klauzule omezení okrajů. Pokud má tabulka okrajů více než jedno omezení okrajů, musí daná hrana splňovat VŠECHNA omezení okrajů, která mají být povolena v hraniční tabulce. Vzhledem k tomu, že žádná hrana nemůže vyhovovat zároveň EC_BOUGHT a EC_BOUGHT1, výše uvedené tvrzení ALTER TABLE selže, pokud jsou v tabulce hran bought vůbec nějaké řádky.

Pro úspěšné vytvoření tohoto okrajového omezení je předepsáno sledovat posloupnost, která je znázorněna v této ukázce:

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

Skutečnost, že jsme přidali nové omezení "nadmnožina" jako první bez odstranění předchozího, umožňuje, aby šlo o operaci pouze s metadaty – nemusí zkontrolovat všechna existující data v tabulce bought, protože zahrnuje existující omezení.

S tímto musí daná hrana v okraji bought splňovat některou z klauzulí omezení hran v omezení EC_BOUGHT_NEW. Jakákoli hrana, která se pokouší připojit správné uzly Customer k Product nebo Supplier k Product, je tedy povolena.

Odstranit okrajová omezení

Následující příklad nejprve identifikuje název hraničního omezení a pak odstraní omezení.

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

Úprava omezení okrajů

Pokud chcete upravit omezení edge pomocí jazyka Transact-SQL, musíte nejprve odstranit stávající omezení edge a pak ho znovu vytvořit pomocí nové definice.

Zobrazení omezení okrajů

Viditelnost metadat v zobrazeních katalogu je omezena na položky, které uživatel vlastní, nebo na které má uživatel udělené určité oprávnění. Pro více informací se podívejte na konfiguraci viditelnosti metadat.

Příklad vrátí všechna omezení okrajů a jejich vlastnosti pro hraniční tabulku bought v databázi 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');

Další kroky