Randbeperkingen
van toepassing op: SQL Server 2019 (15.x) en latere versies
Azure SQL Database
Azure SQL Managed Instance
SQL-database in Microsoft Fabric
Edge-beperkingen kunnen worden gebruikt voor het afdwingen van gegevensintegriteit en specifieke semantiek in de edge-tabellen in de SQL Server Graph-database.
Edge-beperkingen
Edge-tabellen dwingen standaard niets af voor de eindpunten van de rand. Dat wil gezegd, een rand in een grafiekdatabase kan elk knooppunt verbinden met elk ander knooppunt, ongeacht het type.
SQL Graph biedt ondersteuning voor randbeperkingen, waarmee gebruikers beperkingen kunnen toevoegen aan hun edge-tabellen, waardoor specifieke semantiek wordt afgedwongen en ook de gegevensintegriteit behouden blijft. Wanneer een nieuwe rand wordt toegevoegd aan een edge-tabel met randbeperkingen, dwingt de database-engine af dat de knooppunten die de edge probeert te verbinden, aanwezig zijn in de juiste knooppunttabellen. Er wordt ook voor gezorgd dat een knooppunt niet kan worden verwijderd als een rand verwijst naar dat knooppunt.
Randbeperkingsclausules
Eén randbeperking bestaat uit een of meer randbeperkingsclausules.
CONSTRAINT constraint_name CONNECTION (cause1[, clause2...])
- Een edge-beperkingscomponent is een paar namen van knooppunttabellen, gescheiden door het
TO
trefwoord. - De eerste tabelnaam in de edge-constraintclausule is de naam van de FROM-knoopptabel voor de edge-relatie.
- De tweede tabelnaam in de edge-constraintclausule is de naam van de TO-knooppunttabel voor de edge-relatie.
- Het paar tabelnamen geeft daarom de richting aan van de randrelatie.
- Zoals eerder vermeld, kan een randbeperking een of meer randbeperkingsclausules bevatten.
Meerdere beperkingen en clausules
- Meerdere randbeperkingen, gedefinieerd voor dezelfde edge-tabel, worden afgedwongen met een
AND
-operator. - Meerdere randvoorwaardenclausules , gedefinieerd binnen dezelfde randvoorwaarde, worden afgedwongen met een
OR
-operator.
Houd rekening met de Supplier
en Customer
knooppunten in uw grafiek. Elk kan worden gerelateerd aan het Product
-knooppunt door één gedeelde edge-tabel: bought
. De bought
edge-tabel ondersteunt Customer-(bought)->Product
en Supplier-(bought)->Product
relatietypen. Dit kan worden bereikt met behulp van één randbeperking met meerdere randbeperkingsclausules.
Voorbeelden
CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product)
In het bovenstaande voorbeeld ziet u één randbeperking, met één randbeperkingsclausule. Deze beperking is van toepassing op Customer-(bought)->Product
. Het invoegen van een bought
edge-relatie van een Customer
naar Product
zou dus zijn toegestaan. Als u een andere combinatie van knooppunten probeert in te voegen, zoals Supplier-(bought)->Product
, zelfs als het een geldige relatie in de echte wereld beschrijft, zal dat mislukken.
CONSTRAINT EC_BOUGHT CONNECTION (Supplier TO Product, Customer TO Product)
In het bovenstaande voorbeeld wordt één randbeperking gedefinieerd met twee randbeperkingsclausules. Met deze beperkingsclausules kan de bought
edge Supplier-(bought)->Product
of Customer-(bought)->Product
relaties bevatten. Het invoegen van andere typen randrelaties in de bought
tabel mislukt.
CONSTRAINT EC_BOUGHT1 CONNECTION (Supplier TO Product)
CONSTRAINT EC_BOUGHT2 CONNECTION (Customer TO Product)
In het bovenstaande voorbeeld ziet u twee beperkingen in dezelfde randtabel, waarbij elke randbeperking één beperkingscomponent opgeeft. In dit geval staat SQL alleen invoegingen toe die tegelijkertijd voldoen aan de randbeperkingsclausules van BEIDE. Dit is niet mogelijk. Er is geen knooppuntpaar dat kan voldoen aan beide edge-beperkingsclausules. Deze randbeperkingscombinatie maakt de randtabel onbruikbaar.
Zie het voorbeeld 'Een nieuwe randbeperking maken voor bestaande edge-tabel, met nieuwe randbeperkingscomponent' verderop op deze pagina voor een gedetailleerde uitleg van waar meerdere randbeperkingen kunnen worden gebruikt in een praktijkscenario.
Indexen van randbeperkingen
Als u een randbeperking maakt, wordt er niet automatisch een bijbehorende index gemaakt voor $from_id
en $to_id
kolommen in de randtabel. Handmatig een index maken op een $from_id
-, $to_id
-paar is aanbevolen als u puntzoekopdrachten of een OLTP-werklast hebt.
ON DELETE referentiële acties voor randbeperkingen
Met trapsgewijze acties op een randbeperking kunnen gebruikers de acties definiëren die door de database-engine worden uitgevoerd wanneer een gebruiker de knooppunten verwijdert, waarmee de opgegeven edge verbinding maakt. De volgende referentiële acties kunnen worden gedefinieerd: GEEN ACTIE De database-engine genereert een fout wanneer u een knooppunt probeert te verwijderen dat verbinding maakt met edge(s).
CASCADE Wanneer een knooppunt uit de database wordt verwijderd, worden de edge(s) die verbinding maken, verwijderd.
Werken met randbeperkingen
U kunt een randbeperking definiëren in SQL Server met behulp van Transact-SQL. Een randbeperking kan alleen worden gedefinieerd in een grafiekrandtabel. Als u een randbeperking wilt maken, verwijderen of wijzigen, moet u machtiging ALTER voor de tabel hebben.
Edge-beperkingen maken
In de volgende voorbeelden ziet u hoe u een randbeperking maakt voor nieuwe of bestaande tabellen.
Een randbeperking maken in een nieuwe randtabel
In het volgende voorbeeld wordt een randbeperking gemaakt in de bought
edge-tabel.
-- 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;
Referentiële acties definiëren in een nieuwe randtabel
In het volgende voorbeeld wordt een randbeperking gemaakt in de bought
edge-tabel en wordt de referentiële actie DELETE CASCADE gedefinieerd.
-- 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;
Randbeperking toevoegen aan een bestaande randtabel
In het volgende voorbeeld wordt ALTER TABLE gebruikt om een randbeperking toe te voegen aan de bought
randtabel.
-- 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);
Een nieuwe randbeperking maken voor bestaande edge-tabel, met aanvullende randbeperkingsclausules
In het volgende voorbeeld wordt de opdracht ALTER TABLE
gebruikt om een nieuwe randbeperking toe te voegen met aanvullende randbeperkingsclausules in de bought
edge-tabel.
-- 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);
In het voorgaande voorbeeld zijn er twee randbeperkingsclausules in de EC_BOUGHT1
-beperking, een die Customer
verbindt met Product
en andere Supplier
verbindt met Product
. Beide bepalingen worden in disjunction toegepast. Een bepaalde rand moet dus voldoen aan een van deze twee componenten die moeten worden toegestaan in de randtabel.
Een nieuwe randbeperking maken in bestaande edge-tabel, met een nieuwe randbeperkingscomponent
In het volgende voorbeeld wordt de opdracht ALTER TABLE
gebruikt om een nieuwe randbeperking toe te voegen met een nieuwe randbeperkingscomponent in de bought
edge-tabel.
-- 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
Stel je voor dat we in het voorgaande voorbeeld nu ook de relatie van Supplier
tot Product
moeten opnemen via de bought
edge-tabel. U kunt proberen een nieuwe randbeperking toe te voegen:
ALTER TABLE bought ADD CONSTRAINT EC_BOUGHT1 CONNECTION (Supplier TO Product);
Het toevoegen van een nieuwe randbeperking is echter niet de juiste oplossing. We hebben twee afzonderlijke randbeperkingen gemaakt voor de bought
edge-tabel, EC_BOUGHT
en EC_BOUGHT1
. Beide edge-beperkingen hebben verschillende edge-beperkingsclausules. Als een randtabel meer dan één randbeperking heeft, moet een bepaalde rand voldoen aan ALLE randbeperkingen die in de randtabel moeten worden toegestaan. Omdat er geen boog kan voldoen aan zowel EC_BOUGHT
als EC_BOUGHT1
hier, mislukt de bovenstaande ALTER TABLE
uitspraak als er überhaupt rijen zijn in de bought
boogtabel.
Als u deze randbeperking wilt maken, is de voorgeschreven manier om een reeks te volgen, zoals wordt weergegeven in dit voorbeeld:
-- 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]';
Het feit dat we eerst de nieuwe 'superset'-beperking hebben toegevoegd zonder de eerdere beperking te verwijderen, maakt het mogelijk dat de bewerking alleen-metagegevensbewerking is. U hoeft niet alle bestaande gegevens in de bought
tabel te controleren, omdat deze de bestaande beperking omvat.
Om dit te laten doorgaan, moet een bepaalde rand in de bought
-rand voldoen aan een van de randspecifieke beperkingen in de EC_BOUGHT_NEW
-beperking. Daarom is elke rand die geldige Customer
probeert te verbinden met Product
of Supplier
met Product
knooppunten toegestaan.
Edge-beperkingen verwijderen
In het volgende voorbeeld wordt eerst de naam van de randbeperking geïdentificeerd en vervolgens de beperking verwijderd.
-- 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;
Randbeperkingen wijzigen
Als u een randbeperking wilt wijzigen met Behulp van Transact-SQL, moet u eerst de bestaande randbeperking verwijderen en deze vervolgens opnieuw maken met de nieuwe definitie.
Edge-beperkingen weergeven
De zichtbaarheid van de metagegevens in catalogusweergaven is beperkt tot beveiligbare items waarvan een gebruiker eigenaar is of waarvoor de gebruiker een bepaalde machtiging heeft gekregen. Zie Zichtbaarheidsconfiguratie voor metagegevensvoor meer informatie.
In het voorbeeld worden alle randbeperkingen en hun eigenschappen geretourneerd voor de edge-tabel bought
in de tempdb
-database.
-- 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');