Bläddra mellan relationer med graffrågor
Vissa datarelationer representeras naturligt som nätverk, inklusive sociala anslutningar, organisationshierarkier, produktrekommendationer och mönster för bedrägeriidentifiering. Du kan modellera dessa relationer med hjälp av sekundärnycklar och kopplingar, men graffrågor med operatorn MATCH ger ett mer intuitivt och ofta effektivare sätt att passera anslutna data.
Visualisera grafdatastrukturer
Innan du skriver graffrågor hjälper det till att visualisera hur grafdata organiseras. Tänk dig ett enkelt socialt nätverk där människor känner varandra och köper produkter:
I den här modellen:
- Noder (rutor) representerar entiteter som personer och produkter
- Kanter (pilar) representerar relationer mellan noder. Pilriktningen anger relationsriktningen (Alice känner Bob, inte nödvändigtvis Bob känner Alice).
Anmärkning
Det här diagrammet illustrerar diagrambegrepp. Kodexemplen i hela den här lektionen använder liknande men förenklade data för att fokusera på specifika funktioner.
Förstå graffunktioner
Graffunktionerna utökar relationsmodellen med dedikerade nod- och kanttabeller. Noder representerar entiteter som personer, produkter och platser. Kanter representerar relationer mellan dem, till exempel "vet", "köpt" eller "finns i".
Den största fördelen med graffrågor är mönstermatchning. I stället för att skriva komplexa flervägskopplingar uttrycker du det mönster som du letar efter med hjälp av en SYNTAX för ASCII-format:
-- Traditional relational approach (multiple joins)
SELECT p1.Name, p2.Name
FROM Person AS p1
INNER JOIN Friendship AS f ON p1.PersonID = f.Person1ID
INNER JOIN Person AS p2 ON f.Person2ID = p2.PersonID;
-- Graph approach (pattern matching)
SELECT Person1.Name, Person2.Name
FROM Person AS Person1, Friendship, Person AS Person2
WHERE MATCH(Person1-(Friendship)->Person2);
Anmärkning
Graftabeller är helt kompatibla med befintliga relationsfunktioner. Du kan koppla graftabeller till vanliga tabeller, använda index och tillämpa alla vanliga T-SQL-åtgärder.
Skapa nodtabeller
Nodtabeller lagrar entiteter i diagrammet. Skapa dem med CREATE TABLE med AS NODE-satsen:
-- Create a Person node table
CREATE TABLE dbo.Person (
PersonID INT PRIMARY KEY,
Name NVARCHAR(100) NOT NULL,
Email NVARCHAR(200),
Department NVARCHAR(50)
) AS NODE;
-- Create a Product node table
CREATE TABLE dbo.Product (
ProductID INT PRIMARY KEY,
Name NVARCHAR(200) NOT NULL,
Category NVARCHAR(100),
Price DECIMAL(10, 2)
) AS NODE;
-- Create a Location node table
CREATE TABLE dbo.Location (
LocationID INT PRIMARY KEY,
City NVARCHAR(100) NOT NULL,
CountryRegion NVARCHAR(100) NOT NULL
) AS NODE;
SQL Server lägger automatiskt till en $node_id kolumn i nodtabeller som unikt identifierar varje nod. Systemet använder den här kolumnen internt för grafrelationer.
I följande exempel infogas fyra personer i tabellen för noden Person och frågar sedan efter tabellen för att visa både de affärsrelaterade kolumnerna och det systemgenererade $node_id. Observera att INSERT-instruktionen endast använder de användardefinierade kolumnerna. SQL Server genererar $node_id automatiskt för varje rad:
-- Insert person data using standard INSERT syntax
INSERT INTO dbo.Person (PersonID, Name, Email, Department)
VALUES
(1, 'Alice Johnson', 'alice@contoso.com', 'Engineering'),
(2, 'Bob Smith', 'bob@contoso.com', 'Marketing'),
(3, 'Carol Davis', 'carol@contoso.com', 'Engineering'),
(4, 'David Lee', 'david@contoso.com', 'Sales');
-- Query shows the system-generated $node_id alongside user columns
SELECT $node_id, PersonID, Name FROM dbo.Person;
Skapa kanttabeller
Edge-tabeller representerar relationer mellan noder. Skapa dem med hjälp av CREATE TABLE-komponenten med AS EDGE-satsen.
-- Create a "reports to" relationship edge
CREATE TABLE dbo.ReportsTo (
StartDate DATE,
ReportType NVARCHAR(50)
) AS EDGE;
-- Create a "purchased" relationship edge
CREATE TABLE dbo.Purchased (
PurchaseDate DATE NOT NULL,
Quantity INT NOT NULL,
TotalAmount DECIMAL(10, 2)
) AS EDGE;
-- Create a "knows" relationship edge (social connection)
CREATE TABLE dbo.Knows (
ConnectionDate DATE,
ConnectionStrength INT -- 1-10 scale
) AS EDGE;
SQL Server lägger automatiskt till $edge_id, $from_idoch $to_id kolumner i kanttabeller. Du kan infoga kanter genom att ange $from_id och $to_id värdena från de anslutna noderna, så här:
-- Alice reports to Bob
INSERT INTO dbo.ReportsTo ($from_id, $to_id, StartDate, ReportType)
SELECT
(SELECT $node_id FROM dbo.Person WHERE Name = 'Alice Johnson'),
(SELECT $node_id FROM dbo.Person WHERE Name = 'Bob Smith'),
'2023-01-15',
'Direct';
-- Create social connections
INSERT INTO dbo.Knows ($from_id, $to_id, ConnectionDate, ConnectionStrength)
SELECT
(SELECT $node_id FROM dbo.Person WHERE Name = 'Alice Johnson'),
(SELECT $node_id FROM dbo.Person WHERE Name = 'Carol Davis'),
'2022-06-01',
8;
Tips/Råd
Edge-tabeller kan lagra egenskaper om själva relationen, till exempel datum, vikter eller typer. Detta är användbart för tidsanalys eller viktade grafalgoritmer.
Frågediagram med MATCH -satsen
Satsen MATCH använder en mönstersyntax för att ange de relationer som du vill hitta. Det grundläggande mönstret använder pilar för att visa relationsriktningen:
-- Find who reports to whom
SELECT
Employee.Name AS Employee,
Manager.Name AS Manager,
r.StartDate
FROM dbo.Person AS Employee,
dbo.ReportsTo AS r,
dbo.Person AS Manager
WHERE MATCH(Employee-(r)->Manager);
Pilriktningen är viktig:
-
(Node1)-(Edge)->(Node2): Gränsen går från Node1 till Node2 -
(Node1)<-(Edge)-(Node2): Gränsen går från Node2 till Node1
I följande exempel hittar du alla som känner Alice:
SELECT
Connector.Name AS PersonWhoKnowsAlice,
k.ConnectionStrength
FROM dbo.Person AS Connector,
dbo.Knows AS k,
dbo.Person AS Target
WHERE MATCH(Connector-(k)->Target)
AND Target.Name = 'Alice Johnson';
Bläddra mellan flera relationer
Enkelsökningar hittar direkta anslutningar, men grafdatabaser utmärker sig vid flera hopp-traverseringar. Du kan länka flera kantmönster i en enda MATCH sats för att följa sökvägar genom flera relationer. Med den här funktionen kan du svara på frågor som "vilka är mina vänners vänner?" eller "vilka produkter köpte mina kollegor?" utan att skriva komplexa kapslade underfrågor.
I följande exempel hittar du vänners vänner genom att länka två KNOWS-relationer . Mönstret Person1-(k1)->Person2-(k2)->Person3 börjar på Person1, följer en KNOWS-kant till Person2 och följer sedan en annan KNOWS-kant för att nå Person3:
-- Find friends of friends (2-hop connections)
SELECT DISTINCT
Person1.Name AS Person,
Person3.Name AS FriendOfFriend
FROM dbo.Person AS Person1,
dbo.Knows AS k1,
dbo.Person AS Person2,
dbo.Knows AS k2,
dbo.Person AS Person3
WHERE MATCH(Person1-(k1)->Person2-(k2)->Person3)
AND Person1.Name = 'Alice Johnson'
AND Person3.Name <> Person1.Name; -- Exclude self
Du kan också kombinera olika relationstyper i en enda traversering. Följande exempel går från KNOWS till KÖPTA förbindelser för att hitta vilka produkter som har köpts av personer som en viss person känner:
-- Find products purchased by people in the same department
SELECT DISTINCT
p1.Name AS Person,
p1.Department,
prod.Name AS Product
FROM dbo.Person AS p1,
dbo.Knows AS k,
dbo.Person AS p2,
dbo.Purchased AS pu,
dbo.Product AS prod
WHERE MATCH(p1-(k)->p2-(pu)->prod)
AND p1.Department = p2.Department;
Viktigt!
Varje kanttabellalias kan bara visas en gång i ett enda MATCH mönster. Om du vill korsa samma kanttyp flera gånger använder du separata alias.
Använd SHORTEST_PATH för blädreringar med variabel längd
Du kan använda SHORTEST_PATH för att hitta den kortaste anslutningen för ett variabelt antal relationer. Nyckelordet FOR PATH markerar tabeller som deltar i matchning med variabel längd och kvantifierare som + (en eller flera) eller {1,3} (en till tre) styr blädderingsdjupet.
I följande exempel hittar du alla personer som kan nås från Alice inom tre hopp och räknar avståndet till var och en:
SELECT
StartPerson.Name,
LAST_VALUE(ReachablePerson.Name) WITHIN GROUP (GRAPH PATH) AS ReachablePerson,
COUNT(ReachablePerson.Name) WITHIN GROUP (GRAPH PATH) AS Distance
FROM dbo.Person AS StartPerson,
dbo.Knows FOR PATH AS k,
dbo.Person FOR PATH AS ReachablePerson
WHERE MATCH(SHORTEST_PATH(StartPerson(-(k)->ReachablePerson){1,3}))
AND StartPerson.Name = 'Alice Johnson';
Välj mellan graf- och relationsmetoder
Graph-frågor är inte alltid det bästa valet. Tänk på dessa riktlinjer när du bestämmer dig för diagram och traditionella relationella metoder:
Använd graffrågor när:
- Relationer är det primära fokuset för dina frågor
- Du måste navigera variabla eller okända djup (vänner till vänner till vänner)
- Data bildar naturligt ett nätverk (sociala grafer, hierarkier, vägar)
- Frågemönster skulle kräva många självkopplingar i relations-SQL
- Du utför sökvägssökning eller anslutningsanalys
Använd relationsfrågor när:
- Relationer är enkla och har fixerat djup (överordnad-underordnad med en nivå)
- Du filtrerar och aggregerar i första hand entitetsattribut
- Datamodellen är mestadels tabell med få relationer
- Prestanda är kritiska och index på främmande nycklar är tillräckliga
- Ditt team är mer bekant med traditionella SQL-mönster
Felsöka vanliga problem med graffrågor
Graph-frågor har unika syntaxkrav som kan orsaka fel. I följande tabell beskrivs vanliga utmaningar och hur du löser dem.
| Utmaning | Orsak | Lösning |
|---|---|---|
| Frågan returnerar inga resultat | Pilriktningen i MATCH mönstret matchar inte hur kanter infogades |
Kontrollera hur kanter infogades. Om $from_id är Anställd och $to_id är Chef måste pilen peka från Anställd till Chef. |
| Syntaxfel med upprepad kant | Samma kantalias som används flera gånger i ett MATCH mönster |
Skapa separata alias för varje traversering av samma kanttyp. |
SHORTEST_PATH frågan misslyckas |
Edge- och nodtabeller som inte har markerats med FOR PATH |
Lägg till FOR PATH nyckelord i alla tabeller som deltar i matchning med variabel längd. |
| Edge refererar till noder som inte finns | Affärsnyckelkolumner som används i stället för $node_id värden |
Använd underfrågor för att välja $node_id ur nodtabeller när du infogar kanter. |
Anmärkning
Graph-tabeller och operatorn MATCH är tillgängliga i SQL Server 2017 och senare samt Azure SQL Database. Funktionen SHORTEST_PATH kräver SQL Server 2019 eller senare. Kontrollera din plattforms dokumentation för specifik information om funktionens tillgänglighet.
Mer information om graffunktioner finns i Diagrambearbetning med SQL Server och MATCH (Transact-SQL).