Articles

Graph von Microsoft SQL Server – Ein Versuch, der (vorerst) zu kurz kam)

Posted by admin
 TRAN Ngoc Thach
TRAN Ngoc Thach

Folgen

Jun 29, 2020 · 9 min Lesezeit

Haftungsausschluss: Die Meinung in diesem Artikel ist meine allein, basierend auf meiner begrenzten Exposition gegenüber SQL Server Graph. Ich bin kein Experte für SQL Server. Ich könnte in Richtung Neo4j voreingenommen sein.

Mit dem zunehmenden Einsatz von Graph Database und der Dominanz von Neo4j in diesem Nischenmarkt sowie dem deutlichen Leistungsgewinn bei der Abfrage hochgradig vernetzter Daten ist es verständlich, dass Microsoft nicht aus diesem Megatrend herausgelassen werden möchte.

Ab SQL Server 2017 bot SQL Server Diagrammfunktionen mit der Einführung des SchlüsselwortsMATCH. In der Version 2019 wurden unter anderem zwei neue bemerkenswerte Funktionen hinzugefügt: Edge-Einschränkungen und die Verwendung abgeleiteter Tabellen in MATCH -Abfragen. Tauchen in dieser Technologie lange genug, ich habe den Eindruck, dass, ab sofort:

  • Die Diagrammunterstützung in SQL Server ist noch weit von einer vollwertigen Diagrammdatenbank entfernt, z. B. Neo4j.
  • Die Hinzufügung von Funktionen erfolgt langsam inkrementell.
  • Die Graph-Funktion wird widerwillig in relationale Datenbanksysteme integriert.

Kommen wir ins Detail!

Pros & Cons

Das SchlüsselwortMATCH ist meiner Meinung nach nur ein syntaktischer Zucker. Anstatt:

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

… benutzer können die Abfrage so ziemlich verkürzen:

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

Die verkürzte Abfrage ist zweifellos angenehm für die Augen. In der .NET-Welt kann Entity Framework jedoch für datenorientierte Softwareanwendungen bevorzugt werden. Entwickler lassen das Framework einfach optimale Abfragen für sie generieren, während sie sich auf Abstraktionen auf hoher Ebene konzentrieren. Durch diese Logik ist der erfreuliche Effekt von MATCH plötzlich irrelevant. Schlimmer noch, im Moment gibt es sogar keine Roadmap zur Unterstützung dieser Diagrammfunktionen in Entity Framework (Core).

Im Vergleich zu Neo4j, wenn man sich die obigen Abfragen noch einmal ansieht, ist es für Benutzer unvermeidlich, ihre grafische Denkweise in die relationale Datenbankwelt zu biegen. Wir müssen noch im Voraus deklarieren, welche Tabellen in der Klausel FROM den Abgleich durchführen sollen (Sollte es eher der Graph sein, der als ‚durchfahrbares Ganzes‘ betrachtet wird, und man muss sich nicht um detaillierte Daten kümmern)?). Wenn die Kenntnis der Pfeilrichtung in MATCH ein Muss ist, erkennen Benutzer die 1-1-Zuordnung zwischen MATCH -Klausel und der ursprünglichen JOIN -Klausel in dem Sinne, dass der Quellknoten und der Zielknoten unterschieden werden müssen. Im Gegensatz dazu erlaubt die Cypher-Syntax von Neo4j, diese Unterscheidung zu ignorieren. All dies ist nicht unbedingt ein Game-Changer; sondern einfach eine Frage der Bequemlichkeit und der Freude an der Entwicklung. (Später, im 1. Studienfall, werden wir sehen, dass wir aus diesem Grund eine UNION ALL machen müssen.)

Ein Schlüssel zur hohen Leistung der nativen Diagrammdatenbank beim Durchlaufen verbundener Daten ist die indexfreie Adjazenz. Leider gibt es so etwas mit der Diagrammfunktion in SQL Server nicht:

Wir führen nicht auf jedem Knoten eine Adjazenzliste, sondern speichern Kantendaten in Tabellen. Da es sich um eine relationale Datenbank handelt, war das Speichern von Daten in Form von Tabellen für uns eine natürlichere Wahl

Ein weiteres ärgerliches Problem ist das Fehlen von Visualisierungstools, die sowohl für Schema als auch für Daten auf Graph zugeschnitten sind. Als Problemumgehung können Benutzer weiterhin ein Schemadiagramm in SSMS erstellen, aber diese Knoten- und Kantentabellen enden als einzelne, getrennte Tabellen, selbst wenn sie Kantenbeschränkungen haben. Unter anderem sollte die Graph-Technologie auch visuelle Appelle bringen, die es den Benutzern erleichtern, korrekte Abfragen zu erstellen. Das Fehlen solcher Tools ist frustrierend und beeinträchtigt die Produktivität der Entwickler.

Diagramm für Diagrammtabellen

Was tun wir also, um das Diagrammschema zu erhalten? Ich denke, wir öffnen jede Kantentabelle, um die Einschränkungen manuell anzuzeigen, und begründen sie dann mit Hilfe eines Blattes Papier, um das gesamte Diagrammschema herauszufinden.

Graph’s Edge Constraints

In Bezug auf die Datenvisualisierung habe ich Microsoft Power BI mit Force-Directed Graph Addon ausprobiert. Dieses Tool ist jedoch nicht kostenlos und unterstützt die Diagrammfunktionen von SQL Server nicht sofort, dh es werden die Knoten- und Kantentabellen als normale Datenbanktabellen angezeigt. Bei näherer Betrachtung der Spaltenlisten gibt es seltsam aussehende Spaltennamen, z. B. graph_id_...,from_obj_id... . Dies sind interne Spalten, die beim Erstellen von Knoten- / Kantentabellen automatisch generiert werden und von außen nicht zugänglich sind. Ein Fehler wird wie unten von der Get Data-Funktion von Power BI ausgelöst, wenn auf diese Spalten zugegriffen wird.

Power BI – „Daten abrufen“ aus den Diagrammtabellen von SQL Server

Um dieses Problem zu umgehen, muss eine Datenbankansicht erstellt werden, die nur relevante / erreichbare Spalten enthält, z. from_id und to_id in der Kantentabelle, node_id in der Knotentabelle. Extrahieren Sie dann in Power BI die Daten über diese Ansicht. Hoffentlich täusche ich mich nicht, das Force Directed Graph von Power BI scheint eine einzige Tabelle zu erfordern, die aus Spalten besteht Source, Target, Weight, Source Type, Target Type, Link Type. Unser Beispielschema ist simpel; Daher ist das Erstellen dieser einzelnen Tabelle trivial. Was wäre, wenn das Schema +20 Knotentabellen und +10 Kantentabellen enthalten würde, könnten wir am Ende eine einzige Tabelle erhalten, um das gesamte Diagramm mit Power BI zu visualisieren?

#Aktualisiert am 04.07.2020: Beim zweiten Gedanken ist dies sicherlich möglich, obwohl es immer noch umständlich ist. Man sollte bei Kantentabellen beginnen, in denen jeweils $from_id und $to_id mit relevanten Knotentabellen verknüpft sind, um gemeinsame Eigenschaften aller Knoten zu erhalten, z. B. Name oder Id. Führen Sie dann UNION ALL aus, damit alle in der von Power BI erforderlichen endgültigen Einzeltabelle zusammengefasst werden.

Die Abfrage von Knoten und Kanten ist eine der Möglichkeiten der Graphentechnologie. Was eine Diagrammdatenbank auszeichnen kann, ist die integrierte und dennoch erweiterbare Unterstützung für Diagrammalgorithmen wie PageRank und Louvain Community Detection (aka. Louvain Modularität). Leider sind wieder keine solchen Analysefunktionen im Diagramm von SQL Server verfügbar, wie gesagt:

Einige Graph-Datenbanken bieten dedizierte Graph-Analysefunktionen wie „shortest path“ oder „Page Rank“.“ SQL Graph bietet in dieser Version keine solchen Funktionen. Auch hier können T-SQL-Schleifen und temporäre Tabellen verwendet werden, um eine Problemumgehung für diese Szenarien zu schreiben.

In Neo4j sind diese Algorithmen dank der Graph Data Science Library in Produktionsqualität verfügbar. Plus, es ist Open-Source. Im Allgemeinen ist die Dokumentation hilfreich, aber manchmal nicht ausreichend. Mit Open-Source können Entwickler herunterladen und in die Implementierung eines bestimmten Algorithmus eintauchen. oder sogar die Bibliothek mit zusätzlichen Protokollierungsinformationen neu kompilieren, um sie besser zu verstehen. Die Implementierung von PageRank in SQL ist möglich, komplexere Algorithmen wie die Louvain-Modularität können jedoch eine Herausforderung darstellen. Dennoch ziehen es viele Software-Ingenieure vor, sich mehr mit der Geschäftslogik zu beschäftigen, anstatt sich mit technischen Details auf niedriger Ebene zu beschäftigen.

Last but not least ist Common Table Expression meiner Ansicht nach eine Art abgeleitete Tabelle. Seit SQL Server 2019 soll diese Technik offiziell mit Graph funktionieren:

Common Table Expression (CTE) mit Diagrammtabellen und MATCH Klausel

Aber wenn nach der Erstellung der ANSICHT, ist es machbar:

Ansichtserstellung mit Diagrammtabellen und MATCH-Klausel

Ich denke, dies ist ein Zeichen für Inkonsistenz. Der 2. Ansatz erfordert eine dauerhaft erstellte Ansicht, da es nicht möglich ist, eine temporäre Ansicht in SQL Server zu erstellen. Normalerweise überwinden Benutzer dies mit CTE, aber auch hier funktioniert CTE nicht mit Graph, wie oben gezeigt.

Studienfälle

Ein Beispielszenario: Schüler und Lehrer.

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)

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

Fall 1: Alle eingehenden und ausgehenden Verbindungen von Knoten

Motivation: Das Zählen dieser Verbindungen für jeden Knoten ist eine Möglichkeit, herauszufinden, welche am wichtigsten sind.

Neo4j’Schlüssel:

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

Diagramm von SQL Server 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

Bemerkungen: Die SQL-Version ist nicht nur länger, sondern auch unpraktischer, da die Pfeilrichtung in MATCH immer berücksichtigt werden muss.

Fall 2: Top longest paths

Motivation: Lange Abhängigkeitsketten neigen dazu, zerbrechlich zu sein. Zum Beispiel Bibliotheksabhängigkeit.

Neo4j’Schlüssel:

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

Diagramm von SQL Server 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

Bemerkungen: In der SQL Server-Version muss auf die rekursive allgemeine Tabellenausdruckstechnik zurückgegriffen werden. Es umfasst so ziemlich die Denkweise relationaler Datenbanken, um Diagrammprobleme zu lösen.

Fazit

In der Graph-Domäne ist der SQL-Befehl eines SQL-Servers mit oder ohne Graph-Funktion, der zur Lösung von Graph-Problemen verwendet wird, im Vergleich zu Neo4js Cypher in der Regel viel länger und komplexer. Dies führt zu der Implikation, dass die Entwicklung des Codes zeitaufwendiger und später schwieriger zu warten und zu erweitern ist. Ein anderer Ingenieur oder sogar der ursprüngliche, der sich einen Monat später dasselbe Code-Snippet ansieht, wird es frustrierend finden, alle seine Aspekte zu erfassen. Ein bekannter Begriff, um diese Situation zu beschreiben, sind technische Schulden.

Durch die Kombination aller oben genannten Punkte, vom Codeaspekt über die Feature-Unterstützung bis hin zum Tool- / Bibliotheks-Ökosystem, bleibt die Graph-Funktionalität von SQL Server derzeit zwar ermutigend, aber hinter den Erwartungen zurück.

SQL Server ist in Bezug auf relationale Datenbanken extrem ausgereift, aber eindeutig ein Neuling in der Diagrammdatenbank. Diese Diagrammunterstützung wird wahrscheinlich als in relationalen Datenbanksystemen enthalten angesehen.

Related Post

Leave A Comment