Articles

Wykres Microsoft SQL Server – próba, która się nie powiodła (na razie)

Posted by admin
TRAN Ngoc Thach
TRAN Ngoc Thach

Obserwuj

Cze 29, 2020 * 9 min czytać

Zastrzeżenie: opinia w tym artykule jest tylko moja, w oparciu o moją ograniczoną ekspozycję na wykres SQL Server. Nie jestem w żaden sposób ekspertem od SQL Server. Mogę być stronniczy w stosunku do Neo4j.

wraz z rosnącym wykorzystaniem bazy danych Graph i dominacją Neo4j na tym niszowym rynku,a także znaczącym wzrostem wydajności w wyszukiwaniu silnie powiązanych danych, jest zrozumiałe, że Microsoft nie chce zostać pominięty w tym mega-trendzie.

począwszy od SQL Server 2017, SQL Server oferował funkcje Wykresów, wraz z wprowadzeniem słowa kluczowegoMATCH. W wersji 2019 dodano m.in. dwie nowe, godne uwagi funkcje: ograniczenia krawędzi oraz wykorzystanie tabel pochodnych w zapytaniach MATCH. Nurkowanie w tej technologii wystarczająco długo, mam wrażenie, że na razie:

  • obsługa Wykresów w SQL Server jest nadal daleka od pełnej bazy Wykresów, np. Neo4j.
  • dodawanie funkcjonalności jest powoli przyrostowe.
  • funkcja grafu jest wbudowana w relacyjną bazę danych.

przejdźmy do szczegółów!

plusy& minusy

słowo kluczowe MATCH jest moim zdaniem jedynie cukrem składniowym. Zamiast:

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żytkownicy mogą dość dużo skrócić zapytanie jako:

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

skrócone zapytanie jest niewątpliwie przyjemne dla oczu. Jednak w. Net world Entity Framework może być preferowany dla aplikacji zorientowanych na dane; w wyniku czego nie ma potrzeby stosowania poleceń tekstowych SQL. Programiści po prostu pozwalają frameworkowi generować dla nich optymalne zapytania, podczas gdy koncentrują się na abstrakcjach wysokiego poziomu. Zgodnie z tą logiką, przyjemny efekt MATCH jest nagle nieistotny. Co gorsza, w tej chwili nie ma nawet mapy drogowej wspierającej te możliwości Wykresów w Entity Framework (Core).

porównując do Neo4j, patrząc ponownie na powyższe zapytania, nieuniknione jest, aby użytkownicy naginali swoje myślenie Wykresów w relacyjny świat baz danych. Musimy jeszcze z góry zadeklarować, które tabele, w klauzuli FROM, mają przeprowadzić dopasowanie (czy powinien to być raczej Wykres uważany za „całość przejezdną” i nie trzeba dbać o szczegółową organizację danych?). Gdy znajomość kierunku strzałki w MATCH jest koniecznością, użytkownicy zdają sobie sprawę z mapowania 1-1 między MATCH klauzulą a oryginalną klauzulą JOIN, w tym sensie, że trzeba odróżnić węzeł źródłowy od węzła docelowego. Natomiast składnia szyfrowa Neo4j pozwala zignorować to rozróżnienie. Wszystko to niekoniecznie zmienia zasady gry, ale jest po prostu kwestią wygody i radości z rozwoju. (Później, w pierwszym przypadku badania, zobaczymy, że musimy zrobić UNION ALL z tego powodu.)

jednym z kluczy do wysokiej wydajności natywnej bazy danych grafów w przeszukiwaniu połączonych danych jest przyleganie bez indeksów. Niestety w SQL Server nie ma czegoś takiego z funkcją Graph:

nie utrzymujemy listy adjacency na każdym węźle; zamiast tego przechowujemy dane krawędzi w tabelach. Ponieważ jest to relacyjna baza danych, przechowywanie danych w formie tabel było dla nas bardziej naturalnym wyborem

kolejnym irytującym problemem jest brak narzędzi do wizualizacji dostosowanych do grafu, zarówno dla schematu, jak i danych. Jako obejście, użytkownicy mogą nadal tworzyć schemat w SSMS, ale te tabele węzłów i krawędzi kończą się jako pojedyncze, rozłączone tabele, nawet jeśli mają ograniczenia krawędzi. Między innymi Technologia graficzna powinna również przynosić odwołania wizualne, ułatwiając użytkownikom konstruowanie prawidłowych zapytań. Brak takich narzędzi jest frustrujący i niekorzystny dla produktywności programistów.

Diagram dla tabel wykresów

więc co zrobić, aby uzyskać schemat wykresu? Myślę, że otwieramy każdą tabelę krawędzi, aby ręcznie zobaczyć ograniczenia, a następnie, za pomocą kartki papieru, odczytać cały schemat wykresu.

ograniczenia krawędzi grafu

jeśli chodzi o wizualizację danych, próbowałem Microsoft Power BI Z Force-Directed graph addon. Jednak to narzędzie nie jest darmowe i nie obsługuje możliwości Wykresów SQL Server od razu, co oznacza, że widzi tabele węzłów i krawędzi jako normalne tabele bazy danych. Przyglądając się dokładnie listom kolumn, pojawiają się dziwnie wyglądające nazwy kolumn, np. graph_id_...,from_obj_id.... Są to kolumny wewnętrzne, generowane automatycznie podczas tworzenia tabel węzłów / krawędzi, niedostępne z zewnątrz. Błąd jest podnoszony, jak poniżej, przez funkcję pobierania danych Power BI, jeśli uzyskujesz dostęp do tych kolumn.

Power BI – „Get Data” from SQL Server ’ s Graph tables

aby obejść ten problem, należy utworzyć widok bazy danych zawierający tylko odpowiednie/osiągalne kolumny, np. from_id i to_id w tabeli krawędzi, node_id w tabeli węzłów. Następnie w usłudze Power BI wyodrębnij dane za pomocą tego widoku. Mam nadzieję, że się nie mylę, Wykres Power BI w kierunku siły wydaje się wymagać jednej tabeli, która składa się z kolumn Source, Target, Weight, Source Type, Target Type, Link Type. Nasz przykładowy schemat jest uproszczony, dlatego tworzenie tej pojedynczej tabeli jest trywialne. Co jeśli schemat zawierał tabele + 20 węzłów i tabelę + 10 krawędzi, czy moglibyśmy skończyć z pojedynczą tabelą, aby wizualizować cały Wykres za pomocą Power BI?

#Zaktualizowano 04.07.2020: Po namyśle, jest to z pewnością możliwe, nawet jeśli jest to nadal uciążliwe. Należy zacząć od tabel krawędzi, w każdej z nich $from_id i $to_id są połączone z odpowiednimi tabelami węzłów, aby przetłumaczyć je na współdzielone właściwości wszystkich węzłów, np. Name lub Id. Następnie wykonaj UNION ALL dla wszystkich, aby połączyć się w finałowym pojedynczym stole wymaganym przez Power BI.

Zapytanie o węzły i krawędzie jest jedną z możliwości technologii grafów. To, co może wyróżniać bazę danych grafów, to wbudowana, ale rozszerzalna obsługa algorytmów grafów, takich jak PageRank i Louvain Community Detection (aka. Modułowość Louvain). Niestety ponownie, nie ma takich funkcji analitycznych dostępnych w wykresie SQL Server, jak powiedział:

niektóre bazy danych grafów zapewniają dedykowane funkcje analizy grafów, takie jak „najkrótsza ścieżka” lub ” page rank.”SQL Graph nie udostępnia żadnych takich funkcji w tym wydaniu. Ponownie, pętle T-SQL i tabele temp mogą być użyte do napisania obejścia tych scenariuszy.

w Neo4j algorytmy te są łatwo dostępne na poziomie produkcyjnym, dzięki bibliotece Graph Data Science Library. Plus, jest open-source. Ogólnie rzecz biorąc, dokumentacja jest pomocna, ale czasami niewystarczająca. Dzięki oprogramowaniu open-source programiści mogą pobierać i analizować sposób implementacji określonego algorytmu; a nawet przekompilować bibliotekę z dodatkowymi informacjami o logowaniu, aby lepiej zrozumieć. Implementacja PageRank w SQL jest możliwa, ale bardziej złożony algorytm, taki jak modułowość Louvain, może być wyzwaniem. Niemniej jednak wielu inżynierów oprogramowania woli bardziej przejmować się logiką biznesową, zamiast ugrzęzać w niskopoziomowych szczegółach technicznych.

wreszcie, moim zdaniem, wyrażenie Common Table jest rodzajem tabel pochodnych. Od SQL Server 2019 technika ta oficjalnie ma być wykonalna z grafem:

Common table Expression (CTE) z tabelami Wykresów i klauzulą dopasowania

ale jeśli po utworzeniu widoku, jest to do-able:

Tworzenie widoku z tabelami Wykresów i klauzulą dopasowania

myślę, że jest to oznaka niespójności. Drugie podejście wymaga permanentnie utworzonego widoku, ponieważ nie jest możliwe utworzenie tymczasowego widoku w SQL Server. Zwykle użytkownicy pokonują to za pomocą CTE, ale znowu CTE nie działa z grafem, jak pokazano powyżej.

przypadki studiowania

przykładowy scenariusz: uczniowie i nauczyciele.

Cypher Neo4j:

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)

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

Przypadek 1: Wszystkie połączenia przychodzące i wychodzące węzłów

motywacja: liczenie tych połączeń dla każdego węzła jest jednym ze sposobów, aby dowiedzieć się, które z nich są najważniejsze.

Neo4j ’ scypher:

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

Wykres 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

uwagi: Wersja SQL jest nie tylko dłuższa, ale i bardziej niewygodna, ponieważ należy zawsze brać pod uwagę kierunek strzałek w MATCH.

Przypadek 2: Góra najdłuższe ścieżki

motywacja: długie łańcuchy zależności są podatne na kruchość. Na przykład zależność od biblioteki.

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

Wykres 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

uwagi: W wersji SQL Server, trzeba odwołać się do rekurencyjnej techniki Common table Expression. Zasadniczo obejmuje on sposób myślenia o relacyjnych bazach danych, aby rozwiązać problemy z Grafami.

wniosek

w domenie grafu polecenie SQL Server, z funkcją grafu wykorzystywaną lub nie, używane do rozwiązywania problemów z grafem, jest zwykle znacznie dłuższe, a także bardziej złożone w porównaniu z Cypherem Neo4j. Prowadzi to do wniosku, że kod będzie bardziej czasochłonny do opracowania i trudne do późniejszego utrzymania i rozszerzenia. Inny inżynier, a nawet oryginalny, patrząc na ten sam fragment kodu miesiąc później, zrozumie wszystkie jego aspekty. Dobrze znanym terminem opisującym tę sytuację jest dług techniczny.

łącząc wszystkie wyżej wymienione punkty, od aspektu kodu, przez obsługę funkcji, po ekosystem narzędzi/bibliotek, funkcjonalność Wykresów SQL Server, choć jest zachęcająca, nie spełnia oczekiwań.

SQL Server jest niezwykle dojrzały w odniesieniu do relacyjnej bazy danych, ale wyraźnie nowicjusz w Graph Database. Wsparcie dla tego grafu jest prawdopodobnie uważane za zawarte w relacyjnej bazie danych.

Related Post