Articles

Microsoft SQL Server ‘ S Graph – et forsøk som ble kort (for nå)

Posted by admin
TRAN Ngoc Thach
TRAN Ngoc Thach

Følg

Jun 29, 2020 * 9 min lese

Ansvarsfraskrivelse: meningen i denne artikkelen er min alene, basert på min begrensede eksponering FOR SQL Servers Graf. Jeg er på ingen måte en ekspert PÅ SQL Server. Jeg kan være partisk mot Neo4j.

med den økende bruken Av Grafdatabase Og dominansen Til Neo4j i Dette nisjemarkedet, samt den betydelige ytelsesgevinsten i spørring av høyt tilkoblede data, Er Det forståelig At Microsoft ikke vil bli utelatt av denne mega-trenden.

FRA SQL Server 2017 tilbød SQL Server Graffunksjonaliteter, med introduksjonen avMATCH – søkeordet. I 2019-versjonen ble blant annet to nye bemerkelsesverdige funksjoner lagt til: Kantbegrensninger og bruk av avledede tabeller i MATCH – spørringer. Dykking i denne teknologien lenge nok, jeg har et inntrykk av at, som nå:

  • Grafstøtten I SQL Server er fortsatt langt fra en fullverdig Grafdatabase, For Eksempel Neo4j.
  • tillegg av funksjonalitet er sakte inkrementell.
  • Grafen funksjonen er motvillig montert I Relasjonsdatabase tankesett.

La oss komme inn i detaljer!

Pros & Ulemper

MATCH søkeordet er etter min mening bare Et Syntatisk Sukker. I stedet for:

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

… brukere kan ganske mye forkorte spørringen som:

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

den forkortede spørringen er utvilsomt behagelig for øynene. I. NET world kan Imidlertid Entity Framework foretrekkes for dataorienterte programmer; som et resultat av hvilket DET ikke er behov for SQL ren tekst-kommandoer. Utviklere bare la rammen generere optimale spørringer for dem mens de er fokusert på høyt nivå abstraksjoner. Ved denne logikken er den behagelige effekten av MATCH plutselig irrelevant. Verre, for øyeblikket er det enda ingen Veikart for å støtte Disse Graffunksjonene i Entity Framework (Core).

Sammenligning Med Neo4j, ser igjen på de ovennevnte spørringene, er det uunngåelig for brukerne å bøye Sin Graftankegang til Relasjonsdatabaseverden. Vi har fortsatt å erklære på forhånd hvilke tabeller ,i FROM klausul, for å utføre samsvarende (Bør Det heller Være Grafen anses som en ‘traversable hele greia’ og man trenger ikke å bry seg om detaljert data organisasjon ?). Når man kjenner pilens retning i MATCH er et must, kommer brukerne til å innse 1-1-kartleggingen mellom MATCH – klausulen og den opprinnelige JOIN – klausulen, i den forstand at Man må skille Kildenoden og Målnoden. I kontrast, Neo4j Cypher syntaks gjør det mulig å se bort fra dette skillet. Alle disse er ikke nødvendigvis en spillveksler; men bare et spørsmål om bekvemmelighet og glede av utvikling. (Senere, i 1st Study Case, ser vi at vi må gjøre en UNION ALL på grunn av dette.)

en nøkkel til høy ytelse av innfødt Grafdatabase i å krysse tilkoblede data er indeksfri adjacency. Dessverre er det ikke noe slikt Med Graffunksjon I SQL Server:

Vi opprettholder ikke en adjacency liste på hver node; i stedet lagrer vi kantdata i tabeller. Fordi det er en relasjonsdatabase, var lagring av data i form av tabeller et mer naturlig valg for oss

Et annet irriterende problem er mangelen på visualiseringsverktøy skreddersydd Mot Graf, for både skjema og data. Som en løsning kan brukerne fortsatt lage Et Skjemadiagram I SSMS, men Disse Nodene og Kanttabellene ender opp som individuelle, frakoblede tabeller, selv om De har Kantbegrensninger. Blant Annet Bør Grafteknologi også gi visuelle appeller, slik at brukerne kan konstruere riktige søk. Mangler slike verktøy er frustrerende og skadelig for utviklernes produktivitet.

Diagram For Graftabeller

så hva gjør vi for Å få Grafskjemaet? Jeg antar at vi åpner hver Kanttabell for å se begrensningene manuelt, og deretter begrunne dem, ved hjelp av et stykke papir, for å finne ut Hele Grafskjemaet.

Grafens Kantbegrensninger

Når det gjelder datavisualisering, prøvde Jeg Microsoft Power BI med Force-Directed Graph addon. Dette verktøyet er imidlertid ikke gratis, og det støtter IKKE SQL Servers Graffunksjoner ut-av-boksen, noe som betyr at Det ser Nodene og Kantene tabeller som vanlige databasetabeller. Ved å undersøke kolonnelistene nøye, er det rare kolonnenavn, for eksempel graph_id_...,from_obj_id.... De er interne kolonner, automatisk generert når du oppretter Node / Edge tabeller, utilgjengelige fra utsiden. Det oppstår en feil, som nedenfor, Av Power BIS Get Data-funksjon hvis du får tilgang til disse kolonnene.

Power BI- «Hent Data» fra SQL Servers Graftabeller

for å løse dette problemet må man opprette En Databasevisning som bare inneholder relevante / tilgjengelige kolonner, f. eks. from_id og to_id I Kanttabell, node_id I Nodetabell. Deretter i Power BI, trekk ut dataene gjennom Den Visningen. Forhåpentligvis er Jeg ikke feil, Power BIS Kraftstyrte Graf synes å kreve et enkelt bord som består av kolonner Source, Target, Weight, Source Type, Target Type, Link Type. Vårt utvalgsskjema er forenklet; dermed skaper dette enkeltbordet trivielt. Hva om skjemaet inneholdt + 20 Noder Tabeller og + 10 Kanter Tabell, kan vi ende opp med et enkelt bord for å visualisere Hele Grafen med Power BI?

# Oppdatert på 04.07.2020: På andre tanke er dette sikkert mulig, selv om det fortsatt er tungvint. Man bør starte Ved Kanter Tabeller, i hver av Dem $from_id og $to_id er sammen mot relevante Noder Tabeller for å oversette til felles egenskaper for Alle Noder, f.eks Name eller Id. Så gjør UNION ALL for alle å kombinere i det endelige enkeltbordet som Kreves Av Power BI.

Spørring etter noder og kanter er en av mulighetene For Grafteknologi. Det som kan få En Grafdatabase til å skille seg ut, er den innebygde, men utvidbare støtten til Grafalgoritmer, for eksempel PageRank Og Louvain Community Detection (aka. Louvain modularitet). Dessverre igjen, ingen slike analysefunksjoner tilgjengelig i SQL Servers Graf, som sagt:

Noen grafdatabaser gir dedikerte grafanalytiske funksjoner som «korteste sti» eller » pagerank.»SQL Graph gir ikke slike funksjoner i denne versjonen. IGJEN KAN T-SQL-looper og temp-tabeller brukes til å skrive en løsning for disse scenariene.

I Neo4j er disse algoritmene lett tilgjengelige på produksjonsklasse, takket Være Graph Data Science Library. I tillegg er det åpen kildekode. Generelt er dokumentasjon nyttig, men noen ganger ikke tilstrekkelig. Med åpen kildekode kan utviklere laste ned og dykke inn i hvordan en bestemt algoritme implementeres; eller til og med rekompilere biblioteket, med ekstra loggingsinformasjon, for å forstå ytterligere. Implementering PageRank I SQL er mulig, men mer kompleks algoritme som Louvain modularitet kan være utfordrende. Likevel foretrekker mange programvareingeniører å være mer plaget med forretningslogikk, i stedet for å bli slått ned med tekniske detaljer på lavt nivå.

Sist Men Ikke minst, Etter mitt syn Er Vanlig Tabelluttrykk en slags avledede tabeller. SIDEN SQL Server 2019 er denne teknikken offisielt ment å være brukbar Med Graph:

Felles Tabelluttrykk (CTE) med Graftabeller og SAMSVARSKLAUSUL

, men hvis du følger VISNINGSOPPRETTELSEN, kan den:

Vis opprettelse med Graftabeller og KAMPKLAUSUL

jeg tror dette er et tegn på inkonsekvens. 2. tilnærming krever en Permanent Opprettet Visning som Det ikke er mulig å opprette Midlertidig Visning I SQL Server. Normalt brukere overvinne dette MED CTE, men IGJEN CTE fungerer ikke Med Graph, som vist ovenfor.

Studiesaker

et eksempelscenario: Studenter og Lærere.

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)

Grafen TIL SQL Server-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'));

Case 1: alle innkommende og utgående tilkoblinger av noder

Motivasjon: Å Telle disse tilkoblingene for hver node er en måte å finne ut hvilke som er viktigst.

Neo4j ‘ scypher:

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

Sql Server 2019s Graf:

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

Kommentarer: SQL-versjonen er ikke bare lengre, men også mer ubeleilig da pilens retning i MATCH alltid må tas i betraktning.

Sak 2: Topp lengste baner

Motivasjon: Lange avhengighetskjeder er tilbøyelige til å være skjøre. For eksempel bibliotekets avhengighet.

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

Sql Server 2019s Graf:

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

Kommentarer: I SQL Server-versjonen må man bruke Rekursiv Felles Tabelluttrykksteknikk. Det omfatter ganske Mye Relasjonsdatabase tankesett for å løse Grafproblemer.

Konklusjon

I Graph-domenet er EN SQL Servers SQL-kommando, med Graffunksjon brukt eller ikke, brukt til å takle Grafproblemer, vanligvis mye lengre og mer kompleks, i forhold Til Neo4js Cypher. Dette fører til en implikasjon at koden vil være mer tidkrevende å utvikle, og vanskelig å senere vedlikeholde og utvide. En annen ingeniør eller til og med den opprinnelige, ser på samme kodebit en måned senere, vil finne det frustrerende å forstå alle aspekter. Et kjent begrep for å beskrive denne situasjonen er teknisk gjeld.

Kombinere alle de nevnte punktene, fra kodeaspekt, til funksjonsstøtte, til verktøy / bibliotekøkosystem, SQL Servers Graffunksjonalitet for tiden, selv om det er oppmuntrende, faller kort av forventningene.

SQL Server er ekstremt moden med Hensyn Til Relasjonsdatabase, men klart en nybegynner i Grafdatabasen. Denne Grafen støtte er trolig anses å være inneholdt I Relasjonsdatabase mentalitet.

Related Post

Leave A Comment