Kantbegränsningar
gäller för: SQL Server 2019 (15.x) och senare versioner
Azure SQL Database
Azure SQL Managed Instance
SQL-databas i Microsoft Fabric
Gränsbegränsningar kan användas för att framtvinga dataintegritet och specifika semantik på gränstabellerna i SQL Server-grafdatabasen.
Kantbegränsningar
Som standardinställning upprätthåller kanttabeller inte något för kantens slutpunkter. En kant i en grafdatabas kan alltså ansluta valfri nod till valfri annan nod, oavsett typ.
SQL Graph stöder gränsbegränsningar, vilket gör det möjligt för användare att lägga till begränsningar i sina gränstabeller, vilket tvingar fram specifika semantik och även upprätthåller dataintegritet. När en ny kant läggs till i en kanttabell med gränsbegränsningar framtvingar databasmotorn att noderna som gränsen försöker ansluta finns i rätt nodtabeller. Det säkerställs också att en nod inte kan tas bort, om någon kant refererar till noden.
Kantbegränsningsklausuler
En begränsning med en enda kant består av en eller flera gränsbegränsningssatser.
CONSTRAINT constraint_name CONNECTION (cause1[, clause2...])
- En gränsbegränsningssats är ett par nodtabellnamn, avgränsade med nyckelordet
TO
. - Det första tabellnamnet i gränsbegränsningssatsen är namnet på tabellen FROM-nod för gränsrelationen.
- Det andra tabellnamnet i gränsbegränsningssatsen är namnet på to-nodtabellen för gränsrelationen.
- Tabellnamnparet anger därför riktning för gränsrelationen.
- Som tidigare nämnts kan en gränsbegränsning innehålla en eller flera gränsvillkorssatser.
Flera begränsningar och villkor
- Flera gränsbegränsningar, som definierats för samma gränstabell, tillämpas med en
AND
-operator. - Villkor för flera kanter -satser, som definieras inom samma kantvillkor, tillämpas med en
OR
-operator.
Tänk på noderna Supplier
och Customer
i diagrammet. Var och en kan relateras till den Product
noden med en enda delad kanttabell: bought
. Tabellen bought
edge stöder Customer-(bought)->Product
och Supplier-(bought)->Product
relationstyper. Detta kan åstadkommas med hjälp av en kantbegränsning med flera kantbegränsningsklasuler.
Exempel
CONSTRAINT EC_BOUGHT CONNECTION (Customer TO Product)
Exemplet ovan visar en gränsbegränsning med en gränsbegränsningssats. Den här begränsningen stöder Customer-(bought)->Product
. Att infoga en bought
kantrelation som går från en Customer
till Product
skulle tillåtas. Om du försöker infoga någon annan kombination av noder, till exempel Supplier-(bought)->Product
, även om det kan beskriva en giltig relation i verkligheten, skulle misslyckas.
CONSTRAINT EC_BOUGHT CONNECTION (Supplier TO Product, Customer TO Product)
Exemplet ovan definierar en gränsbegränsning med två gränsvillkorssatser. Med dessa villkorssatser kan den bought
-kanten innehålla antingen en Supplier-(bought)->Product
- eller en Customer-(bought)->Product
-relation. Det går inte att infoga andra typer av kantrelationer i den bought
tabellen.
CONSTRAINT EC_BOUGHT1 CONNECTION (Supplier TO Product)
CONSTRAINT EC_BOUGHT2 CONNECTION (Customer TO Product)
Exemplet ovan visar två begränsningar i samma gränstabell, där varje gränsbegränsning anger en begränsningssats. I den här situationen tillåter SQL endast infogningar som uppfyller båda gränsbegränsningssatserna samtidigt. Det här är inte möjligt. Det finns inget nodpar som kan uppfylla båda gränsvillkorssatserna. Den här gränsbegränsningskombinationen gör kanttabellen oanvändbar.
En detaljerad förklaring av var flera gränsbegränsningar kan användas i ett verkligt scenario finns i exemplet "Skapa en ny gränsbegränsning för befintlig gränstabell med ny gränsbegränsningssats" senare på den här sidan.
Index över kantbegränsningar
När du skapar en gränsbegränsning skapas inte automatiskt ett motsvarande index för $from_id
och $to_id
kolumner i kanttabellen. Om du har punktsökningsfrågor eller OLTP-arbetsbelastning rekommenderar vi att du skapar ett index manuellt på ett $from_id
, $to_id
par.
VID BORTTAGNING av referensåtgärder för gränsbegränsningar
Med sammanhängande åtgärder med en gränsbegränsning kan användarna definiera de åtgärder som databasmotorn vidtar när en användare tar bort de noder som den angivna gränsen ansluter till. Följande referensåtgärder kan definieras: INGEN ÅTGÄRD Databasmotorn genererar ett fel när du försöker ta bort en nod som har anslutna kanter.
CASCADE När en nod tas bort från databasen tas anslutningskanter bort.
Arbeta med gränsbegränsningar
Du kan definiera en gränsbegränsning i SQL Server med hjälp av Transact-SQL. En gränsbegränsning kan endast definieras i en grafkanttabell. Om du vill skapa, ta bort eller ändra en gränsbegränsning måste du ha ALTER- behörighet i tabellen.
Skapa gränsbegränsningar
I följande exempel visas hur du skapar en gränsbegränsning för nya eller befintliga tabeller.
Skapa en gränsbegränsning för en ny gränstabell
I följande exempel skapas en gränsbegränsning för bought
edge-tabellen.
-- 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;
Definiera referensåtgärder i en ny gränstabell
I följande exempel skapas en kantbegränsning för bought
kanttabellen och definierar en referensåtgärd 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;
Lägga till gränsvillkor i en befintlig gränstabell
I följande exempel används ALTER TABLE för att lägga till en gränsbegränsning i bought
edge-tabellen.
-- 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);
Skapa en ny gränsbegränsning för befintlig gränstabell med ytterligare gränsvillkorssatser
I följande exempel används kommandot ALTER TABLE
för att lägga till en ny gränsbegränsning med ytterligare gränsbegränsningssatser i bought
edge-tabellen.
-- 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);
I föregående exempel finns det två gränsvillkorssatser i villkoret EC_BOUGHT1
, en som ansluter Customer
till Product
och andra ansluter Supplier
till Product
. Båda dessa satser tillämpas i disjunction. En given kant måste alltså uppfylla någon av dessa två satser för att tillåtas i gränstabellen.
Skapa en ny gränsbegränsning för befintlig gränstabell med en ny gränsbegränsningssats
I följande exempel används kommandot ALTER TABLE
för att lägga till en ny gränsbegränsning med en ny gränsbegränsningssats i bought
edge-tabellen.
-- 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
I föregående exempel, föreställ dig att vi nu också måste inkludera Supplier
till Product
-relationen, via kanttabellen bought
. Du kan prova att lägga till en ny gränsbegränsning:
ALTER TABLE bought ADD CONSTRAINT EC_BOUGHT1 CONNECTION (Supplier TO Product);
Att lägga till en ny gränsbegränsning är dock inte rätt lösning. Vi har skapat två separata gränsbegränsningar för bought
edge-tabellen, EC_BOUGHT
och EC_BOUGHT1
. Båda dessa gränsbegränsningar har olika gränsvillkorssatser. Om en kanttabell har mer än en gränsbegränsning måste en viss kant uppfylla ALLA gränsbegränsningar som ska tillåtas i kanttabellen. Eftersom ingen kant här kan uppfylla både EC_BOUGHT
och EC_BOUGHT1
misslyckas ovanstående ALTER TABLE
-instruktion om det alls finns några rader i bought
kant-tabellen.
För att den här gränsbegränsningen ska skapas är det föreskrivna sättet att följa en sekvens som visas i det här exemplet:
-- 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]';
Det faktum att vi lade till den nya "superuppsättningsbegränsningen" först utan att släppa den tidigare, gör att åtgärden kan vara en endast metadataåtgärd – den behöver inte kontrollera alla befintliga data i tabellen bought
, eftersom den omfattar den befintliga begränsningen.
För att en viss kant ska tillåtas i kanten bought
måste den uppfylla någon av kantbegränsningsklasulerna i EC_BOUGHT_NEW
-begränsningen. Därför tillåts alla kanter som försöker ansluta giltiga Customer
till Product
eller Supplier
till Product
noder.
Ta bort gränsbegränsningar
I följande exempel identifieras först namnet på gränsbegränsningen och sedan tas villkoret bort.
-- 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;
Ändra gränsbegränsningar
Om du vill ändra en gränsbegränsning med Transact-SQL måste du först ta bort den befintliga gränsbegränsningen och sedan återskapa den med den nya definitionen.
Visa gränsbegränsningar
Synligheten för metadata i katalogvyer är begränsad till skyddsbara objekt som en användare antingen äger eller som användaren har beviljats viss behörighet för. För mer information, se konfigureringen av metadatasynlighet.
Exemplet returnerar alla gränsbegränsningar och deras egenskaper för gränstabellen bought
i tempdb
-databasen.
-- 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');