Procházení relací pomocí grafových dotazů

Dokončeno

Návod

Další podrobnosti najdete na kartě Text a obrázky .

Některé vztahy s daty jsou přirozeně reprezentovány jako sítě, včetně sociálních připojení, organizačních hierarchií, doporučení produktů a vzorců detekce podvodů. I když můžete tyto relace modelovat pomocí cizích klíčů a spojení, grafové dotazy pomocí operátoru MATCH poskytují intuitivnější a efektivnější způsob procházení připojených dat.

Vizualizace datových struktur grafu

Než začnete psát dotazy na grafy, pomůže vám to vizualizovat uspořádání dat grafu. Představte si jednoduchou sociální síť, kde se lidé navzájem znají a kupují produkty:

Diagram znázorňující datový model grafu s uzly Osoba a Produkt, které jsou propojené hranami ZNÁ a KOUPIL.

V tomto modelu:

  • Uzly (rámečky ) představují entity, jako jsou lidé a produkty.
  • Hrany (šipky) představují vztahy mezi uzly. Směr šipky označuje směr vztahu (Alice zná Boba, ne nutně Boba zná Alice).

Poznámka:

Tento diagram znázorňuje koncepty grafu. Příklady kódu v této lekci používají podobná, ale zjednodušená data, abyste se mohli zaměřit na konkrétní funkce.

Pochopit možnosti grafu

Možnosti grafu rozšiřují relační model o vyhrazené uzly a hraniční tabulky. Uzly představují entity, jako jsou lidé, produkty a umístění. Hrany představují vztahy mezi nimi, například "zná", "koupil" nebo "umístěn v".

Klíčovou výhodou grafových dotazů je porovnávání vzorů. Místo psaní složitých vícecestných spojení vyjadřujete vzor, který hledáte, pomocí syntaxe stylu ASCII:

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

Poznámka:

Tabulky grafů jsou plně kompatibilní se stávajícími relačními funkcemi. Grafové tabulky můžete spojit s běžnými tabulkami, používat indexy a použít všechny standardní operace T-SQL.

Vytvoření tabulek uzlů

Tabulky uzlů ukládají entity v grafu. Vytvořte je pomocí CREATE TABLE s AS NODE klauzulí:

-- 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 automaticky přidá $node_id sloupec do tabulek uzlů, které jednoznačně identifikuje každý uzel. Systém používá tento sloupec interně pro relace grafu.

Následující příklad vloží čtyři osoby do tabulky uzlu Person a poté se dotazuje na tabulku, aby zobrazil jak obchodní sloupce, tak systémem generované $node_id. Všimněte si, že příkaz INSERT používá pouze uživatelem definované sloupce. SQL Server vygeneruje $node_id automaticky pro každý řádek:

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

Vytvořit tabulky hran

Hraniční tabulky představují relace mezi uzly. Vytvořte je pomocí CREATE TABLE s AS EDGE klauzulí:

-- 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 automaticky přidá $edge_ida $from_id$to_id sloupce do hraničních tabulek. Hrany můžete vložit zadáním hodnot $from_id a $to_id z propojených uzlů, například tímto způsobem:

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

Návod

Hraniční tabulky můžou ukládat vlastnosti samotné relace, jako jsou kalendářní data, váhy nebo typy. To je užitečné pro dočasné analýzy nebo vážené grafové algoritmy.

Dotazování grafů pomocí MATCH klauzule

Klauzule MATCH používá syntaxi vzoru k určení relací, které chcete najít. Základní vzor používá šipky k zobrazení směru relace:

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

Směr šipky záleží:

  • (Node1)-(Edge)->(Node2): Edge přechází z Node1 na Node2.
  • (Node1)<-(Edge)-(Node2): Edge přechází z Node2 na Node1.

Následující příklad najde všechny lidi, kteří znají 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';

Procházení více vztahů

Dotazy s jedním skokem najdou přímá připojení, ale grafové databáze excelují při procházení s více skoky. V jedné klauzuli MATCH můžete propojit více vzorců hran, abyste mohli sledovat cesty napříč několika relacemi. Díky této funkci můžete odpovídat na otázky, jako jsou "kdo jsou přátelé mých přátel?" nebo "jaké produkty si moji kolegové koupili?" bez psaní složitých vnořených poddotazů.

Následující příklad najde přátele přátel propojením dvou vztahů . Vzor Person1-(k1)->Person2-(k2)->Person3 začíná u Person1, následuje jednu hranu KNOWS k Person2 a poté následuje další hranu KNOWS k dosažení 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

V rámci jednoho průchodu můžete také kombinovat různé typy relací. Následující příklad přechází z na ZAKOUPENÉ hrany, aby našel, které produkty byly zakoupeny lidmi, které daná osoba zná.

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

Důležité

Každý alias hraniční tabulky se může zobrazit jenom jednou v jednom MATCH vzoru. Aby bylo možné procházet stejný typ hrany vícekrát, použijte různé aliasy.

Používá se SHORTEST_PATH pro procházení s proměnlivou délkou.

Můžete použít SHORTEST_PATH k vyhledání nejkratšího připojení mezi proměnlivým počtem relací. Klíčové slovo FOR PATH označuje tabulky, které se účastní porovnávání s proměnlivou délkou, a kvantifikátory jako + (jedna nebo více) nebo {1,3} (jedna až tři) řídí hloubku procházení.

Následující příklad najde všechny osoby, které jsou z Alice dosažitelné během tří hopů, a spočítá vzdálenost k jednotlivým z nich.

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

Volba mezi grafy a relačními přístupy

Grafové dotazy nejsou vždy nejlepší volbou. Při rozhodování mezi grafem a tradičními relačními přístupy zvažte tyto pokyny:

Dotazy na grafy použijte v případech:

  • Relace jsou primárním cílem vašich dotazů.
  • Potřebujete procházet proměnnou nebo neznámou hloubku (přátel přátel přátel)
  • Data přirozeně tvoří síť (sociální grafy, hierarchie, trasy).
  • Vzory dotazů by vyžadovaly mnoho samoobslužných spojení v relačním SQL.
  • Provádíte hledání cest nebo analýzu připojení.

Relační dotazy použijte v případech:

  • Relace jsou jednoduché a s pevnou hloubkou (nadřazená-podřízená struktura s jednou úrovní)
  • Primárně filtrujete a agregujete atributy entit.
  • Datový model je většinou tabulkový s několika relacemi.
  • Výkon je kritický a indexy cizích klíčů jsou dostatečné.
  • Váš tým je obeznámenější s tradičními vzory SQL.

Řešení běžných problémů s dotazy na grafy

Grafové dotazy mají jedinečné požadavky na syntaxi, které můžou způsobit chyby. Následující tabulka popisuje běžné problémy a jejich řešení.

Výzva Příčina Řešení
Dotaz nevrací žádné výsledky. Směr šipky ve MATCH vzorci neodpovídá způsobu vložení hran Ověřte, jakým způsobem byly hrany vloženy. Pokud $from_id je Zaměstnanec a $to_id je Manažer, šipka musí odkazovat od zaměstnance na manažera.
Chyba syntaxe s opakovaným okrajem Stejný alias edge použitý vícekrát v jednom MATCH vzoru Vytvořte samostatné aliasy pro každé procházení stejného typu hrany.
SHORTEST_PATH Dotaz je neúspěšný. Tabulky hran a uzlů, které nejsou označeny FOR PATH Přidejte FOR PATH klíčové slovo do všech tabulek, které se účastní párování s proměnnou délkou.
Hrany odkazují na neexistující uzly Sloupce s obchodním klíčem použité namísto hodnot $node_id Pomocí poddotazů můžete při vkládání okrajů vybírat $node_id z tabulek uzlů.

Poznámka:

Tabulky grafů a MATCH operátor jsou k dispozici v SQL Serveru 2017 a novějších verzích a v Azure SQL Database. Funkce SHORTEST_PATH vyžaduje SQL Server 2019 nebo novější. Konkrétní dostupnost funkcí najdete v dokumentaci k vaší platformě.

Další informace o funkcích grafu najdete v tématu Zpracování grafů pomocí SQL Serveru a MATCH (Transact-SQL).