Travers-relasjoner med grafforespørsler

Fullført

Noen dataforhold representeres naturlig som nettverk, inkludert sosiale forbindelser, organisatoriske hierarkier, produktanbefalinger og mønstre for svindeldeteksjon. Selv om du kan modellere disse relasjonene ved hjelp av fremmednøkler og joins, gir grafforespørsler med operatoren MATCH en mer intuitiv og ofte mer effektiv måte å traveriere sammenkoblede data på.

Visualiser grafdatastrukturer

Før man skriver grafforespørsler, hjelper det å visualisere hvordan grafdata er organisert. Tenk deg et enkelt sosialt nettverk hvor folk kjenner hverandre og kjøper produkter:

Diagram som viser en grafdatamodell med Person- og Produktnoder koblet sammen med KNOWS og PURCHASED kanter.

I denne modellen:

  • Noder (bokser ) representerer enheter som personer og produkter
  • Kanter (piler) representerer relasjoner mellom noder. Pilretningen indikerer relasjonsretningen (Alice kjenner Bob, ikke nødvendigvis Bob kjenner Alice).

Bemerkning

Dette diagrammet illustrerer grafkonsepter. Kodeeksemplene gjennom denne enheten bruker lignende, men forenklede data for å fokusere på spesifikke funksjoner.

Forstå grafens muligheter

Graffunksjonene utvider relasjonsmodellen med dedikerte node- og kanttabeller. Noder representerer enheter som personer, produkter og lokasjoner. Kanter representerer relasjoner mellom dem, som «vet», «kjøpt» eller «lokalisert i».

Den viktigste fordelen med grafspørringer er mønstergjenkjenning. I stedet for å skrive komplekse flerveis joins, uttrykker du mønsteret du ser etter ved hjelp av en ASCII-stil syntaks:

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

Bemerkning

Graftabeller er fullt kompatible med eksisterende relasjonsfunksjoner. Du kan koble sammen graftabeller med vanlige tabeller, bruke indekser, og bruke alle standard T-SQL-operasjoner.

Opprett nodetabeller

Nodetabeller lagrer enheter i grafen din. Lag dem ved å bruke CREATE TABLE klausulen AS NODE :

-- 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 legger automatisk til en $node_id kolonne i nodetabeller som entydig identifiserer hver node. Systemet bruker denne kolonnen internt for grafrelasjoner.

Følgende eksempel setter inn fire personer i Person-nodetabellen, og spør deretter tabellen for å vise både forretningskolonnene og den systemgenererte $node_id. Legg merke til at INSERT-setningen kun bruker de brukerdefinerte kolonnene. SQL Server genererer automatisk for $node_id hver 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;

Lag kanttabeller

Kanttabeller representerer relasjoner mellom noder. Lag dem ved å bruke CREATE TABLE klausulen AS EDGE :

-- 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 legger automatisk til $edge_id, $from_id, og $to_id kolonner i kanttabeller. Du kan sette inn kanter ved å spesifisere $from_id og-verdiene $to_id fra de sammenkoblede nodene, slik:

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

Kanttabeller kan lagre egenskaper om selve relasjonen, som datoer, vekter eller typer. Dette er nyttig for tidsanalyse eller vektede grafalgoritmer.

Søk i grafer med klausulen MATCH

Klausulen MATCH bruker en mønstersyntaks for å spesifisere hvilke relasjoner du ønsker å finne. Det grunnleggende mønsteret bruker piler for å vise relasjonsretningen:

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

Pilretningen er viktig:

  • (Node1)-(Edge)->(Node2): Kanten går fra Node1 til Node2
  • (Node1)<-(Edge)-(Node2): Kanten går fra Node2 til Node1

Følgende eksempel finner alle som kjenner 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';

Traverser flere relasjoner

Enkelthopp-spørringer finner direkte forbindelser, men grafdatabaser utmerker seg ved multi-hop traverseringer. Du kan kjede flere kantmønstre i én enkelt MATCH klausul for å følge stier gjennom flere relasjoner. Denne funksjonen lar deg svare på spørsmål som «hvem er vennene til vennene mine?» eller «hvilke produkter kjøpte kollegene mine?» uten å skrive kompliserte nestede underforespørsler.

Følgende eksempel finner venner av venner ved å kjede sammen to KNOW-relasjoner . Mønsteret Person1-(k1)->Person2-(k2)->Person3 starter ved Person1, følger én KNOWS edge til Person2, og følger deretter en annen KNOWS edge for å 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 også kombinere ulike forholdstyper i én og samme reise. Følgende eksempel krysser fra KJENT til KJØPT kanter for å finne hvilke produkter som ble kjøpt av folk en gitt person kjenner:

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

Viktig!

Hvert kanttabellalias kan bare forekomme én gang i ett enkelt MATCH mønster. For å krysse samme kanttype flere ganger, bruk separate aliaser.

Bruk SHORTEST_PATH for traverseringer med variabel lengde

Du kan bruke SHORTEST_PATH det for å finne den korteste forbindelsen på tvers av et variabelt antall relasjoner. Nøkkelordet FOR PATH markerer tabeller som deltar i variabel lengde-matching, og kvantifikatorer som + (en eller flere) eller {1,3} (én til tre) styrer traverseringsdybden.

Følgende eksempel viser alle personer som kan nås fra Alice innen tre hopp og teller avstanden til hver:

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

Velg mellom graf- og relasjonelle tilnærminger

Grafforespørsler er ikke alltid det beste valget. Vurder disse retningslinjene når du skal velge mellom graf- og tradisjonelle relasjonelle tilnærminger:

Bruk grafspørringer når:

  • Relasjoner er hovedfokuset i spørsmålene dine
  • Du må krysse variable eller ukjente dybder (venner av venner av venner av venner)
  • Dataene danner naturlig et nettverk (sosiale grafer, hierarkier, ruter)
  • Spørringsmønstre ville kreve mange selv-joins i relasjonsbasert SQL
  • Du utfører sti-finning eller tilkoblingsanalyse

Bruk relasjonsforespørsler når:

  • Relasjonene er enkle og har fast dybde (forelder-barn på ett nivå)
  • Du filtrerer og aggregerer primært entitetsattributter
  • Datamodellen er for det meste tabellbasert med få sammenhenger
  • Ytelsen er kritisk, og indekser på fremmednøkler er tilstrekkelige
  • Teamet ditt er mer kjent med tradisjonelle SQL-mønstre

Feilsøking av vanlige grafspørringsutfordringer

Grafforespørsler har unike syntakskrav som kan forårsake feil. Tabellen nedenfor beskriver vanlige utfordringer og hvordan de kan løses.

Utfordring Årsak Løsning
Spørring gir ingen resultater Pilretningen i MATCH mønsteret stemmer ikke overens med hvordan kantene ble satt inn Bekreft hvordan kantene ble satt inn. Hvis $from_id er ansatt og $to_id er leder, må pilen peke fra ansatt til leder.
Syntaksfeil med gjentatt kant Samme kantalias brukt flere ganger i ett MATCH mønster Lag separate aliaser for hver traversering av samme kanttype.
SHORTEST_PATH Spørring feiler Kant- og nodetabeller ikke merket med FOR PATH Legg til FOR PATH nøkkelord i alle tabeller som deltar i variabel lengde-matching.
Edge refererer til ikke-eksisterende noder Bedriftsnøkkelkolonner brukt i stedet for $node_id verdier Bruk underspørringer for å velge $node_id fra nodetabeller når du setter inn kanter.

Bemerkning

Graftabeller og operatøren MATCH er tilgjengelige i SQL Server 2017 og nyere, samt Azure SQL Database. Funksjonen SHORTEST_PATH krever SQL Server 2019 eller nyere. Sjekk plattformens dokumentasjon for spesifikke funksjonsmuligheter.

For mer informasjon om graffunksjoner, se Grafbehandling med SQL Server og MATCH (Transact-SQL).