Articles

Graf Microsoft SQL Server-pokus, který selhal (prozatím)

Posted by admin
TRAN Ngoc Thach
TRAN Ngoc Thach

sledovat

29. června 2020 * 9 min čtení

zřeknutí se odpovědnosti: názor v tomto článku je pouze Můj, na základě mého omezeného vystavení grafu serveru SQL Server. Nejsem v žádném případě odborníkem na SQL Server. Mohl bych být zaujatý vůči Neo4j.

s rostoucím využíváním databáze grafů a dominancí Neo4j na tomto specializovaném trhu, stejně jako jeho významný nárůst výkonu při dotazování na vysoce propojená data, je pochopitelné, že Microsoft nechce být vynechán z tohoto mega-trendu.

počínaje SQL Server 2017, SQL Server nabídl Graph funkce, se zavedenímMATCH Klíčové slovo. Ve verzi 2019 byly mimo jiné přidány dvě nové pozoruhodné funkce: omezení hran a použití odvozených tabulek v dotazech MATCH. Potápění v této technologii dost dlouho, mám dojem, že od této chvíle:

  • podpora grafů v SQL Serveru je stále daleko od plnohodnotné databáze grafů, např. Neo4j.
  • přidávání funkcí je pomalu přírůstkové.
  • funkce grafu je neochotně začleněna do myšlení relační databáze.

pojďme do detailů!

Pros & nevýhody

Klíčové slovo MATCH je podle mého názoru pouze Syntatickým cukrem. Spíše než:

SELECT *
FROM NodeTable1 nt1 JOIN EdgeTable et ON nt1.$node_id = et.$from_id JOIN NodeTable2 nt2 ON nt2.$node_id = et.$to_id

… uživatelé mohou do značné míry zkrátit dotaz jako:

SELECT *
FROM NodeTable1 nt1, EdgeTable et, NodeTable2 nt2
WHERE MATCH(nt1-(et)->nt2)

zkrácený dotaz je nepochybně příjemný pro oči. Ve světě. Net však může být Entity Framework upřednostňován pro softwarové aplikace orientované na data; v důsledku čehož není potřeba příkazů prostého textu SQL. Vývojáři prostě nechat rámec generovat optimální dotazy pro ně, zatímco oni jsou zaměřeny na vysoké úrovni abstrakce. Podle této logiky je příjemný efekt MATCH najednou irelevantní. Horší je, že v současné době neexistuje ani plán podpory těchto grafových schopností v Entity Framework (Core).

ve srovnání s Neo4j, při opětovném pohledu na výše uvedené dotazy, je nevyhnutelné, aby uživatelé ohýbali své Grafové myšlení do světa relačních databází. Stále musíme předem prohlásit, které tabulky v klauzuli FROM provedou shodu (měl by to být spíše Graf považovaný za „projetelnou celou věc“ a člověk se nemusí starat o podrobnou organizaci dat?). Když je nutné znát směr šipky v MATCH, uživatelé si uvědomí mapování 1-1 mezi klauzulí MATCH a původní klauzulí JOIN v tom smyslu, že je třeba rozlišovat zdrojový uzel a cílový uzel. Naproti tomu syntaxe Neo4j Cypher umožňuje toto rozlišení ignorovat. To vše nemusí být nutně měnič her; ale prostě otázka pohodlí a radosti z vývoje. (Později, v případě 1. studie, uvidíme, že kvůli tomu musíme udělat UNION ALL.)

jedním z klíčů k vysokému výkonu nativní databáze grafů při procházení připojených dat je sousedství bez indexu. Bohužel neexistuje žádná taková věc s funkcí Graph v SQL Serveru:

na každém uzlu neudržujeme seznam sousedství; místo toho ukládáme data edge do tabulek. Protože se jedná o relační databázi, ukládání dat ve formě tabulek bylo pro nás přirozenější volbou

dalším nepříjemným problémem je nedostatek vizualizačních nástrojů přizpůsobených grafům pro schéma i data. Jako řešení mohou uživatelé stále vytvářet schéma schématu v SSMS, ale tyto tabulky uzlů a hran končí jako jednotlivé, odpojené tabulky, i když mají omezení okrajů. Technologie grafů by měla mimo jiné přinést také vizuální odvolání, což uživatelům usnadní vytváření správných dotazů. Nedostatek takových nástrojů je frustrující a škodlivý pro produktivitu vývojářů.

Diagram pro tabulky grafů

takže co uděláme, abychom získali schéma grafu? Myslím, že jsme se otevřít každý okraj tabulky ručně vidět omezení, a pak důvod na ně, s pomocí kusu papíru, přijít na celé schéma grafu.

omezení hran grafu

pokud jde o vizualizaci dat, vyzkoušel jsem Microsoft Power BI s grafovým addonem zaměřeným na sílu. Tento nástroj však není zdarma a nepodporuje grafické schopnosti serveru SQL Server, což znamená, že vidí tabulky uzlů a hran jako normální databázové tabulky. Při pečlivém zkoumání seznamů sloupců existují podivně vypadající názvy sloupců, např. graph_id_...,from_obj_id.... Jedná se o interní sloupce, automaticky generované při vytváření tabulek uzlů/hran, nepřístupné zvenčí. Chyba je vyvolána, jak je uvedeno níže, funkcí Power BI Get Data při přístupu k těmto sloupcům.

Power BI – „získat Data“ z grafových tabulek SQL Serveru

Chcete-li tento problém vyřešit, musíte vytvořit databázové zobrazení obsahující pouze relevantní / dosažitelné sloupce, např. from_id a to_id v tabulce hran, node_id v tabulce uzlů. Pak v Power BI extrahujte data tímto pohledem. Doufejme, že se nemýlím, zdá se, že graf Power BI vyžaduje jednu jedinou tabulku, která se skládá ze sloupců Source, Target, Weight, Source Type, Target Type, Link Type. Naše vzorové schéma je zjednodušující; vytvoření této jediné tabulky je tedy triviální. Co když schéma obsahovalo tabulky uzlů + 20 a tabulku okrajů + 10, mohli bychom skončit s jedinou tabulkou pro vizualizaci celého grafu pomocí Power BI?

# Aktualizováno 04.07.2020: Na druhou stranu je to jistě možné, i když je to stále těžkopádné. Jeden by měl začínat u okrajů tabulek, v každé z nich jsou $from_id a $to_id spojeny proti relevantním tabulkám uzlů, aby se převedly do sdílených vlastností všech uzlů, např. Name nebo Id. Pak se UNION ALL pro všechny spojit do konečné jediné tabulky požadované Power BI.

dotazování na uzly a hrany je jednou z možností Grafové technologie. Co může vyniknout databázi grafů, je vestavěná, ale rozšiřitelná podpora grafových algoritmů, jako je PageRank a detekce komunity Louvain (aka. Louvain modularity). Bohužel znovu, žádné takové analytické funkce dostupné v grafu SQL Server, jak bylo řečeno:

některé databáze grafů poskytují vyhrazené analytické funkce grafu, jako je „nejkratší cesta“ nebo „hodnocení stránky“.“SQL Graph neposkytuje žádné takové funkce v této verzi. Opět platí, že T-SQL smyčky a temp tabulky mohou být použity k napsání řešení pro tyto scénáře.

v Neo4j jsou tyto algoritmy snadno dostupné ve výrobní třídě díky Graph Data Science Library. Plus, je to open-source. Obecně je dokumentace užitečná, ale někdy nestačí. S open-source, vývojáři mohou stáhnout a ponořit se do toho, jak je implementován konkrétní algoritmus; nebo dokonce rekompilovat knihovnu, s dalšími informacemi o protokolování, dále pochopit. Implementace PageRank v SQL je možná, ale složitější algoritmus, jako je modularita Louvain, může být náročný. Nicméně, mnoho softwarových inženýrů dává přednost tomu, aby se více obtěžovali obchodní logikou, místo aby byli zaplaveni technickými detaily na nízké úrovni.

v neposlední řadě je podle mého názoru běžný tabulkový výraz jakousi odvozenou tabulkou. Od SQL Server 2019 má být tato technika oficiálně funkční s grafem:

společný výraz tabulky (CTE) s grafovými tabulkami a klauzulí shody

ale pokud následuje vytvoření zobrazení, je schopen:

vytvoření zobrazení pomocí grafových tabulek a klauzule shody

myslím, že je to známka nekonzistence. 2. přístup vyžaduje trvale vytvořené zobrazení, protože není možné vytvořit dočasné zobrazení v SQL Serveru. Za normálních okolností, uživatelé překonat to s CTE, ale opět CTE nefunguje s grafem, jak je uvedeno výše.

studijní případy

ukázkový scénář: studenti a učitelé.

Neo4j ‚ s Cypher:

CREATE (S1:NStudents {name: "S1"}), (S2:NStudents {name: "S2"}), (T1:NTeachers {name: "T1"}), (S3:NStudents {name: "S3"}), (T2:NTeachers {name: "T2"}), (S4:NStudents {name: "S4"}), (S1)-->(S2), (S2)-->(T1), (T1)-->(T2), (T2)-->(S4), (S3)-->(T1)

graf SQL Serveru 2019:

CREATE TABLE NStudents ( NVARCHAR(MAX) NOT NULL, INT NOT NULL) AS NODE;CREATE TABLE NTeachers ( NVARCHAR(MAX) NOT NULL, FLOAT NOT NULL) AS NODE;CREATE TABLE Talks (CONSTRAINT EC_Talk CONNECTION (NStudents TO NStudents, NStudents TO NTeachers, NTeachers TO NStudents, NTeachers TO NTeachers) ON DELETE CASCADE) AS EDGE;INSERT INTO NStudents VALUES ('S1',1),('S2',2),('S3',3),('S4',4);
INSERT INTO NTeachers VALUES ('T1',123), ('T2',456);
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NStudents WHERE = 'S1'),
(SELECT $node_id FROM NStudents WHERE = 'S2'));
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NStudents WHERE = 'S2'),
(SELECT $node_id FROM NTeachers WHERE = 'T1'));
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NTeachers WHERE = 'T1'),
(SELECT $node_id FROM NTeachers WHERE = 'T2'));
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NTeachers WHERE = 'T2'),
(SELECT $node_id FROM NStudents WHERE = 'S4'));
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NStudents WHERE = 'S3'),
(SELECT $node_id FROM NTeachers WHERE = 'T1'));

případ 1: všechna příchozí a odchozí připojení uzlů

motivace: počítání těchto připojení pro každý uzel je jedním ze způsobů, jak zjistit, které z nich jsou nejdůležitější.

Neo4j ‚ scypher:

MATCH (n)--()
RETURN n.name, COUNT(r) AS allCons
ORDER BY allCons DESC

graf SQL Serveru 2019:

--Create a View first, for convenience purpose.
CREATE VIEW view_AllPeople
AS
SELECT $node_id AS ,
FROM NStudents
UNION ALL
SELECT $node_id AS ,
FROM NTeachers;--Query using the View.
WITH CTE()
AS
(
SELECT ap1.
FROM view_AllPeople ap1, Talks t, view_AllPeople ap2
WHERE MATCH(ap1-(t)->ap2)
UNION ALL
SELECT ap1.
FROM view_AllPeople ap1, Talks t, view_AllPeople ap2
WHERE MATCH(ap1<-(t)-ap2)
)
SELECT , COUNT(*) AS allConns
FROM CTE
GROUP BY
ORDER BY allConns DESC

poznámky: Verze SQL je nejen delší, ale také nepohodlnější, protože směr šipek v MATCH musí být vždy zohledněn.

Případ 2: Nejvyšší nejdelší cesty

motivace: dlouhé řetězce závislostí jsou náchylné k křehkosti. Například závislost knihovny.

Neo4j ‚ scypher:

// The WHERE is to filter out duplicate paths, e.g. A->B = B->A.
MATCH p=(n)--(m)
WHERE ID(n) < ID(m)
RETURN n.name, m.name, length(p) AS len, AS node_list
ORDER BY len DESC

graf SQL Serveru 2019:

WITH CTE(from_id, to_id, , )
AS
(
SELECT $from_id, $to_id, 1 AS , CONVERT(NVARCHAR(MAX), $to_id) AS
FROM Talks
UNION ALL
SELECT t.$from_id, t.$to_id, +1, CONVERT(NVARCHAR(MAX), CTE. + ',' + CONVERT(NVARCHAR(MAX), $to_id))
FROM Talks t JOIN CTE ON t.$to_id = CTE.
)
SELECT vap., ,
FROM CTE JOIN (SELECT MAX(c.) AS maxLevel FROM CTE c GROUP BY c.) myMax ON CTE. = myMax.maxLevel JOIN
view_AllPeople vap ON CTE. = vap.
ORDER BY DESC

poznámky: Ve verzi SQL Server je třeba použít rekurzivní techniku výrazu Common Table. Do značné míry zahrnuje myšlení relační databáze k řešení problémů s grafy.

závěr

v Grafové doméně je příkaz SQL serveru SQL s funkcí Graph využívanou nebo ne, používaný k řešení problémů s grafem, obvykle mnohem zdlouhavější a složitější ve srovnání s Cypherem Neo4j. To vede k tomu, že vývoj kódu bude časově náročnější a bude obtížné jej později udržovat a rozšiřovat. Jiný inženýr nebo dokonce ten původní, při pohledu na stejný úryvek kódu o měsíc později, zjistí, že je frustrující pochopit všechny jeho aspekty. Známým termínem pro popis této situace je technický dluh.

kombinace všech výše uvedených bodů, od aspektu kódu, přes podporu funkcí, až po ekosystém nástrojů/knihoven, funkčnost grafu SQL Serveru v současné době, i když je povzbudivá, nedosahuje očekávání.

SQL Server je extrémně vyspělý s ohledem na relační databázi, ale jasně nováček v databázi grafů. Tato podpora grafu je pravděpodobně považována za obsaženou v mentalitě relační databáze.

Related Post