Articles

Microsoft SQL Server ’ s Graph-ett försök som blev kort (för nu)

Posted by admin
TRAN Ngoc Thach
TRAN Ngoc Thach

följ

Jun 29, 2020 * 9 min läs

Disclaimer: yttrandet i den här artikeln är min ensam, baserat på min begränsade exponering för SQL Servers Graf. Jag är inte på något sätt expert på SQL Server. Jag kan vara partisk mot Neo4j.

med den ökande användningen av grafdatabas och dominansen av Neo4j på denna nischmarknad, liksom dess betydande prestandavinst när det gäller att fråga mycket anslutna data, är det förståeligt att Microsoft inte vill lämnas utanför denna megatrend.

från SQL Server 2017 erbjöd SQL Server graffunktioner, med introduktionen av nyckelordet MATCH. I 2019-versionen tillkom bland annat två nya anmärkningsvärda funktioner: Kantbegränsningar och användningen av härledda tabeller i MATCH – frågor. Dykning i denna teknik tillräckligt länge, jag har ett intryck av att, från och med nu:

  • Grafstödet i SQL Server är fortfarande långt ifrån en fullfjädrad grafdatabas, t. ex.Neo4j.
  • tillägget av funktionalitet är långsamt inkrementellt.
  • Graffunktionen är motvilligt anpassad till Relationsdatabasens tankesätt.

Låt oss komma in i detaljer!

fördelar& nackdelar

nyckelordet MATCH är enligt min mening bara ett Synatiskt socker. Snarare än:

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

… användare kan ganska mycket förkorta frågan som:

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

den förkortade frågan är utan tvekan trevlig för ögonen. Men i. NET world kan Entity Framework föredras för dataorienterade mjukvaruapplikationer; som ett resultat av vilket det inte finns något behov av SQL-textkommandon. Utvecklare låter bara ramverket generera optimala frågor för dem medan de är inriktade på abstraktioner på hög nivå. Med denna logik är den tilltalande effekten av MATCH plötsligt irrelevant. Värre är att det för närvarande inte finns någon färdplan för att stödja dessa graffunktioner i Entity Framework (Core).

jämfört med Neo4j, titta igen på ovanstående frågor, är det oundvikligt för användare att böja sin graf tänkesätt i relationsdatabas världen. Vi måste fortfarande förklara i förväg vilka tabeller, i FROM klausul ,för att utföra matchningen (borde det snarare vara grafen som betraktas som en ’traverserbar hel sak’ och man behöver inte bry sig om detaljerad dataorganisation?). När man känner till pilriktningen i MATCH är ett måste, kommer användarna att inse 1-1-kartläggningen mellan MATCH – klausulen och den ursprungliga JOIN – klausulen, i den meningen att man måste skilja Källnoden och Målnoden. Däremot tillåter Neo4js Cypher-syntax att bortse från denna skillnad. Alla dessa är inte nödvändigtvis en spelväxlare; utan helt enkelt en fråga om bekvämlighet och glädje av utveckling. (Senare, i 1: A Studiefallet, ser vi att vi måste göra en UNION ALL på grund av detta.)

en nyckel till hög prestanda för inbyggd grafdatabas vid korsning av anslutna data är indexfri närhet. Tyvärr finns det inget sådant med Graffunktionen i SQL Server:

vi upprätthåller inte en adjacency-lista på varje nod; istället lagrar vi edge-data i tabeller. Eftersom det är en relationsdatabas var lagring av data i form av tabeller ett mer naturligt val för oss

en annan irriterande fråga är bristen på visualiseringsverktyg skräddarsydda mot diagram, för både schema och data. Som en lösning kan användare fortfarande skapa ett Schemadiagram i SSMS, men dessa noder och Kanttabeller hamnar som enskilda, frånkopplade tabeller även om de har Kantbegränsningar. Bland annat bör Grafteknik också ge visuella överklaganden, vilket underlättar för användare att konstruera korrekta frågor. Att sakna sådana verktyg är frustrerande och skadligt för utvecklarens produktivitet.

Diagram för Graftabeller

så vad gör vi för att få Grafschemat? Jag antar att vi öppnar varje Kantbord för att manuellt se begränsningarna, och sedan resonera på dem, med hjälp av ett papper, för att räkna ut hela Grafschemat.

graphs Kantbegränsningar

när det gäller datavisualisering försökte jag Microsoft Power BI med Force-Directed Graph addon. Men det här verktyget är inte gratis, och det stöder inte SQL Servers graffunktioner out-of-the-box, vilket betyder att det ser noderna och Kanttabellerna som vanliga databastabeller. Genom att noggrant undersöka kolumnlistorna finns det konstiga kolumnnamn, t.ex. graph_id_...,from_obj_id.... Det är interna kolumner, som automatiskt genereras när du skapar nod/Kantbord, otillgängliga från utsidan. Ett fel höjs, enligt nedan, av Power BI: s Get Data-funktion om åtkomst till dessa kolumner.

Power BI – ”Get Data” från SQL Servers Graftabeller

för att lösa problemet måste man skapa en Databasvy som endast innehåller relevanta/nåbara kolumner, t. ex. from_id och to_id i Kantbordet, node_id i Nodtabellen. Sedan i Power BI, extrahera data genom den vyn. Förhoppningsvis misstar jag mig inte, Power BI: s Kraftstyrda Graf verkar kräva en enda tabell som består av kolumner Source, Target, Weight, Source Type, Target Type, Link Type. Vårt provschema är förenklat; vilket skapar denna enda tabell är trivial. Vad händer om schemat innehöll +20 noder tabeller och + 10 kanter tabell, kan vi sluta med en enda tabell för att visualisera hela grafen med Power BI?

# uppdaterad den 04.07.2020: Vid närmare eftertanke är detta säkert möjligt även om det fortfarande är besvärligt. Man bör börja vid Kanttabeller, i vilka $from_id och $to_id förenas mot relevanta Nodtabeller för att översätta till delade egenskaper för alla noder, t.ex. Nameeller Id. Gör sedan UNION ALL för alla att kombinera i den slutliga enda tabellen som krävs av Power BI.

att fråga efter noder och kanter är en av möjligheterna med Grafteknik. Vad som kan göra att en grafdatabas sticker ut är det inbyggda men ändå utbyggbara stödet för grafalgoritmer, som PageRank och Louvain Community Detection (aka. Louvain modularitet). Tyvärr igen, inga sådana analysfunktioner tillgängliga i SQL Servers graf, som sagt:

vissa grafdatabaser ger dedikerade graf analytiska funktioner som” kortaste vägen ”eller” sidrankning.”SQL Graph tillhandahåller inga sådana funktioner i den här versionen. Återigen kan T-SQL-slingor och temp-tabeller användas för att skriva en lösning för dessa scenarier.

i Neo4j är dessa algoritmer lätt tillgängliga i produktionsklass tack vare Graph Data Science Library. Plus, det är öppen källkod. I allmänhet är dokumentation till hjälp, men ibland inte tillräckligt. Med öppen källkod kan utvecklare ladda ner och dyka in i hur en specifik algoritm implementeras; eller till och med kompilera om biblioteket, med ytterligare loggningsinformation, för att ytterligare förstå. Det är möjligt att implementera PageRank i SQL, men mer komplex algoritm som Louvain-modularitet kan vara utmanande. Ändå föredrar många mjukvaruingenjörer att vara mer besvärade med affärslogik, istället för att fastna med tekniska detaljer på låg nivå.

sist men inte minst, enligt min mening är vanligt Tabeluttryck ett slags härledda tabeller. Sedan SQL Server 2019 ska denna teknik officiellt vara användbar med Graf:

Common Table Expression (CTE) med Graftabeller och matchklausul

men om följande vy skapas är det möjligt:

Visa skapande med Graftabeller och matchklausul

jag tror att detta är ett tecken på inkonsekvens. Den 2: a metoden kräver en permanent skapad vy eftersom det inte är möjligt att skapa tillfällig vy i SQL Server. Normalt övervinner användarna detta med CTE, men igen fungerar CTE inte med graf, som visat ovan.

Studiefall

ett exempelscenario: studenter och lärare.

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)

SQL Server 2019s Graf:

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

fall 1: alla inkommande och utgående anslutningar av noder

Motivation: att räkna dessa anslutningar för varje nod är ett sätt att ta reda på vilka som är viktigast.

Neo4j ’ scipher:

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

SQL Server 2019s Diagram:

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

anmärkningar: SQL-versionen är inte bara längre utan också mer obekväm eftersom pilens riktning i MATCH alltid måste beaktas.

Fall 2: Topp längsta banor

Motivation: långa beroendekedjor är benägna att vara bräckliga. Till exempel biblioteksberoende.

Neo4j ’ scipher:

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

SQL Server 2019s Diagram:

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

anmärkningar: I SQL Server-versionen måste man använda sig av rekursiv vanlig Tabelluttrycksteknik. Det omfattar ganska mycket Relationsdatabastänkande för att lösa Grafproblem.

slutsats

i Grafdomänen är en SQL-Servers SQL-kommando, med graffunktion som används eller inte, som används för att ta itu med Grafproblem, vanligtvis mycket längre och mer komplex jämfört med Neo4js Cypher. Detta leder till en implikation att koden blir mer tidskrävande att utveckla och svår att senare underhålla och utvidga. En annan ingenjör eller till och med den ursprungliga, som tittar på samma kodavsnitt en månad senare, kommer att finna det frustrerande att förstå alla dess aspekter. En välkänd term för att beskriva denna situation är teknisk skuld.

kombinera alla ovannämnda punkter, från kodaspekt, till funktionsstöd, till verktygs-/biblioteksekosystem, saknar SQL Servers Graffunktionalitet för närvarande, även om det är uppmuntrande, förväntningarna.

SQL Server är extremt Mogen med avseende på relationsdatabas, men helt klart en nybörjare i Grafdatabasen. Detta Grafstöd anses troligen finnas i Relationsdatabasmentalitet.

Related Post

Leave A Comment