Omezení hran
Platí pro: SQL Server 2019 (15.x) a novější verze
Azure SQL Database
Azure SQL Managed Instance
SQL 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
- Architektura SQL grafu
- Ukázková databáze SQL Graph
- VYTVOŘIT TABULKU (SQL graf)
- ALTER TABLE table_constraint